diff --git a/Android.bp b/Android.bp
index 9763730..114b2e1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -10,8 +10,6 @@
         "-Werror",
         // Override -Wno-error=implicit-fallthrough from soong
         "-Werror=implicit-fallthrough",
-        "-Werror=sometimes-uninitialized",
-        "-Werror=conditional-uninitialized",
         "-Wnullable-to-nonnull-conversion",
         "-Wsign-compare",
         "-Wthread-safety",
diff --git a/OWNERS b/OWNERS
index 7d617ec..107eefc 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,7 +4,6 @@
 jchalard@google.com
 lorenzo@google.com
 maze@google.com
-nuccachen@google.com
 reminv@google.com
 satk@google.com
 xiaom@google.com
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 27eac94..c8dbf77 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,6 +1,5 @@
 [Builtin Hooks]
 clang_format = true
-commit_msg_test_field = false
 
 [Builtin Hooks Options]
 clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 095fa7d..2d3673c 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,20 +1,10 @@
 {
     "presubmit": [
-        { "name": "libnetdbpf_test" },
         { "name": "netd_integration_test" },
         { "name": "netd_unit_test" },
-        { "name": "netdclient_test" },
-        { "name": "netdutils_test" }
-    ],
-    "postsubmit": [
-        { "name": "libnetdbpf_test",
-          "keywords": ["netd-device-kernel-4.9", "netd-device-kernel-4.14"]},
-        { "name": "netd_integration_test",
-          "keywords": ["netd-device-kernel-4.9", "netd-device-kernel-4.14"]},
-        { "name": "netd_unit_test",
-          "keywords": ["netd-device-kernel-4.9", "netd-device-kernel-4.14"]}
-    ],
-    "imports": [
-        { "path": "packages/modules/DnsResolver" }
+        { "name": "libnetdbpf_test" },
+        { "name": "netdutils_test" },
+        { "name": "resolv_integration_test" },
+        { "name": "resolv_unit_test" }
     ]
 }
diff --git a/apex/Android.bp b/apex/Android.bp
new file mode 100644
index 0000000..c1d33e1
--- /dev/null
+++ b/apex/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+apex {
+    name: "com.android.resolv",
+    manifest: "manifest.json",
+    multilib: {
+        first: {
+             native_shared_libs: ["libnetd_resolv"],
+        },
+    },
+    key: "com.android.resolv.key",
+    certificate: ":com.android.resolv.certificate",
+
+    // Use a custom AndroidManifest.xml used for API targeting.
+    androidManifest: "AndroidManifest.xml",
+}
+
+apex_key {
+    name: "com.android.resolv.key",
+    public_key: "com.android.resolv.avbpubkey",
+    private_key: "com.android.resolv.pem",
+}
+
+android_app_certificate {
+     name: "com.android.resolv.certificate",
+     // will use cert.pk8 and cert.x509.pem
+     certificate: "testcert",
+}
diff --git a/apex/AndroidManifest.xml b/apex/AndroidManifest.xml
new file mode 100644
index 0000000..9d6455c
--- /dev/null
+++ b/apex/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+  package="com.android.resolv">
+  <!-- APEX does not have classes.dex -->
+  <application android:hasCode="false" />
+  <!--
+    * The interface between the resolver and netd is backwards compatible, so the resolver APEX
+    * can work with any version of netd.
+    -->
+  <uses-sdk
+      android:targetSdkVersion="29"
+  />
+</manifest>
diff --git a/apex/OWNERS b/apex/OWNERS
new file mode 100644
index 0000000..bc97a1b
--- /dev/null
+++ b/apex/OWNERS
@@ -0,0 +1,4 @@
+chenbruce@google.com
+codewiz@google.com
+martinwu@google.com
+
diff --git a/apex/com.android.resolv.avbpubkey b/apex/com.android.resolv.avbpubkey
new file mode 100644
index 0000000..e0af34c
--- /dev/null
+++ b/apex/com.android.resolv.avbpubkey
Binary files differ
diff --git a/apex/com.android.resolv.pem b/apex/com.android.resolv.pem
new file mode 100644
index 0000000..6eb688d
--- /dev/null
+++ b/apex/com.android.resolv.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJJwIBAAKCAgEAqcW/Lsj7Ftp8jUpWaW82J+uSpIlcs5w/vsIBEPW/nrakXvLG
+GBA1gauamV+2hvQ76CIkXqsYeaBl8jo1JZuF+ek0tEtHnvMCuGWZZmJSni9CWdXa
+GjQf74+HD0LcVYZd07xjW4aR42httOq9S9zGEucQHaTSQ0C0JBRFMUaAva7QJG15
+w0oqogze7TKTxO2aXZ9R1n3STprY+dv5FXcgGNraAZiSZRYc2FDvgE3J1V1PrdV8
+9RZv6133Iz5eINxR/6MTo2yxNxwZ6gsLD72gTX4N7nc9xtbC9WXCi8Uf7b6dhfyf
+zwZfJSKnwHh6EMa1AdIEgSSdIjbbcCP5mFscbvzUWNuAtUn8RWXUFOF5ssWsTMQC
+QtmfAnbVYH3oMxv3HBlDzS4CVMBmIBUZDbtvpPdQYBJPA/l/kU4DVjCv6Kpgx5Z3
+tVXVA9elta6eZ2dXL7aOPeOJS7OwP6nnEZr/7JJ8NRtQNOwRUU1xRcTxkwRmr/2A
+4h2qoYvxCOebqijvobKzB9cCzM5PvQzLA2aF7yohMN24HNNcTaybeBY6yUGd/iaD
+q0xyD8t7XyoEpMs7SOKkVp08G/kpp7hxRWUzADhhYrvMEAIsyIxX5jSTZYtvYLU/
+UMbfpUNE3qQEYNMv6d5+/Psv8EAjQA5mkNiSY/VWWnPkWapha8MAvYA9nTcCAwEA
+AQKCAgBKG8gY5CK3FyjHhGu0GpfJVUvuBwgwX0R0QLu2a4/5+EBIMjHGz0yMDhyu
+VtmWj4aXDlBSAt3sOdhGpKIOiJUzQll/Wl0pRWsqky8jQkhORNLx5CgQyDAoor6S
+Kt2Dd+P9SX8VtOh6HFvHXbDELNtJ5RNj3U7rjJMWLMMHf38zTdwOCrvcQ8PYeUXW
+xP08OXvo4mMW/lWPeoi8iQlyFU4ti1se1zsQZVayFqJ1n387ZEAj4c1qLyEr3RjE
+ibUNIx+oN8eazxeMtveY8rkhZeVT7nKmZebRpW31MTZ7TNFjNpIMqvoXpPBjhX00
+x2KBcDwTT1ooBZOSG+AuU4Xgu+Ts1+6nZKbhnQuxvgslFyDEdtuID7nuXu08D3B2
+OpCtrQt08QS/dLHpcOhSMjkxqH2aITVPQgGWK16E7pcVex/Lapyjr4ETx1GqjpCL
+uKhmvGsrcdUD9fETzV5ZsMBHrnCSlq0XRnWFuGYmxlSIAciNUTMFfy7D/ml++Boe
+S33HwuaJlnUp3iAbIddXXx+zZHBocJ1Iznl1iu8CMdh+79wMOPkcMDRRNZPpMca+
+ukfGRRdrtyPyrWdrv9d+jtORBC3L9Kgg5yCEXe3HZCSLj/9UUrEAAACEw/IuYxy0
+AsDwpHS9WuqvLYbFPL3UQlSlFJWKkgCZwO+K+c2MsVnllWI0AQKCAQEA0NqVa0Jx
+TGxE2EEEgxA63c+rp5Qm2IlKns+tbnWnfI6XW/JiFkDqTVkIcg6F3dVyjEaZnGWa
+MPCORCtOGQ8IyAYQANyza/CW2+i0YvJBSMmCsbo7wUdrYU9krPRLLWYLhue5HdTP
+5+H+lFXmu3o36YhhWwfMflZsV1MOzRF3eIH3FaTgzoXmBQH3CH5y2c3OWjhMrTnz
+51HZFPu3XB3wmqEIyHAsQke68HxgyJ7uBYUmdAIYYMLgV3Jp/ds+QxXSqwYz97tS
+oe6778QLqcn/Q9LtonagDMO/ATSw/0fLt1+8QLdbksDTC4MUoaGKxuiL7sy5PnKd
+72oV75t06Tz26QKCAQEA0BiyFaC3EcZG6KmoZvM+bHGK9gp5tKr0AgERLAVe+M/f
+1NsBxf1HxoHlkudGRo64J+SwM+ZVVh5UPtrb1Le5a3IR9qL++ZfPM1WuvlHz9uBc
+lJLPozboWoUovbfaoKQtuRzzOYBwodwAbY02LNNtM33jqXNUN0MM0L3ZH3FmOglU
+u/4dH+EvgLDpnCV0czMlGSo9I9977Nvy3dQBXjzz9EF+covAhq7skmfwDblTAZR7
+EkmsCmoeEoKRAEtKgAxs0Hgyo2iMIxYy0pdvjGhJe64JQb3EKLjxhYsadnI+S5YI
+QBH9+EX/ZLSii+cIkEeh1lSMk9uT1/Rp4V40sdmfHwKCAQA9oTLUWt/qCEzsb4sw
+TbrBN4XUxpAL979wS6JG5SsOQ1mAxW6SWIeLWYl3drej9Vd+81pi30x3wpSIoyrB
+lEEoHTndt0KuyGkL7YhFZm1DWEtbvLPjXfre1TnFG7WPaPxfy8NBfUn4iCTCivKy
+Qed730WzQgLjCQehYR4N/2h8xAUwet3ns3Vj5ueJtx6XDPcmglSGDYLesLVZTsoV
+wbP9PSXFV+yHhnkwe9NngBaGxHrLYs7kxrzCsT17rpWZ4DexRfxRzxIcPMFyiCxU
+5wmPbw+2kEC8Y4rahTzxp7MCopp/klvQW1wrmnudEnlMJtUcG4dSWSonuutMMFh4
+dwf5AoIBAEX9+HAT1V9yHEmHPvAZooZhDkdBMLxWv6mo6DixOcdgS73RR+BrF2gq
+Kqhlh5qVyFUKs0VRlKRZoSZfAI+kmAYOoQIewrn6mKOAjzzOXctMnXcPhi00e6Ru
+o0xkeXGMpyBbH2fYzolycOZoF6+uEU2/awKEmu/XaokPQec0ghjFKK3ug6dEW3Di
+kECHzIouyqyTK2tUcN8y/5YjB67Fu5wNJ1WpscDbNxDrSq+jBMtEQLze8LG0DZdW
+OSUrLcyx4SuhMg8KTBBFGCUC8G7+aLDj0ZM+G6tCwWGUbvsl49QSi4XZR13pVURv
+CTkbJSM6JLHtUDcvJKP/PlmiEQE83CsCggEAOIlm8zRHeJe3GdZAPIwV8EYCh7rd
+ghRjGIwzjylazzZyeHLQBKaIwNdlgOZG1HqTljdp4ZE0f+Oyh2lGOqQEqWjMBJPp
+yZG1jBCCsJMfTweWxzLhmzV4UUQ+MZQDjZ7uOKGYwN/rkhW30zZMenoZ+PywFhhl
+ldnPsQMBvqS03eCIaQveRkq8S/qA3uDGPjsEPTaYMJgw9/imsP8hW3z+kd7hH76R
+Guk98WHe3wvasV1RNOp5ixwUQgVmFJLrTVX+dfSKLw0XzekkG/1Uis7r2HXCfoaZ
+boHvICyW0kmhnsOVA7mWwByhUav9Ghevm9czVATTIGiA8lIZxFFbvr2KTg==
+-----END RSA PRIVATE KEY-----
diff --git a/apex/manifest.json b/apex/manifest.json
new file mode 100644
index 0000000..f3f5b02
--- /dev/null
+++ b/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.resolv",
+  "version": 299900000
+}
diff --git a/apex/testcert.pk8 b/apex/testcert.pk8
new file mode 100644
index 0000000..adfc589
--- /dev/null
+++ b/apex/testcert.pk8
Binary files differ
diff --git a/apex/testcert.x509.pem b/apex/testcert.x509.pem
new file mode 100644
index 0000000..cba30d6
--- /dev/null
+++ b/apex/testcert.x509.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGADCCA+igAwIBAgIJAJiRMVvanGUaMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
+VmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UE
+AwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
+Fw0xODEwMzAxMjEzNTFaFw00NjAzMTcxMjEzNTFaMIGUMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UEAwwHQW5kcm9p
+ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBAL3ghKA8Gz9qOORY8gMY4wlB2tCJLDUO2tFG
+LVK1UphtQMp+YEcz/0VQKVV7de7z6V4EMQ5P1HbxHOsjcKn/zXAl4YgFt7b5kZbC
+bpNK4CYHEfho3j6fpYtq5d9q8rIA2kI0uZkkqPy1zXKTl2C2PjOoAnLQRk5xBVQG
+M10/wYsf7yX36mSWoJJwKPp/EzVFpA+hX8HpljeIiZ6CFzKwJdqv9zO/xzfp6NsX
+Tv5EGdkDxmw3qQqKgyl8dLMTZ/2zNfvVOMeZDusEPDF7A/lbU1byLWrKQdCzVb40
+yc7BCSRGYwM29R/byOcgD+lslwKSGzgzNmQXICt1tXz9bSJR8qh4tlAaiRc3ZKBe
+hJWIFGkGtD/cDGtDE5DbNAOz6CdSDdE2XN0Qf0cfN1RHVE6fo2FtFicRRVuFBt8M
+2cbQ7bzmEvtHD6W6dsf120FH7gppXKmnhMx1WazpxR2QltbiYDTy2ZZi4paS/jDB
+fL9gMCWp3Ohg2y74NGfUw5CQWQsDpcki6I7RvwClBCyOV51LHn5LE/nY4DkVrZxk
+Pw0/YrTWz5J5PbdMetTuIunE4ec4lm8nZnh1ET+2MHx2+RoyF5vBs4rp1KHHRaEA
+veD2AfQOWxz7kOG9+akFot7n+QoWEGdwY0mJ9jsO/IITCjv3VbD7o0OoJv1R2AW5
+sK2KQ4PDAgMBAAGjUzBRMB0GA1UdDgQWBBT2EbrayXGhY6VCvSlLtRNyjW9ceDAf
+BgNVHSMEGDAWgBT2EbrayXGhY6VCvSlLtRNyjW9ceDAPBgNVHRMBAf8EBTADAQH/
+MA0GCSqGSIb3DQEBCwUAA4ICAQC7SsWap9zDKmuR0qMUZ6wlualnag0hUG1jZHQP
+t63KO6LmNNMSuXRX60Zcq6WWzgLOyoT4HqHZZ47Jamfb4XQQcnWMMW0tJ3pDtTkz
+dZILBInHJO8QPYI8Du6XWsDLSvMajq6ueBtO3NdcgsNL7eiHf3WoOtajLZxFM94Z
+MESkUQOIsqHolYeTMHLTsuGkX1CK2Zw3Xn18bUSTYwZCHa6mYH00ItUBfetGCnWh
+Y7bth/R15Cc+hocSB7ZsOa/R5kDyDdFDIKrnV5nH5Yd7CryrYC6Ac5UarYrxSJTq
+eKPwqUlJB/tJW/lvdLt8YaURbFGzf/ZqU12zZRafYjmMjcQvfpzMoDSnbvHTA9IR
+ZGO7dwhwykoSaL4/8LWde49xQUq6F2pQBRmEr+7mTzml1MaM5cWEk5emkCMXgLog
+k+c56CAk1EdM1teWik7wR0TIqkkYyYJHTSg61GkXUIXrZJ6iYx2ejDg1+QTPm9rU
+Yr7nP52gVkQuUAX1+xB6wKLSDizQJw8SNiUGXl5+2vwV6+0BI3/CXlQ8I/nRPBC1
+oqOIkRSbE+IF7DP9QvYuNG/3bZZQ8LUVeHxqI5Mq8K2VIJZd95AIwPNMH34SaDGz
+9xjG28Fq4ZkuDP0pCsHM9d2XEwK5PEVS18WW5fJ/QcJKMno4IPTB70ZBBjVzv6Y+
+MYjOrw==
+-----END CERTIFICATE-----
diff --git a/bpf_progs/Android.bp b/bpf_progs/Android.bp
index 7b1f015..a393035 100644
--- a/bpf_progs/Android.bp
+++ b/bpf_progs/Android.bp
@@ -14,11 +14,6 @@
 // limitations under the License.
 //
 
-cc_library_headers {
-    name: "netd_bpf_progs_headers",
-    export_include_dirs: ["."],
-}
-
 //
 // bpf kernel programs
 //
diff --git a/bpf_progs/bpf_net_helpers.h b/bpf_progs/bpf_net_helpers.h
deleted file mode 100644
index 714b7e6e..0000000
--- a/bpf_progs/bpf_net_helpers.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef NETDBPF_BPF_NET_HELPERS_H
-#define NETDBPF_BPF_NET_HELPERS_H
-
-#include <linux/bpf.h>
-#include <linux/if_packet.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-// this returns 0 iff skb->sk is NULL
-static uint64_t (*bpf_get_socket_cookie)(struct __sk_buff* skb) = (void*)BPF_FUNC_get_socket_cookie;
-
-static uint32_t (*bpf_get_socket_uid)(struct __sk_buff* skb) = (void*)BPF_FUNC_get_socket_uid;
-static int (*bpf_skb_load_bytes)(struct __sk_buff* skb, int off, void* to,
-                                 int len) = (void*)BPF_FUNC_skb_load_bytes;
-
-static int (*bpf_skb_change_proto)(struct __sk_buff* skb, __be16 proto,
-                                   __u64 flags) = (void*)BPF_FUNC_skb_change_proto;
-static int (*bpf_l3_csum_replace)(struct __sk_buff* skb, __u32 offset, __u64 from, __u64 to,
-                                  __u64 flags) = (void*)BPF_FUNC_l3_csum_replace;
-static int (*bpf_l4_csum_replace)(struct __sk_buff* skb, __u32 offset, __u64 from, __u64 to,
-                                  __u64 flags) = (void*)BPF_FUNC_l4_csum_replace;
-static int (*bpf_redirect)(__u32 ifindex, __u64 flags) = (void*)BPF_FUNC_redirect;
-
-// Android only supports little endian architectures
-#define htons(x) (__builtin_constant_p(x) ? ___constant_swab16(x) : __builtin_bswap16(x))
-#define htonl(x) (__builtin_constant_p(x) ? ___constant_swab32(x) : __builtin_bswap32(x))
-#define ntohs(x) htons(x)
-#define ntohl(x) htonl(x)
-
-static inline __always_inline __unused bool is_received_skb(struct __sk_buff* skb) {
-    return skb->pkt_type == PACKET_HOST || skb->pkt_type == PACKET_BROADCAST ||
-           skb->pkt_type == PACKET_MULTICAST;
-}
-
-#endif  // NETDBPF_BPF_NET_HELPERS_H
diff --git a/bpf_progs/clatd.c b/bpf_progs/clatd.c
index fb7acfa..578d244 100644
--- a/bpf_progs/clatd.c
+++ b/bpf_progs/clatd.c
@@ -23,16 +23,31 @@
 #include <linux/ipv6.h>
 #include <linux/pkt_cls.h>
 #include <linux/swab.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
 #include <stdbool.h>
 #include <stdint.h>
 
 #include "bpf_helpers.h"
-#include "bpf_net_helpers.h"
 #include "netdbpf/bpf_shared.h"
 
+// bionic/libc/kernel/uapi/linux/udp.h:
+//   struct __kernel_udphdr {
+// bionic/libc/kernel/tools/defaults.py:
+//   # We want to support both BSD and Linux member names in struct udphdr.
+//   "udphdr": "__kernel_udphdr",
+// so instead it just doesn't work... ugh.
+#define udphdr __kernel_udphdr
+
 // From kernel:include/net/ip.h
 #define IP_DF 0x4000  // Flag: "Don't Fragment"
 
+// Android only supports little endian architectures
+#define htons(x) (__builtin_constant_p(x) ? ___constant_swab16(x) : __builtin_bswap16(x))
+#define htonl(x) (__builtin_constant_p(x) ? ___constant_swab32(x) : __builtin_bswap32(x))
+#define ntohs(x) htons(x)
+#define ntohl(x) htonl(x)
+
 DEFINE_BPF_MAP(clat_ingress_map, HASH, ClatIngressKey, ClatIngressValue, 16)
 
 static inline __always_inline int nat64(struct __sk_buff* skb, bool is_ethernet) {
@@ -41,6 +56,8 @@
     const void* data_end = (void*)(long)skb->data_end;
     const struct ethhdr* const eth = is_ethernet ? data : NULL;  // used iff is_ethernet
     const struct ipv6hdr* const ip6 = is_ethernet ? (void*)(eth + 1) : data;
+    const struct tcphdr* const tcp = (void*)(ip6 + 1);
+    const struct udphdr* const udp = (void*)(ip6 + 1);
 
     // Must be meta-ethernet IPv6 frame
     if (skb->protocol != htons(ETH_P_IPV6)) return TC_ACT_OK;
@@ -58,10 +75,12 @@
     if (ntohs(ip6->payload_len) > 0xFFFF - sizeof(struct iphdr)) return TC_ACT_OK;
 
     switch (ip6->nexthdr) {
-        case IPPROTO_TCP:  // For TCP & UDP the checksum neutrality of the chosen IPv6
-        case IPPROTO_UDP:  // address means there is no need to update their checksums.
-        case IPPROTO_GRE:  // We do not need to bother looking at GRE/ESP headers,
-        case IPPROTO_ESP:  // since there is never a checksum to update.
+        case IPPROTO_TCP:  // If TCP, must have 20 byte minimal TCP header
+            if (tcp + 1 > (struct tcphdr*)data_end) return TC_ACT_OK;
+            break;
+
+        case IPPROTO_UDP:  // If UDP, must have 8 byte minimal UDP header
+            if (udp + 1 > (struct udphdr*)data_end) return TC_ACT_OK;
             break;
 
         default:  // do not know how to handle anything else
@@ -116,9 +135,8 @@
     // Note that there is no L4 checksum update: we are relying on the checksum neutrality
     // of the ipv6 address chosen by netd's ClatdController.
 
-    // Packet mutations begin - point of no return, but if this first modification fails
-    // the packet is probably still pristine, so let clatd handle it.
-    if (bpf_skb_change_proto(skb, htons(ETH_P_IP), 0)) return TC_ACT_OK;
+    // Packet mutations begin - point of no return.
+    if (bpf_skb_change_proto(skb, htons(ETH_P_IP), 0)) return TC_ACT_SHOT;
 
     // bpf_skb_change_proto() invalidates all pointers - reload them.
     data = (void*)(long)skb->data;
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
index 3212314..1362be2 100644
--- a/bpf_progs/netd.c
+++ b/bpf_progs/netd.c
@@ -51,7 +51,9 @@
     // that skb->sk is NULL during RX (early decap socket lookup failure),
     // which commonly happens for incoming packets to an unconnected udp socket.
     // Additionally bpf_get_socket_cookie() returns 0 if skb->sk is NULL
-    if ((sock_uid == 65534) && !bpf_get_socket_cookie(skb) && is_received_skb(skb))
+    if ((sock_uid == 65534) && !bpf_get_socket_cookie(skb) &&
+        (skb->pkt_type == PACKET_HOST || skb->pkt_type == PACKET_BROADCAST ||
+         skb->pkt_type == PACKET_MULTICAST))
         return BPF_MATCH;
 
     UidOwnerValue* whitelistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
diff --git a/bpf_progs/netd.h b/bpf_progs/netd.h
index be9aaee..8be21be 100644
--- a/bpf_progs/netd.h
+++ b/bpf_progs/netd.h
@@ -29,7 +29,6 @@
 #include <linux/ipv6.h>
 #include <stdbool.h>
 #include <stdint.h>
-#include "bpf_net_helpers.h"
 #include "netdbpf/bpf_shared.h"
 
 typedef struct {
diff --git a/client/Android.bp b/client/Android.bp
index 7b51322..bb52430 100644
--- a/client/Android.bp
+++ b/client/Android.bp
@@ -21,10 +21,10 @@
     header_libs: [
         "libnetd_client_headers",
         "libbase_headers", // for unique_fd.h
-        "libnetd_resolv_headers",
     ],
     export_header_lib_headers: ["libnetd_client_headers"],
     include_dirs: [
+        "system/netd/resolv",
         "system/netd/libnetdutils/include",
     ],
     defaults: ["netd_defaults"],
@@ -38,10 +38,9 @@
     defaults: ["netd_defaults"],
     test_suites: ["device-tests"],
     include_dirs: [
+        "system/netd/resolv",
         "system/netd/include",
-    ],
-    header_libs: [
-        "libnetd_resolv_headers",
+        "system/netd/libnetdutils/include",
     ],
     static_libs: [
         "libgmock",
diff --git a/client/NetdClient.cpp b/client/NetdClient.cpp
index d5945d0..a7dc0ad 100644
--- a/client/NetdClient.cpp
+++ b/client/NetdClient.cpp
@@ -130,7 +130,7 @@
     const int ret = libcConnect(sockfd, addr, addrlen);
     // Save errno so it isn't clobbered by sending ON_CONNECT_COMPLETE
     const int connectErrno = errno;
-    const auto latencyMs = static_cast<unsigned>(s.timeTakenUs() / 1000);
+    const unsigned latencyMs = lround(s.timeTaken());
     // Send an ON_CONNECT_COMPLETE command that includes sockaddr and connect latency for reporting
     if (shouldSetFwmark) {
         FwmarkConnectInfo connectInfo(ret == 0 ? 0 : connectErrno, latencyMs, addr);
diff --git a/client/NetdClientTest.cpp b/client/NetdClientTest.cpp
index b523ccc..6f2fc09 100644
--- a/client/NetdClientTest.cpp
+++ b/client/NetdClientTest.cpp
@@ -36,10 +36,9 @@
         pollfd fds[1] = {{.fd = dnsProxyFd, .events = POLLIN}};
         enum { SERVERFD = 0 };
 
-        int poll_result = TEMP_FAILURE_RETRY(poll(fds, std::size(fds), -1));
-        ASSERT_GT(poll_result, 0);
+        const int s = TEMP_FAILURE_RETRY(poll(fds, std::size(fds), -1));
+        if (s <= 0) break;
 
-        if (fds[SERVERFD].revents & POLLERR) return;
         if (fds[SERVERFD].revents & POLLIN) {
             char buf[4096];
             TEMP_FAILURE_RETRY(read(fds[SERVERFD].fd, &buf, sizeof(buf)));
diff --git a/include/BinderUtil.h b/include/BinderUtil.h
index 6b41465..9333dcd 100644
--- a/include/BinderUtil.h
+++ b/include/BinderUtil.h
@@ -14,11 +14,8 @@
  * limitations under the License.
  */
 
-#pragma once
-
-#include <android-base/stringprintf.h>
-#include <json/value.h>
-#include <json/writer.h>
+#ifndef NETD_INCLUDE_BINDER_UTIL_H
+#define NETD_INCLUDE_BINDER_UTIL_H
 
 #ifdef ANDROID_BINDER_STATUS_H
 #define IS_BINDER_OK(__ex__) (__ex__ == ::android::binder::Status::EX_NONE)
@@ -107,3 +104,5 @@
             ::android::base::StringPrintf(" <%.2fms>", logTransaction["duration_ms"].asFloat()));
     logFn(output);
 }
+
+#endif /* NETD_INCLUDE_BINDER_UTIL_H */
diff --git a/libnetdbpf/Android.bp b/libnetdbpf/Android.bp
index 574e7c3..b5fefac 100644
--- a/libnetdbpf/Android.bp
+++ b/libnetdbpf/Android.bp
@@ -26,6 +26,7 @@
         "libbpf_android",
         "liblog",
         "libnetdutils",
+        "libutils",
     ],
     export_include_dirs: ["include"],
     defaults: ["netd_defaults"],
diff --git a/libnetdbpf/BpfNetworkStats.cpp b/libnetdbpf/BpfNetworkStats.cpp
index 30b43fa..fe86cc1 100644
--- a/libnetdbpf/BpfNetworkStats.cpp
+++ b/libnetdbpf/BpfNetworkStats.cpp
@@ -191,7 +191,7 @@
         return ret;
     }
 
-    BpfMap<uint32_t, uint8_t> configurationMap(mapRetrieve(CONFIGURATION_MAP_PATH, BPF_OPEN_FLAGS));
+    BpfMap<uint32_t, uint8_t> configurationMap(mapRetrieve(CONFIGURATION_MAP_PATH, 0));
     if (!configurationMap.isValid()) {
         int ret = -errno;
         ALOGE("get configuration map fd failed: %s", strerror(errno));
@@ -241,10 +241,7 @@
             return netdutils::status::ok;
         }
         StatsKey fakeKey = {
-                .uid = (uint32_t)UID_ALL,
-                .tag = (uint32_t)TAG_NONE,
-                .counterSet = (uint32_t)SET_ALL,
-        };
+            .uid = (uint32_t)UID_ALL, .counterSet = (uint32_t)SET_ALL, .tag = (uint32_t)TAG_NONE};
         lines->push_back(populateStatsEntry(fakeKey, value, ifname));
         return netdutils::status::ok;
     };
@@ -324,8 +321,6 @@
 }
 
 stats_line& stats_line::operator=(const stats_line& rhs) {
-    if (this == &rhs) return *this;
-
     strlcpy(iface, rhs.iface, sizeof(iface));
     uid = rhs.uid;
     set = rhs.set;
diff --git a/libnetdbpf/BpfNetworkStatsTest.cpp b/libnetdbpf/BpfNetworkStatsTest.cpp
index 057f2a9..8153127 100644
--- a/libnetdbpf/BpfNetworkStatsTest.cpp
+++ b/libnetdbpf/BpfNetworkStatsTest.cpp
@@ -201,10 +201,10 @@
     SKIP_IF_BPF_NOT_SUPPORTED;
 
     StatsValue value1 = {
-            .rxPackets = 0,
             .rxBytes = 0,
-            .txPackets = 0,
+            .rxPackets = 0,
             .txBytes = 0,
+            .txPackets = 0,
     };
     Stats result1 = {};
     ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID1, &result1, mFakeAppUidStatsMap));
@@ -217,17 +217,15 @@
     updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
     updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
     updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
-    StatsValue value1 = {
-            .rxPackets = TEST_PACKET0,
-            .rxBytes = TEST_BYTES0,
-            .txPackets = TEST_PACKET1,
-            .txBytes = TEST_BYTES1,
-    };
+    StatsValue value1 = {.rxBytes = TEST_BYTES0,
+                         .rxPackets = TEST_PACKET0,
+                         .txBytes = TEST_BYTES1,
+                         .txPackets = TEST_PACKET1,};
     StatsValue value2 = {
-            .rxPackets = TEST_PACKET0 * 2,
-            .rxBytes = TEST_BYTES0 * 2,
-            .txPackets = TEST_PACKET1 * 2,
-            .txBytes = TEST_BYTES1 * 2,
+        .rxBytes = TEST_BYTES0 * 2,
+        .rxPackets = TEST_PACKET0 * 2,
+        .txBytes = TEST_BYTES1 * 2,
+        .txPackets = TEST_PACKET1 * 2,
     };
     ASSERT_TRUE(isOk(mFakeAppUidStatsMap.writeValue(TEST_UID1, value1, BPF_ANY)));
     ASSERT_TRUE(isOk(mFakeAppUidStatsMap.writeValue(TEST_UID2, value2, BPF_ANY)));
@@ -260,16 +258,16 @@
     updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
     updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
     StatsValue value1 = {
-            .rxPackets = TEST_PACKET0,
-            .rxBytes = TEST_BYTES0,
-            .txPackets = TEST_PACKET1,
-            .txBytes = TEST_BYTES1,
+        .rxBytes = TEST_BYTES0,
+        .rxPackets = TEST_PACKET0,
+        .txBytes = TEST_BYTES1,
+        .txPackets = TEST_PACKET1,
     };
     StatsValue value2 = {
-            .rxPackets = TEST_PACKET1,
-            .rxBytes = TEST_BYTES1,
-            .txPackets = TEST_PACKET0,
-            .txBytes = TEST_BYTES0,
+        .rxBytes = TEST_BYTES1,
+        .rxPackets = TEST_PACKET1,
+        .txBytes = TEST_BYTES0,
+        .txPackets = TEST_PACKET0,
     };
     uint32_t ifaceStatsKey = IFACE_INDEX1;
     EXPECT_TRUE(isOk(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY)));
@@ -290,10 +288,10 @@
     ASSERT_EQ(0, bpfGetIfaceStatsInternal(NULL, &totalResult, mFakeIfaceStatsMap,
                                           mFakeIfaceIndexNameMap));
     StatsValue totalValue = {
-            .rxPackets = TEST_PACKET0 * 2 + TEST_PACKET1,
-            .rxBytes = TEST_BYTES0 * 2 + TEST_BYTES1,
-            .txPackets = TEST_PACKET1 * 2 + TEST_PACKET0,
-            .txBytes = TEST_BYTES1 * 2 + TEST_BYTES0,
+        .rxBytes = TEST_BYTES0 * 2 + TEST_BYTES1,
+        .rxPackets = TEST_PACKET0 * 2 + TEST_PACKET1,
+        .txBytes = TEST_BYTES1 * 2 + TEST_BYTES0,
+        .txPackets = TEST_PACKET1 * 2 + TEST_PACKET0,
     };
     expectStatsEqual(totalValue, totalResult);
 }
@@ -303,12 +301,10 @@
 
     updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
     updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
-    StatsValue value1 = {
-            .rxPackets = TEST_PACKET0,
-            .rxBytes = TEST_BYTES0,
-            .txPackets = TEST_PACKET1,
-            .txBytes = TEST_BYTES1,
-    };
+    StatsValue value1 = {.rxBytes = TEST_BYTES0,
+                         .rxPackets = TEST_PACKET0,
+                         .txBytes = TEST_BYTES1,
+                         .txPackets = TEST_PACKET1,};
     populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
     populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX2, TEST_COUNTERSET0, value1, mFakeStatsMap);
     populateFakeStats(TEST_UID1, TEST_TAG + 1, IFACE_INDEX1, TEST_COUNTERSET0, value1,
@@ -340,12 +336,10 @@
 
     updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
     updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
-    StatsValue value1 = {
-            .rxPackets = TEST_PACKET0,
-            .rxBytes = TEST_BYTES0,
-            .txPackets = TEST_PACKET1,
-            .txBytes = TEST_BYTES1,
-    };
+    StatsValue value1 = {.rxBytes = TEST_BYTES0,
+                         .rxPackets = TEST_PACKET0,
+                         .txBytes = TEST_BYTES1,
+                         .txPackets = TEST_PACKET1,};
     populateFakeStats(0, 0, 0, OVERFLOW_COUNTERSET, value1, mFakeStatsMap);
     populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
     populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET0, value1, mFakeStatsMap);
@@ -376,28 +370,22 @@
     SKIP_IF_BPF_NOT_SUPPORTED;
 
     updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
-    StatsValue value1 = {
-            .rxPackets = TEST_PACKET0,
-            .rxBytes = TEST_BYTES0 * 20,
-            .txPackets = TEST_PACKET1,
-            .txBytes = TEST_BYTES1 * 20,
-    };
+    StatsValue value1 = {.rxBytes = TEST_BYTES0 * 20,
+                         .rxPackets = TEST_PACKET0,
+                         .txBytes = TEST_BYTES1 * 20,
+                         .txPackets = TEST_PACKET1,};
     uint32_t ifaceIndex = UNKNOWN_IFACE;
     populateFakeStats(TEST_UID1, 0, ifaceIndex, TEST_COUNTERSET0, value1, mFakeStatsMap);
     populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
-    StatsValue value2 = {
-            .rxPackets = TEST_PACKET0,
-            .rxBytes = TEST_BYTES0 * 40,
-            .txPackets = TEST_PACKET1,
-            .txBytes = TEST_BYTES1 * 40,
-    };
+    StatsValue value2 = {.rxBytes = TEST_BYTES0 * 40,
+                         .rxPackets = TEST_PACKET0,
+                         .txBytes = TEST_BYTES1 * 40,
+                         .txPackets = TEST_PACKET1,};
     populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET0, value2, mFakeStatsMap);
-    StatsKey curKey = {
-            .uid = TEST_UID1,
-            .tag = 0,
-            .counterSet = TEST_COUNTERSET0,
-            .ifaceIndex = ifaceIndex,
-    };
+    StatsKey curKey = {.uid = TEST_UID1,
+                       .tag = 0,
+                       .ifaceIndex = ifaceIndex,
+                       .counterSet = TEST_COUNTERSET0};
     char ifname[IFNAMSIZ];
     int64_t unknownIfaceBytesTotal = 0;
     ASSERT_EQ(-ENODEV, getIfaceNameFromMap(mFakeIfaceIndexNameMap, mFakeStatsMap, ifaceIndex,
@@ -424,16 +412,16 @@
     updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
     updateIfaceMap(LONG_IFACE_NAME, IFACE_INDEX4);
     StatsValue value1 = {
-            .rxPackets = TEST_PACKET0,
-            .rxBytes = TEST_BYTES0,
-            .txPackets = TEST_PACKET1,
-            .txBytes = TEST_BYTES1,
+        .rxBytes = TEST_BYTES0,
+        .rxPackets = TEST_PACKET0,
+        .txBytes = TEST_BYTES1,
+        .txPackets = TEST_PACKET1,
     };
     StatsValue value2 = {
-            .rxPackets = TEST_PACKET1,
-            .rxBytes = TEST_BYTES1,
-            .txPackets = TEST_PACKET0,
-            .txBytes = TEST_BYTES0,
+        .rxBytes = TEST_BYTES1,
+        .rxPackets = TEST_PACKET1,
+        .txBytes = TEST_BYTES0,
+        .txPackets = TEST_PACKET0,
     };
     uint32_t ifaceStatsKey = IFACE_INDEX1;
     EXPECT_TRUE(isOk(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY)));
@@ -464,22 +452,22 @@
     updateIfaceMap(IFACE_NAME1, IFACE_INDEX3);  // Duplicate!
 
     StatsValue value1 = {
-            .rxPackets = TEST_PACKET0,
             .rxBytes = TEST_BYTES0,
-            .txPackets = TEST_PACKET1,
+            .rxPackets = TEST_PACKET0,
             .txBytes = TEST_BYTES1,
+            .txPackets = TEST_PACKET1,
     };
     StatsValue value2 = {
-            .rxPackets = TEST_PACKET1,
             .rxBytes = TEST_BYTES1,
-            .txPackets = TEST_PACKET0,
+            .rxPackets = TEST_PACKET1,
             .txBytes = TEST_BYTES0,
+            .txPackets = TEST_PACKET0,
     };
     StatsValue value3 = {
-            .rxPackets = TEST_PACKET0 * 2,
             .rxBytes = TEST_BYTES0 * 2,
-            .txPackets = TEST_PACKET1 * 2,
+            .rxPackets = TEST_PACKET0 * 2,
             .txBytes = TEST_BYTES1 * 2,
+            .txPackets = TEST_PACKET1 * 2,
     };
 
     std::vector<stats_line> lines;
@@ -553,10 +541,10 @@
     updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
 
     StatsValue value1 = {
-            .rxPackets = TEST_PACKET0,
             .rxBytes = TEST_BYTES0,
-            .txPackets = TEST_PACKET1,
+            .rxPackets = TEST_PACKET0,
             .txBytes = TEST_BYTES1,
+            .txPackets = TEST_PACKET1,
     };
 
     // Mutate uid, 0 < TEST_UID1 < INT_MAX < INT_MIN < UINT_MAX.
diff --git a/libnetdbpf/include/netdbpf/bpf_shared.h b/libnetdbpf/include/netdbpf/bpf_shared.h
index 933172a..66d20ec 100644
--- a/libnetdbpf/include/netdbpf/bpf_shared.h
+++ b/libnetdbpf/include/netdbpf/bpf_shared.h
@@ -87,7 +87,7 @@
     IIF_MATCH = (1 << 5),
 };
 
-enum BpfPermissionMatch {
+enum BpfPemissionMatch {
     BPF_PERMISSION_INTERNET = 1 << 2,
     BPF_PERMISSION_UPDATE_DEVICE_STATS = 1 << 3,
 };
diff --git a/libnetdutils/AndroidTest.xml b/libnetdutils/AndroidTest.xml
new file mode 100644
index 0000000..dc13361
--- /dev/null
+++ b/libnetdutils/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for netdutils_test">
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="netdutils_test->/data/local/tmp/netdutils_test" />
+    </target_preparer>
+    <option name="test-suite-tag" value="apct" />
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="netdutils_test" />
+    </test>
+</configuration>
diff --git a/libnetdutils/InternetAddresses.cpp b/libnetdutils/InternetAddresses.cpp
index 78d30b2..944ed91 100644
--- a/libnetdutils/InternetAddresses.cpp
+++ b/libnetdutils/InternetAddresses.cpp
@@ -61,8 +61,9 @@
     };
     addrinfo* res;
     const int ret = getaddrinfo(repr.c_str(), nullptr, &hints, &res);
-    ScopedAddrinfo res_cleanup(res);
+    // TODO: move ScopedAddrinfo into libnetdutils and use it here.
     if (ret != 0) {
+        freeaddrinfo(res);
         return false;
     }
 
@@ -83,6 +84,7 @@
             break;
     }
 
+    freeaddrinfo(res);
     return rval;
 }
 
diff --git a/libnetdutils/ThreadUtilTest.cpp b/libnetdutils/ThreadUtilTest.cpp
index 8fad8b8..2fe63b7 100644
--- a/libnetdutils/ThreadUtilTest.cpp
+++ b/libnetdutils/ThreadUtilTest.cpp
@@ -14,49 +14,22 @@
  * limitations under the License.
  */
 
-#include <string>
-
-#include <android-base/expected.h>
 #include <gtest/gtest.h>
-#include <netdutils/ThreadUtil.h>
 
-namespace android::netdutils {
+#include "netdutils/ThreadUtil.h"
+
+namespace android {
+namespace netdutils {
 
 namespace {
 
-android::base::expected<std::string, int> getThreadName() {
-    char name[16] = {};
-    if (const int ret = pthread_getname_np(pthread_self(), name, sizeof(name)); ret != 0) {
-        return android::base::unexpected(ret);
-    }
-    return std::string(name);
-}
-
 class NoopRun {
   public:
-    explicit NoopRun(const std::string& name = "") : mName(name) { instanceNum++; }
-
-    // Destructor happens in the thread.
-    ~NoopRun() {
-        if (checkName) {
-            auto expected = getThreadName();
-            EXPECT_TRUE(expected.has_value());
-            EXPECT_EQ(mExpectedName, expected.value());
-        }
-        instanceNum--;
-    }
+    NoopRun() { instanceNum++; }
+    ~NoopRun() { instanceNum--; }
 
     void run() {}
 
-    std::string threadName() { return mName; }
-
-    // Set the expected thread name which will be used to check if it matches the actual thread
-    // name which is returned from the system call. The check will happen in the destructor.
-    void setExpectedName(const std::string& expectedName) {
-        checkName = true;
-        mExpectedName = expectedName;
-    }
-
     static bool waitForAllReleased(int timeoutMs) {
         constexpr int intervalMs = 20;
         int limit = timeoutMs / intervalMs;
@@ -71,11 +44,6 @@
 
     // To track how many instances are alive.
     static std::atomic<int> instanceNum;
-
-  private:
-    std::string mName;
-    std::string mExpectedName;
-    bool checkName = false;
 };
 
 std::atomic<int> NoopRun::instanceNum;
@@ -93,30 +61,5 @@
     EXPECT_EQ(0, NoopRun::instanceNum);
 }
 
-TEST(ThreadUtilTest, SetThreadName) {
-    NoopRun::instanceNum = 0;
-
-    // Test thread name empty.
-    NoopRun* obj1 = new NoopRun();
-    obj1->setExpectedName("");
-
-    // Test normal case.
-    NoopRun* obj2 = new NoopRun("TestName");
-    obj2->setExpectedName("TestName");
-
-    // Test thread name too long.
-    std::string name("TestNameTooooLong");
-    NoopRun* obj3 = new NoopRun(name);
-    obj3->setExpectedName(name.substr(0, 15));
-
-    // Thread names are examined in their destructors.
-    EXPECT_EQ(3, NoopRun::instanceNum);
-    threadLaunch(obj1);
-    threadLaunch(obj2);
-    threadLaunch(obj3);
-
-    EXPECT_TRUE(NoopRun::waitForAllReleased(1000));
-    EXPECT_EQ(0, NoopRun::instanceNum);
-}
-
-}  // namespace android::netdutils
+}  // namespace netdutils
+}  // namespace android
diff --git a/libnetdutils/include/netdutils/InternetAddresses.h b/libnetdutils/include/netdutils/InternetAddresses.h
index e817b78..07a6e90 100644
--- a/libnetdutils/include/netdutils/InternetAddresses.h
+++ b/libnetdutils/include/netdutils/InternetAddresses.h
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef NETDUTILS_INTERNETADDRESSES_H_
+#define NETDUTILS_INTERNETADDRESSES_H_
 
-#include <netdb.h>
 #include <netinet/in.h>
 #include <stdint.h>
 #include <cstring>
@@ -104,16 +104,6 @@
 
 }  // namespace internal_
 
-struct AddrinfoDeleter {
-    void operator()(struct addrinfo* p) const {
-        if (p != nullptr) {
-            freeaddrinfo(p);
-        }
-    }
-};
-
-typedef std::unique_ptr<struct addrinfo, struct AddrinfoDeleter> ScopedAddrinfo;
-
 inline bool usesScopedIds(const in6_addr& ipv6) {
     return (IN6_IS_ADDR_LINKLOCAL(&ipv6) || IN6_IS_ADDR_MC_LINKLOCAL(&ipv6));
 }
@@ -242,23 +232,6 @@
   public:
     // TODO: static forString
 
-    static IPSockAddr toIPSockAddr(const std::string& repr, in_port_t port) {
-        return IPSockAddr(IPAddress::forString(repr), port);
-    }
-    static IPSockAddr toIPSockAddr(const sockaddr& sa) {
-        switch (sa.sa_family) {
-            case AF_INET:
-                return IPSockAddr(*reinterpret_cast<const sockaddr_in*>(&sa));
-            case AF_INET6:
-                return IPSockAddr(*reinterpret_cast<const sockaddr_in6*>(&sa));
-            default:
-                return IPSockAddr();
-        }
-    }
-    static IPSockAddr toIPSockAddr(const sockaddr_storage& ss) {
-        return toIPSockAddr(*reinterpret_cast<const sockaddr*>(&ss));
-    }
-
     IPSockAddr() = default;
     IPSockAddr(const IPSockAddr&) = default;
     IPSockAddr(IPSockAddr&&) = default;
@@ -318,3 +291,5 @@
 
 }  // namespace netdutils
 }  // namespace android
+
+#endif  // NETDUTILS_INTERNETADDRESSES_H_
diff --git a/libnetdutils/include/netdutils/NetworkConstants.h b/libnetdutils/include/netdutils/NetworkConstants.h
index dead9a1..682ceaf 100644
--- a/libnetdutils/include/netdutils/NetworkConstants.h
+++ b/libnetdutils/include/netdutils/NetworkConstants.h
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef NETDUTILS_NETWORKCONSTANTS_H_
+#define NETDUTILS_NETWORKCONSTANTS_H_
 
 namespace android {
 namespace netdutils {
@@ -25,8 +26,7 @@
 constexpr int IPV6_ADDR_LEN = 16;
 constexpr int IPV6_ADDR_BITS = 128;
 
-// Referred from SHA256_DIGEST_LENGTH in boringssl
-constexpr size_t SHA256_SIZE = 32;
-
 }  // namespace netdutils
 }  // namespace android
+
+#endif  // NETDUTILS_NETWORKCONSTANTS_H_
diff --git a/libnetdutils/include/netdutils/Stopwatch.h b/libnetdutils/include/netdutils/Stopwatch.h
index e7b4326..18e2050 100644
--- a/libnetdutils/include/netdutils/Stopwatch.h
+++ b/libnetdutils/include/netdutils/Stopwatch.h
@@ -29,12 +29,22 @@
 
   public:
     Stopwatch() : mStart(clock::now()) {}
+
     virtual ~Stopwatch() = default;
 
+    float timeTaken() const { return getElapsed(clock::now()); }
+
     int64_t timeTakenUs() const { return getElapsedUs(clock::now()); }
-    int64_t getTimeAndResetUs() {
+
+    float getTimeAndReset() {
         const auto& now = clock::now();
-        int64_t elapsed = getElapsedUs(now);
+        float elapsed = getElapsed(now);
+        mStart = now;
+        return elapsed;
+    }
+    float getTimeAndResetUs() {
+        const auto& now = clock::now();
+        float elapsed = getElapsedUs(now);
         mStart = now;
         return elapsed;
     }
@@ -42,6 +52,10 @@
   private:
     time_point mStart;
 
+    float getElapsed(const time_point& now) const {
+        using ms = std::chrono::duration<float, std::ratio<1, 1000>>;
+        return (std::chrono::duration_cast<ms>(now - mStart)).count();
+    }
     int64_t getElapsedUs(const time_point& now) const {
         return (std::chrono::duration_cast<std::chrono::microseconds>(now - mStart)).count();
     }
diff --git a/libnetdutils/include/netdutils/ThreadUtil.h b/libnetdutils/include/netdutils/ThreadUtil.h
index 62e6f70..2ef97ef 100644
--- a/libnetdutils/include/netdutils/ThreadUtil.h
+++ b/libnetdutils/include/netdutils/ThreadUtil.h
@@ -34,22 +34,9 @@
     pthread_attr_t attr;
 };
 
-inline void setThreadName(std::string name) {
-    // MAX_TASK_COMM_LEN=16 is not exported by bionic.
-    const size_t MAX_TASK_COMM_LEN = 16;
-
-    // Crop name to 16 bytes including the NUL byte, as required by pthread_setname_np()
-    if (name.size() >= MAX_TASK_COMM_LEN) name.resize(MAX_TASK_COMM_LEN - 1);
-
-    if (int ret = pthread_setname_np(pthread_self(), name.c_str()); ret != 0) {
-        LOG(WARNING) << "Unable to set thread name to " << name << ": " << strerror(ret);
-    }
-}
-
 template <typename T>
 inline void* runAndDelete(void* obj) {
     std::unique_ptr<T> handler(reinterpret_cast<T*>(obj));
-    setThreadName(handler->threadName().c_str());
     handler->run();
     return nullptr;
 }
diff --git a/resolv/Android.bp b/resolv/Android.bp
new file mode 100644
index 0000000..d1bf2e1
--- /dev/null
+++ b/resolv/Android.bp
@@ -0,0 +1,223 @@
+cc_library_headers {
+    name: "libnetd_resolv_headers",
+    export_include_dirs: ["include"],
+}
+
+aidl_interface {
+    name: "dnsresolver_aidl_interface",
+    local_include_dir: "binder",
+    srcs: [
+        "binder/android/net/IDnsResolver.aidl",
+        "binder/android/net/ResolverParamsParcel.aidl",
+    ],
+    imports: [
+        "netd_event_listener_interface",
+    ],
+    backend: {
+        ndk: {
+            gen_log: true,
+        },
+    },
+    api_dir: "aidl/dnsresolver",
+    versions: [
+        "1",
+        "2",
+    ],
+}
+
+cc_test_library {
+    name: "libnetd_test_metrics_listener",
+    defaults: ["netd_defaults"],
+    srcs: [
+        "tests/BaseTestMetricsListener.cpp",
+        "tests/TestMetrics.cpp",
+    ],
+    include_dirs: [
+        "system/netd/include",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libutils",
+        "netd_event_listener_interface-V1-cpp",
+    ],
+}
+
+cc_library {
+    name: "libnetd_resolv",
+    version_script: "libnetd_resolv.map.txt",
+    defaults: ["netd_defaults"],
+    srcs: [
+        "getaddrinfo.cpp",
+        "gethnamaddr.cpp",
+        "sethostent.cpp",
+        "res_cache.cpp",
+        "res_comp.cpp",
+        "res_debug.cpp",
+        "res_init.cpp",
+        "res_mkquery.cpp",
+        "res_query.cpp",
+        "res_send.cpp",
+        "res_state.cpp",
+        "res_stats.cpp",
+        "Dns64Configuration.cpp",
+        "DnsProxyListener.cpp",
+        "DnsResolver.cpp",
+        "DnsResolverService.cpp",
+        "DnsTlsDispatcher.cpp",
+        "DnsTlsQueryMap.cpp",
+        "DnsTlsTransport.cpp",
+        "DnsTlsServer.cpp",
+        "DnsTlsSessionCache.cpp",
+        "DnsTlsSocket.cpp",
+        "PrivateDnsConfiguration.cpp",
+        "ResolverController.cpp",
+        "ResolverEventReporter.cpp",
+    ],
+    // Link everything statically (except for libc) to minimize our dependence
+    // on system ABIs
+    stl: "libc++_static",
+    static_libs: [
+        "libbase",
+        "libcrypto",
+        "libcutils",
+        "libjsoncpp",
+        "liblog",
+        "libnetdutils",
+        "libssl",
+        "libstatslog_resolv",
+        "libstatssocket",
+        "libsysutils",
+        "libutils",
+        "netd_event_listener_interface-ndk_platform",
+        "dnsresolver_aidl_interface-ndk_platform",
+        "server_configurable_flags",
+        "stats_proto",
+        "libprotobuf-cpp-lite",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    include_dirs: [
+        "system/netd/include",
+        "system/netd/server",
+    ],
+    export_include_dirs: ["include"],
+    // TODO: pie in the sky: make this code clang-tidy clean
+    tidy: false,
+    product_variables: {
+        debuggable: {
+            cppflags: [
+                "-DRESOLV_ALLOW_VERBOSE_LOGGING=1",
+            ],
+        },
+    },
+}
+
+cc_library_static {
+    name: "stats_proto",
+    defaults: ["netd_defaults"],
+    proto: {
+        export_proto_headers: true,
+        type: "lite",
+    },
+    srcs: [
+        "stats.proto",
+    ],
+}
+
+genrule {
+    name: "statslog_resolv.h",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_resolv.h --module resolv --namespace android,net,stats",
+    out: [
+        "statslog_resolv.h",
+    ],
+}
+
+genrule {
+    name: "statslog_resolv.cpp",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_resolv.cpp --module resolv --namespace android,net,stats --importHeader statslog_resolv.h",
+    out: [
+        "statslog_resolv.cpp",
+    ],
+}
+
+cc_library_static {
+    name: "libstatslog_resolv",
+    generated_sources: ["statslog_resolv.cpp"],
+    generated_headers: ["statslog_resolv.h"],
+    defaults: ["netd_defaults"],
+    export_generated_headers: ["statslog_resolv.h"],
+    static_libs: [
+        "libcutils",
+        "liblog",
+        "libstatssocket",
+        "libutils",
+    ],
+}
+
+cc_test {
+    name: "resolv_integration_test",
+    test_suites: ["device-tests"],
+    require_root: true,
+    defaults: ["netd_defaults"],
+    srcs: [
+        "dns_responder/dns_responder.cpp",
+        "resolver_test.cpp",
+        "dnsresolver_binder_test.cpp",
+    ],
+    include_dirs: [
+        "system/netd/resolv/include",
+        "system/netd/server",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libcrypto",
+        "liblog",
+        "libnetd_client",
+        "libssl",
+        "libutils",
+    ],
+    static_libs: [
+        "libgmock",
+        "libnetd_test_dnsresponder",
+        "libnetd_test_metrics_listener",
+        "libnetd_test_tun_interface",
+        "liblogwrap",
+        "libnetdutils",
+        "netd_aidl_interface-V2-cpp",
+        "netd_event_listener_interface-V1-cpp",
+        "dnsresolver_aidl_interface-V2-cpp",
+    ],
+    tidy: false,
+    compile_multilib: "both",
+}
+
+cc_test {
+    name: "resolv_unit_test",
+    test_suites: ["device-tests"],
+    defaults: ["netd_defaults"],
+    srcs: [
+        "dns_tls_test.cpp",
+        "libnetd_resolv_test.cpp",
+        "res_cache_test.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libcrypto",
+        "libcutils",
+        "liblog",
+        "libssl",
+    ],
+    static_libs: [
+        "libgmock",
+        "libnetd_resolv",
+        "libnetd_test_dnsresponder",
+        "libnetdutils",
+        "libprotobuf-cpp-lite",
+        "server_configurable_flags",
+        "stats_proto",
+    ],
+}
diff --git a/resolv/AndroidTest.xml b/resolv/AndroidTest.xml
new file mode 100644
index 0000000..f5715c9
--- /dev/null
+++ b/resolv/AndroidTest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!-- This test config file is auto-generated. -->
+<configuration description="Config for resolv_integration_test.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="resolv_integration_test->/data/local/tmp/resolv_integration_test" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="resolv_integration_test" />
+        <!--
+            On 2018-12-12, GetAddrInfoStressTest_Binder_100 suddenly jumped
+            from ~1xs to ~70s runtime in APCT continuous integration, causing
+            resolv_integration_test to flake with the default 60s timeout.
+            We're not sure what caused the regression, but it's not due to a change
+            in the Android image and unlikely to affect users.
+            Just bump the timeout to 120s for now.
+        -->
+        <option name="native-test-timeout" value="120000" />
+    </test>
+</configuration>
diff --git a/resolv/Dns64Configuration.cpp b/resolv/Dns64Configuration.cpp
new file mode 100644
index 0000000..a1dfdca
--- /dev/null
+++ b/resolv/Dns64Configuration.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Dns64Configuration"
+#define DBG 0
+
+#include "Dns64Configuration.h"
+
+#include <log/log.h>
+#include <netdb.h>
+#include <thread>
+#include <utility>
+
+#include <arpa/inet.h>
+
+#include "DnsResolver.h"
+#include "NetdConstants.h"  // ScopedAddrinfo
+#include "getaddrinfo.h"
+#include "netd_resolv/resolv.h"
+#include "netdutils/BackoffSequence.h"
+#include "netdutils/DumpWriter.h"
+#include "netid_client.h"
+#include "stats.pb.h"
+
+namespace android {
+
+using android::net::NetworkDnsEventReported;
+using netdutils::DumpWriter;
+using netdutils::IPAddress;
+using netdutils::IPPrefix;
+
+namespace net {
+
+const char Dns64Configuration::kIPv4OnlyHost[] = "ipv4only.arpa.";
+const char Dns64Configuration::kIPv4Literal1[] = "192.0.0.170";
+const char Dns64Configuration::kIPv4Literal2[] = "192.0.0.171";
+
+void Dns64Configuration::startPrefixDiscovery(unsigned netId) {
+    std::lock_guard guard(mMutex);
+
+    // TODO: Keep previous prefix for a while
+    // Currently, we remove current prefix, if any, before starting a prefix discovery.
+    // This causes that Netd and framework temporarily forgets DNS64 prefix even the prefix may be
+    // discovered in a short time.
+    removeDns64Config(netId);
+
+    Dns64Config cfg(getNextId(), netId);
+    // Emplace a copy of |cfg| in the map.
+    mDns64Configs.emplace(std::make_pair(netId, cfg));
+
+    // Note that capturing |cfg| in this lambda creates a copy.
+    std::thread discovery_thread([this, cfg] {
+        // Make a mutable copy rather than mark the whole lambda mutable.
+        // No particular reason.
+        Dns64Config evalCfg(cfg);
+
+        auto backoff = netdutils::BackoffSequence<>::Builder()
+                               .withInitialRetransmissionTime(std::chrono::seconds(1))
+                               .withMaximumRetransmissionTime(std::chrono::seconds(3600))
+                               .build();
+
+        while (true) {
+            if (!this->shouldContinueDiscovery(evalCfg)) break;
+
+            android_net_context netcontext{};
+            mGetNetworkContextCallback(evalCfg.netId, 0, &netcontext);
+
+            // Prefix discovery must bypass private DNS because in strict mode
+            // the server generally won't know the NAT64 prefix.
+            netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
+            if (doRfc7050PrefixDiscovery(netcontext, &evalCfg)) {
+                this->recordDns64Config(evalCfg);
+                break;
+            }
+
+            if (!this->shouldContinueDiscovery(evalCfg)) break;
+
+            if (!backoff.hasNextTimeout()) break;
+            {
+                std::unique_lock<std::mutex> cvGuard(mMutex);
+                // TODO: Consider some chrono math, combined with wait_until()
+                // perhaps, to prevent early re-resolves from the removal of
+                // other netids with IPv6-only nameservers.
+                mCv.wait_for(cvGuard, backoff.getNextTimeout());
+            }
+        }
+    });
+    discovery_thread.detach();
+}
+
+void Dns64Configuration::stopPrefixDiscovery(unsigned netId) {
+    std::lock_guard guard(mMutex);
+    removeDns64Config(netId);
+    mCv.notify_all();
+}
+
+IPPrefix Dns64Configuration::getPrefix64Locked(unsigned netId) const REQUIRES(mMutex) {
+    const auto& iter = mDns64Configs.find(netId);
+    if (iter != mDns64Configs.end()) return iter->second.prefix64;
+
+    return IPPrefix{};
+}
+
+IPPrefix Dns64Configuration::getPrefix64(unsigned netId) const {
+    std::lock_guard guard(mMutex);
+    return getPrefix64Locked(netId);
+}
+
+void Dns64Configuration::dump(DumpWriter& dw, unsigned netId) {
+    static const char kLabel[] = "DNS64 config";
+
+    std::lock_guard guard(mMutex);
+
+    const auto& iter = mDns64Configs.find(netId);
+    if (iter == mDns64Configs.end()) {
+        dw.println("%s: none", kLabel);
+        return;
+    }
+
+    const Dns64Config& cfg = iter->second;
+    if (cfg.prefix64.length() == 0) {
+        dw.println("%s: no prefix yet discovered", kLabel);
+    } else {
+        dw.println("%s: discovered prefix %s", kLabel, cfg.prefix64.toString().c_str());
+    }
+}
+
+// NOTE: The full RFC 7050 DNS64 discovery process is not implemented here.
+// Instead, and more simplistic version of the same thing is done, and it
+// currently assumes the DNS64 prefix is a /96.
+bool Dns64Configuration::doRfc7050PrefixDiscovery(const android_net_context& netcontext,
+                                                  Dns64Config* cfg) {
+    ALOGW("(%u, %u) Detecting NAT64 prefix from DNS...", cfg->netId, cfg->discoveryId);
+
+    const struct addrinfo hints = {
+            .ai_family = AF_INET6,
+    };
+
+    // TODO: Refactor so that netd can get all the regular getaddrinfo handling
+    // that regular apps get. We bypass the UNIX socket connection back to
+    // ourselves, which means we also bypass all the special netcontext flag
+    // handling and the resolver event logging.
+    struct addrinfo* res = nullptr;
+    NetworkDnsEventReported event;
+    const int status = android_getaddrinfofornetcontext(kIPv4OnlyHost, nullptr, &hints, &netcontext,
+                                                        &res, &event);
+    ScopedAddrinfo result(res);
+    if (status != 0) {
+        ALOGW("(%u, %u) plat_prefix/dns(%s) status = %d/%s", cfg->netId, cfg->discoveryId,
+              kIPv4OnlyHost, status, gai_strerror(status));
+        return false;
+    }
+
+    // Use only the first result.  If other records are present, possibly
+    // with differing DNS64 prefixes they are ignored. Note that this is a
+    // violation of https://tools.ietf.org/html/rfc7050#section-3
+    //
+    //     "A node MUST look through all of the received AAAA resource records
+    //      to collect one or more Pref64::/n."
+    //
+    // TODO: Consider remedying this.
+    if (result->ai_family != AF_INET6) {
+        ALOGW("(%u, %u) plat_prefix/unexpected address family: %d", cfg->netId, cfg->discoveryId,
+              result->ai_family);
+        return false;
+    }
+    const IPAddress ipv6(reinterpret_cast<sockaddr_in6*>(result->ai_addr)->sin6_addr);
+    // Only /96 DNS64 prefixes are supported at this time.
+    cfg->prefix64 = IPPrefix(ipv6, 96);
+
+    ALOGW("(%u, %u) Detected NAT64 prefix %s", cfg->netId, cfg->discoveryId,
+          cfg->prefix64.toString().c_str());
+
+    return true;
+}
+
+bool Dns64Configuration::isDiscoveryInProgress(const Dns64Config& cfg) const REQUIRES(mMutex) {
+    const auto& iter = mDns64Configs.find(cfg.netId);
+    if (iter == mDns64Configs.end()) return false;
+
+    const Dns64Config& currentCfg = iter->second;
+    return (currentCfg.discoveryId == cfg.discoveryId);
+}
+
+bool Dns64Configuration::reportNat64PrefixStatus(unsigned netId, bool added, const IPPrefix& pfx) {
+    if (pfx.ip().family() != AF_INET6 || pfx.ip().scope_id() != 0) {
+        ALOGW("Abort to send NAT64 prefix notification. Unexpected NAT64 prefix (%u, %d, %s).",
+              netId, added, pfx.toString().c_str());
+        return false;
+    }
+    Nat64PrefixInfo args = {netId, added, pfx.ip().toString(), (uint8_t)pfx.length()};
+    mPrefixCallback(args);
+    return true;
+}
+
+bool Dns64Configuration::shouldContinueDiscovery(const Dns64Config& cfg) {
+    std::lock_guard guard(mMutex);
+    return isDiscoveryInProgress(cfg);
+}
+
+void Dns64Configuration::removeDns64Config(unsigned netId) REQUIRES(mMutex) {
+    IPPrefix prefix = getPrefix64Locked(netId);
+    mDns64Configs.erase(netId);
+    if (!prefix.isUninitialized()) {
+        reportNat64PrefixStatus(netId, PREFIX_REMOVED, prefix);
+    }
+}
+
+void Dns64Configuration::recordDns64Config(const Dns64Config& cfg) {
+    std::lock_guard guard(mMutex);
+    if (!isDiscoveryInProgress(cfg)) return;
+
+    removeDns64Config(cfg.netId);
+    mDns64Configs.emplace(std::make_pair(cfg.netId, cfg));
+
+    reportNat64PrefixStatus(cfg.netId, PREFIX_ADDED, cfg.prefix64);
+
+    // TODO: consider extending INetdEventListener to report the DNS64 prefix
+    // up to ConnectivityService to potentially include this in LinkProperties.
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/resolv/Dns64Configuration.h b/resolv/Dns64Configuration.h
new file mode 100644
index 0000000..58b115e
--- /dev/null
+++ b/resolv/Dns64Configuration.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DNS_DNS64CONFIGURATION_H_
+#define DNS_DNS64CONFIGURATION_H_
+
+#include <netinet/in.h>
+#include <condition_variable>
+#include <cstdlib>
+#include <mutex>
+#include <unordered_map>
+
+#include <android-base/thread_annotations.h>
+#include "netdutils/DumpWriter.h"
+#include "netdutils/InternetAddresses.h"
+
+struct android_net_context;
+
+namespace android {
+namespace net {
+
+/**
+ * This class handles RFC 7050 -style DNS64 prefix discovery.
+ *
+ * The ResolverController starts DNS64 prefix discovery when it observes a
+ * a network with only IPv6 nameservers. (It stops discovery whenever an IPv4
+ * nameserver is added or the network is deleted.)
+ *
+ * Each time prefix discovery is started, a new discoveryId is generated so
+ * that running resolution threads can notice they are no longer the most
+ * recent resolution attempt. This results in the backoff schedule of resolution
+ * being reset.
+ *
+ * Thread-safety: All public methods in this class MUST be thread-safe.
+ * (In other words: this class handles all its locking privately.)
+ */
+class Dns64Configuration {
+  public:
+    // Simple data struct for passing back packet NAT64 prefix event information to the
+    // Dns64PrefixCallback callback.
+    struct Nat64PrefixInfo {
+        unsigned netId;
+        bool added;
+        std::string prefixString;
+        uint8_t prefixLength;
+    };
+
+    // Callback that is triggered for every NAT64 prefix event.
+    using Nat64PrefixCallback = std::function<void(const Nat64PrefixInfo&)>;
+
+    using GetNetworkContextCallback = std::function<void(uint32_t, uint32_t, android_net_context*)>;
+
+    // Parameters from RFC 7050 section 8.
+    static const char kIPv4OnlyHost[];  // "ipv4only.arpa."
+    static const char kIPv4Literal1[];  // 192.0.0.170
+    static const char kIPv4Literal2[];  // 192.0.0.171
+
+    Dns64Configuration() = delete;
+    Dns64Configuration(GetNetworkContextCallback getNetworkCallback,
+                       Nat64PrefixCallback prefixCallback)
+        : mGetNetworkContextCallback(std::move(getNetworkCallback)),
+          mPrefixCallback(std::move(prefixCallback)) {}
+    Dns64Configuration(const Dns64Configuration&) = delete;
+    Dns64Configuration(Dns64Configuration&&) = delete;
+    Dns64Configuration& operator=(const Dns64Configuration&) = delete;
+    Dns64Configuration& operator=(Dns64Configuration&&) = delete;
+
+    void startPrefixDiscovery(unsigned netId);
+    void stopPrefixDiscovery(unsigned netId);
+    netdutils::IPPrefix getPrefix64(unsigned netId) const;
+
+    void dump(netdutils::DumpWriter& dw, unsigned netId);
+
+  private:
+    struct Dns64Config {
+        Dns64Config(unsigned pseudoRandomId, unsigned network)
+            : discoveryId(pseudoRandomId), netId(network) {}
+
+        const unsigned int discoveryId;
+        const unsigned int netId;
+        netdutils::IPPrefix prefix64{};
+    };
+
+    enum { PREFIX_REMOVED, PREFIX_ADDED };
+
+    static bool doRfc7050PrefixDiscovery(const android_net_context& netcontext, Dns64Config* cfg);
+
+    unsigned getNextId() REQUIRES(mMutex) { return mNextId++; }
+    netdutils::IPPrefix getPrefix64Locked(unsigned netId) const REQUIRES(mMutex);
+    bool isDiscoveryInProgress(const Dns64Config& cfg) const REQUIRES(mMutex);
+    bool reportNat64PrefixStatus(unsigned netId, bool added, const netdutils::IPPrefix& pfx)
+            REQUIRES(mMutex);
+
+    bool shouldContinueDiscovery(const Dns64Config& cfg);
+    void recordDns64Config(const Dns64Config& cfg);
+    void removeDns64Config(unsigned netId) REQUIRES(mMutex);
+
+    mutable std::mutex mMutex;
+    std::condition_variable mCv;
+    unsigned int mNextId GUARDED_BY(mMutex);
+    std::unordered_map<unsigned, Dns64Config> mDns64Configs GUARDED_BY(mMutex);
+    const GetNetworkContextCallback mGetNetworkContextCallback;
+    const Nat64PrefixCallback mPrefixCallback;
+};
+
+}  // namespace net
+}  // namespace android
+
+#endif  // DNS_DNS64CONFIGURATION_H_
diff --git a/resolv/DnsProxyListener.cpp b/resolv/DnsProxyListener.cpp
new file mode 100644
index 0000000..8925bc4
--- /dev/null
+++ b/resolv/DnsProxyListener.cpp
@@ -0,0 +1,1259 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DnsProxyListener.h"
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <errno.h>
+#include <linux/if.h>
+#include <math.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#define LOG_TAG "DnsProxyListener"
+
+#include <algorithm>
+#include <vector>
+
+#include <android-base/stringprintf.h>
+#include <android/multinetwork.h>  // ResNsendFlags
+#include <cutils/misc.h>           // FIRST_APPLICATION_UID
+#include <netdutils/InternetAddresses.h>
+#include <netdutils/OperationLimiter.h>
+#include <netdutils/ResponseCode.h>
+#include <netdutils/Slice.h>
+#include <netdutils/Stopwatch.h>
+#include <netdutils/ThreadUtil.h>
+#include <private/android_filesystem_config.h>  // AID_SYSTEM
+#include <statslog_resolv.h>
+#include <sysutils/SocketClient.h>
+
+#include "DnsResolver.h"
+#include "NetdClient.h"  // NETID_USE_LOCAL_NAMESERVERS
+#include "NetdPermissions.h"
+#include "PrivateDnsConfiguration.h"
+#include "ResolverEventReporter.h"
+#include "getaddrinfo.h"
+#include "gethnamaddr.h"
+#include "netd_resolv/stats.h"  // RCODE_TIMEOUT
+#include "res_send.h"
+#include "resolv_cache.h"
+#include "resolv_private.h"
+#include "stats.pb.h"
+
+using aidl::android::net::metrics::INetdEventListener;
+using android::net::NetworkDnsEventReported;
+
+namespace android {
+
+using netdutils::ResponseCode;
+using netdutils::Stopwatch;
+
+namespace net {
+namespace {
+
+// Limits the number of outstanding DNS queries by client UID.
+constexpr int MAX_QUERIES_PER_UID = 256;
+
+// Max packet size for answer, sync with getaddrinfo.c
+constexpr int MAXPACKET = 8 * 1024;
+
+android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);
+
+void logArguments(int argc, char** argv) {
+    if (!WOULD_LOG(VERBOSE)) return;
+    for (int i = 0; i < argc; i++) {
+        LOG(VERBOSE) << __func__ << ": argv[" << i << "]=" << (argv[i] ? argv[i] : "null");
+    }
+}
+
+template<typename T>
+void tryThreadOrError(SocketClient* cli, T* handler) {
+    cli->incRef();
+
+    const int rval = netdutils::threadLaunch(handler);
+    if (rval == 0) {
+        // SocketClient decRef() happens in the handler's run() method.
+        return;
+    }
+
+    char* msg = nullptr;
+    asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
+    cli->sendMsg(ResponseCode::OperationFailed, msg, false);
+    free(msg);
+
+    delete handler;
+    cli->decRef();
+}
+
+bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
+    if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
+        return false;
+    }
+    *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
+    return true;
+}
+
+constexpr bool requestingUseLocalNameservers(unsigned flags) {
+    return (flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) != 0;
+}
+
+inline bool queryingViaTls(unsigned dns_netid) {
+    // TODO: The simpler PrivateDnsStatus should suffice here.
+    ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}};
+    gPrivateDnsConfiguration.getStatus(dns_netid, &privateDnsStatus);
+    switch (static_cast<PrivateDnsMode>(privateDnsStatus.mode)) {
+        case PrivateDnsMode::OPPORTUNISTIC:
+            for (int i = 0; i < privateDnsStatus.numServers; i++) {
+                if (privateDnsStatus.serverStatus[i].validation == Validation::success) {
+                    return true;
+                }
+            }
+            return false;
+        case PrivateDnsMode::STRICT:
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool hasPermissionToBypassPrivateDns(uid_t uid) {
+    static_assert(AID_SYSTEM >= 0 && AID_SYSTEM < FIRST_APPLICATION_UID,
+        "Calls from AID_SYSTEM must not result in a permission check to avoid deadlock.");
+    if (uid >= 0 && uid < FIRST_APPLICATION_UID) {
+        return true;
+    }
+
+    for (const char* const permission :
+         {PERM_CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERM_NETWORK_BYPASS_PRIVATE_DNS,
+          PERM_MAINLINE_NETWORK_STACK}) {
+        if (gResNetdCallbacks.check_calling_permission(permission)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void maybeFixupNetContext(android_net_context* ctx) {
+    if (requestingUseLocalNameservers(ctx->flags) && !hasPermissionToBypassPrivateDns(ctx->uid)) {
+        // Not permitted; clear the flag.
+        ctx->flags &= ~NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
+    }
+
+    if (!requestingUseLocalNameservers(ctx->flags)) {
+        // If we're not explicitly bypassing DNS-over-TLS servers, check whether
+        // DNS-over-TLS is in use as an indicator for when to use more modern
+        // DNS resolution mechanics.
+        if (queryingViaTls(ctx->dns_netid)) {
+            ctx->flags |= NET_CONTEXT_FLAG_USE_EDNS;
+        }
+    }
+}
+
+void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
+                          socklen_t addrlen);
+
+int extractResNsendAnswers(const uint8_t* answer, size_t anslen, int ipType,
+                           std::vector<std::string>* ip_addrs) {
+    int total_ip_addr_count = 0;
+    ns_msg handle;
+    if (ns_initparse((const uint8_t*) answer, anslen, &handle) < 0) {
+        return 0;
+    }
+    int ancount = ns_msg_count(handle, ns_s_an);
+    ns_rr rr;
+    for (int i = 0; i < ancount; i++) {
+        if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
+            continue;
+        }
+        const uint8_t* rdata = ns_rr_rdata(rr);
+        if (ipType == ns_t_a) {
+            sockaddr_in sin = {.sin_family = AF_INET};
+            memcpy(&sin.sin_addr, rdata, sizeof(sin.sin_addr));
+            addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
+            total_ip_addr_count++;
+        } else if (ipType == ns_t_aaaa) {
+            sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
+            memcpy(&sin6.sin6_addr, rdata, sizeof(sin6.sin6_addr));
+            addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
+            total_ip_addr_count++;
+        }
+    }
+
+    return total_ip_addr_count;
+}
+
+int extractGetAddrInfoAnswers(const addrinfo* result, std::vector<std::string>* ip_addrs) {
+    int total_ip_addr_count = 0;
+    if (result == nullptr) {
+        return 0;
+    }
+    for (const addrinfo* ai = result; ai; ai = ai->ai_next) {
+        sockaddr* ai_addr = ai->ai_addr;
+        if (ai_addr) {
+            addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen);
+            total_ip_addr_count++;
+        }
+    }
+    return total_ip_addr_count;
+}
+
+int extractGetHostByNameAnswers(const hostent* hp, std::vector<std::string>* ip_addrs) {
+    int total_ip_addr_count = 0;
+    if (hp == nullptr) {
+        return 0;
+    }
+    if (hp->h_addrtype == AF_INET) {
+        in_addr** list = (in_addr**) hp->h_addr_list;
+        for (int i = 0; list[i] != nullptr; i++) {
+            sockaddr_in sin = {.sin_family = AF_INET, .sin_addr = *list[i]};
+            addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
+            total_ip_addr_count++;
+        }
+    } else if (hp->h_addrtype == AF_INET6) {
+        in6_addr** list = (in6_addr**) hp->h_addr_list;
+        for (int i = 0; list[i] != nullptr; i++) {
+            sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = *list[i]};
+            addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
+            total_ip_addr_count++;
+        }
+    }
+    return total_ip_addr_count;
+}
+
+int rcodeToAiError(int rcode) {
+    switch (rcode) {
+        case NOERROR:
+            return 0;
+        case RCODE_TIMEOUT:
+            return NETD_RESOLV_TIMEOUT;
+        default:
+            return EAI_NODATA;
+    }
+}
+
+int resNSendToAiError(int err, int rcode) {
+    if (err > 0) {
+        return rcodeToAiError(rcode);
+    }
+    if (err == -ETIMEDOUT) {
+        return NETD_RESOLV_TIMEOUT;
+    }
+    return EAI_SYSTEM;
+}
+
+template <typename IntegralType>
+bool simpleStrtoul(const char* input, IntegralType* output, int base = 10) {
+    char* endPtr;
+    errno = 0;
+    auto result = strtoul(input, &endPtr, base);
+    // Check the length in order to ensure there is no "-" sign
+    if (!*input || *endPtr || (endPtr - input) != static_cast<ptrdiff_t>(strlen(input)) ||
+        (errno == ERANGE && (result == ULONG_MAX))) {
+        return false;
+    }
+    *output = result;
+    return true;
+}
+
+bool setQueryId(uint8_t* msg, size_t msgLen, uint16_t query_id) {
+    if (msgLen < sizeof(HEADER)) {
+        errno = EINVAL;
+        return false;
+    }
+    auto hp = reinterpret_cast<HEADER*>(msg);
+    hp->id = htons(query_id);
+    return true;
+}
+
+bool parseQuery(const uint8_t* msg, size_t msgLen, uint16_t* query_id, int* rr_type,
+                std::string* rr_name) {
+    ns_msg handle;
+    ns_rr rr;
+    if (ns_initparse((const uint8_t*)msg, msgLen, &handle) < 0 ||
+        ns_parserr(&handle, ns_s_qd, 0, &rr) < 0) {
+        return false;
+    }
+    *query_id = ns_msg_id(handle);
+    *rr_name = ns_rr_name(rr);
+    *rr_type = ns_rr_type(rr);
+    return true;
+}
+
+void initDnsEvent(NetworkDnsEventReported* event) {
+    // The value 0 has the special meaning of unset/unknown in Westworld atoms.
+    event->set_hints_ai_flags(-1);
+    event->set_res_nsend_flags(-1);
+}
+
+// Return 0 if the event should not be logged.
+// Otherwise, return subsampling_denom
+uint32_t getDnsEventSubsamplingRate(int netid, int returnCode) {
+    uint32_t subsampling_denom = resolv_cache_get_subsampling_denom(netid, returnCode);
+    if (subsampling_denom == 0) return 0;
+    // Sample the event with a chance of 1 / denom.
+    return (arc4random_uniform(subsampling_denom) == 0) ? subsampling_denom : 0;
+}
+
+void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs,
+                    int returnCode, NetworkDnsEventReported& event, const std::string& query_name,
+                    const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) {
+    if (uint32_t rate = getDnsEventSubsamplingRate(netContext.dns_netid, returnCode)) {
+        const std::string& dnsQueryStats = event.dns_query_events().SerializeAsString();
+        stats::BytesField dnsQueryBytesField{dnsQueryStats.c_str(), dnsQueryStats.size()};
+        event.set_return_code(static_cast<ReturnCode>(returnCode));
+        android::net::stats::stats_write(android::net::stats::NETWORK_DNS_EVENT_REPORTED,
+                                         event.event_type(), event.return_code(),
+                                         event.latency_micros(), event.hints_ai_flags(),
+                                         event.res_nsend_flags(), event.network_type(),
+                                         event.private_dns_modes(), dnsQueryBytesField, rate);
+    }
+
+    const auto& listeners = ResolverEventReporter::getInstance().getListeners();
+    if (listeners.size() == 0) {
+        LOG(ERROR) << __func__
+                   << ": DNS event not sent since no INetdEventListener receiver is available.";
+        return;
+    }
+    const int latencyMs = latencyUs / 1000;
+    for (const auto& it : listeners) {
+        it->onDnsEvent(netContext.dns_netid, eventType, returnCode, latencyMs, query_name, ip_addrs,
+                       total_ip_addr_count, netContext.uid);
+    }
+}
+
+bool onlyIPv4Answers(const addrinfo* res) {
+    // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
+
+    for (const addrinfo* ai = res; ai; ai = ai->ai_next)
+        if (ai->ai_family != AF_INET) return false;
+
+    return true;
+}
+
+bool isSpecialUseIPv4Address(const struct in_addr& ia) {
+    const uint32_t addr = ntohl(ia.s_addr);
+
+    // Only check necessary IP ranges in RFC 5735 section 4
+    return ((addr & 0xff000000) == 0x00000000) ||  // "This" Network
+           ((addr & 0xff000000) == 0x7f000000) ||  // Loopback
+           ((addr & 0xffff0000) == 0xa9fe0000) ||  // Link Local
+           ((addr & 0xf0000000) == 0xe0000000) ||  // Multicast
+           (addr == INADDR_BROADCAST);             // Limited Broadcast
+}
+
+bool isSpecialUseIPv4Address(const struct sockaddr* sa) {
+    if (sa->sa_family != AF_INET) return false;
+
+    return isSpecialUseIPv4Address(((struct sockaddr_in*) sa)->sin_addr);
+}
+
+bool onlyNonSpecialUseIPv4Addresses(struct hostent* hp) {
+    // Null hostent pointer isn't checked because the caller doesn't pass null pointer.
+
+    if (hp->h_addrtype != AF_INET) return false;
+
+    for (int i = 0; hp->h_addr_list[i] != nullptr; i++)
+        if (isSpecialUseIPv4Address(*(struct in_addr*) hp->h_addr_list[i])) return false;
+
+    return true;
+}
+
+bool onlyNonSpecialUseIPv4Addresses(const addrinfo* res) {
+    // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
+
+    for (const addrinfo* ai = res; ai; ai = ai->ai_next) {
+        if (ai->ai_family != AF_INET) return false;
+        if (isSpecialUseIPv4Address(ai->ai_addr)) return false;
+    }
+
+    return true;
+}
+
+void logDnsQueryResult(const struct hostent* hp) {
+    if (!WOULD_LOG(DEBUG)) return;
+    if (hp == nullptr) return;
+
+    LOG(DEBUG) << __func__ << ": DNS records:";
+    for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
+        char ip_addr[INET6_ADDRSTRLEN];
+        if (inet_ntop(hp->h_addrtype, hp->h_addr_list[i], ip_addr, sizeof(ip_addr)) != nullptr) {
+            LOG(DEBUG) << __func__ << ": [" << i << "] " << hp->h_addrtype;
+        } else {
+            PLOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail";
+        }
+    }
+}
+
+void logDnsQueryResult(const addrinfo* res) {
+    if (!WOULD_LOG(DEBUG)) return;
+    if (res == nullptr) return;
+
+    int i;
+    const addrinfo* ai;
+    LOG(DEBUG) << __func__ << ": DNS records:";
+    for (ai = res, i = 0; ai; ai = ai->ai_next, i++) {
+        if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) continue;
+        char ip_addr[INET6_ADDRSTRLEN];
+        int ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0,
+                              NI_NUMERICHOST);
+        if (!ret) {
+            LOG(DEBUG) << __func__ << ": [" << i << "] " << ai->ai_flags << " " << ai->ai_family
+                       << " " << ai->ai_socktype << " " << ai->ai_protocol;
+        } else {
+            LOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail " << ret;
+        }
+    }
+}
+
+bool isValidNat64Prefix(const netdutils::IPPrefix prefix) {
+    if (prefix.family() != AF_INET6) {
+        LOG(ERROR) << __func__ << ": Only IPv6 NAT64 prefixes are supported " << prefix.family();
+        return false;
+    }
+    if (prefix.length() != 96) {
+        LOG(ERROR) << __func__ << ": Only /96 NAT64 prefixes are supported " << prefix.length();
+        return false;
+    }
+    return true;
+}
+
+bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, struct hostent* hp) {
+    if (hp == nullptr) return false;
+    if (!onlyNonSpecialUseIPv4Addresses(hp)) return false;
+    if (!isValidNat64Prefix(prefix)) return false;
+
+    struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
+    struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
+    for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
+        struct in_addr iaOriginal = *(struct in_addr*) hp->h_addr_list[i];
+        struct in6_addr* ia6 = (struct in6_addr*) hp->h_addr_list[i];
+        memset(ia6, 0, sizeof(struct in6_addr));
+
+        // Synthesize /96 NAT64 prefix in place. The space has reserved by getanswer() and
+        // _hf_gethtbyname2() in system/netd/resolv/gethnamaddr.cpp and
+        // system/netd/resolv/sethostent.cpp.
+        *ia6 = v6prefix->sin6_addr;
+        ia6->s6_addr32[3] = iaOriginal.s_addr;
+
+        if (WOULD_LOG(DEBUG)) {
+            char buf[INET6_ADDRSTRLEN];  // big enough for either IPv4 or IPv6
+            inet_ntop(AF_INET, &iaOriginal.s_addr, buf, sizeof(buf));
+            LOG(DEBUG) << __func__ << ": DNS A record: " << buf;
+            inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
+            LOG(DEBUG) << __func__ << ": NAT64 prefix: " << buf;
+            inet_ntop(AF_INET6, ia6, buf, sizeof(buf));
+            LOG(DEBUG) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
+        }
+    }
+    hp->h_addrtype = AF_INET6;
+    hp->h_length = sizeof(in6_addr);
+
+    logDnsQueryResult(hp);
+    return true;
+}
+
+bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, addrinfo* result) {
+    if (result == nullptr) return false;
+    if (!onlyNonSpecialUseIPv4Addresses(result)) return false;
+    if (!isValidNat64Prefix(prefix)) return false;
+
+    struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
+    struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
+    for (addrinfo* ai = result; ai; ai = ai->ai_next) {
+        struct sockaddr_in sinOriginal = *(struct sockaddr_in*) ai->ai_addr;
+        struct sockaddr_in6* sin6 = (struct sockaddr_in6*) ai->ai_addr;
+        memset(sin6, 0, sizeof(sockaddr_in6));
+
+        // Synthesize /96 NAT64 prefix in place. The space has reserved by get_ai() in
+        // system/netd/resolv/getaddrinfo.cpp.
+        sin6->sin6_addr = v6prefix->sin6_addr;
+        sin6->sin6_addr.s6_addr32[3] = sinOriginal.sin_addr.s_addr;
+        sin6->sin6_family = AF_INET6;
+        sin6->sin6_port = sinOriginal.sin_port;
+        ai->ai_addrlen = sizeof(struct sockaddr_in6);
+        ai->ai_family = AF_INET6;
+
+        if (WOULD_LOG(DEBUG)) {
+            char buf[INET6_ADDRSTRLEN];  // big enough for either IPv4 or IPv6
+            inet_ntop(AF_INET, &sinOriginal.sin_addr.s_addr, buf, sizeof(buf));
+            LOG(DEBUG) << __func__ << ": DNS A record: " << buf;
+            inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
+            LOG(DEBUG) << __func__ << ": NAT64 prefix: " << buf;
+            inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf));
+            LOG(DEBUG) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
+        }
+    }
+    logDnsQueryResult(result);
+    return true;
+}
+
+bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) {
+    return !gDnsResolv->resolverCtrl.getPrefix64(netId, prefix);
+}
+
+}  // namespace
+
+DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) {
+    registerCmd(new GetAddrInfoCmd());
+    registerCmd(new GetHostByAddrCmd());
+    registerCmd(new GetHostByNameCmd());
+    registerCmd(new ResNSendCommand());
+    registerCmd(new GetDnsNetIdCommand());
+}
+
+DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, char* host, char* service,
+                                                         addrinfo* hints,
+                                                         const android_net_context& netcontext)
+    : mClient(c), mHost(host), mService(service), mHints(hints), mNetContext(netcontext) {}
+
+DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() {
+    free(mHost);
+    free(mService);
+    free(mHints);
+}
+
+static bool sendBE32(SocketClient* c, uint32_t data) {
+    uint32_t be_data = htonl(data);
+    return c->sendData(&be_data, sizeof(be_data)) == 0;
+}
+
+// Sends 4 bytes of big-endian length, followed by the data.
+// Returns true on success.
+static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
+    return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
+}
+
+// Returns true on success
+static bool sendhostent(SocketClient* c, hostent* hp) {
+    bool success = true;
+    int i;
+    if (hp->h_name != nullptr) {
+        success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name);
+    } else {
+        success &= sendLenAndData(c, 0, "") == 0;
+    }
+
+    for (i=0; hp->h_aliases[i] != nullptr; i++) {
+        success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]);
+    }
+    success &= sendLenAndData(c, 0, ""); // null to indicate we're done
+
+    uint32_t buf = htonl(hp->h_addrtype);
+    success &= c->sendData(&buf, sizeof(buf)) == 0;
+
+    buf = htonl(hp->h_length);
+    success &= c->sendData(&buf, sizeof(buf)) == 0;
+
+    for (i=0; hp->h_addr_list[i] != nullptr; i++) {
+        success &= sendLenAndData(c, 16, hp->h_addr_list[i]);
+    }
+    success &= sendLenAndData(c, 0, ""); // null to indicate we're done
+    return success;
+}
+
+static bool sendaddrinfo(SocketClient* c, addrinfo* ai) {
+    // struct addrinfo {
+    //      int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
+    //      int     ai_family;      /* PF_xxx */
+    //      int     ai_socktype;    /* SOCK_xxx */
+    //      int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+    //      socklen_t ai_addrlen;   /* length of ai_addr */
+    //      char    *ai_canonname;  /* canonical name for hostname */
+    //      struct  sockaddr *ai_addr;      /* binary address */
+    //      struct  addrinfo *ai_next;      /* next structure in linked list */
+    // };
+
+    // Write the struct piece by piece because we might be a 64-bit netd
+    // talking to a 32-bit process.
+    bool success =
+            sendBE32(c, ai->ai_flags) &&
+            sendBE32(c, ai->ai_family) &&
+            sendBE32(c, ai->ai_socktype) &&
+            sendBE32(c, ai->ai_protocol);
+    if (!success) {
+        return false;
+    }
+
+    // ai_addrlen and ai_addr.
+    if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
+        return false;
+    }
+
+    // strlen(ai_canonname) and ai_canonname.
+    if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) {
+        return false;
+    }
+
+    return true;
+}
+
+void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res,
+                                                            NetworkDnsEventReported* event) {
+    if (mHost == nullptr) return;
+
+    const bool ipv6WantedButNoData = (mHints && mHints->ai_family == AF_INET6 && *rv == EAI_NODATA);
+    const bool unspecWantedButNoIPv6 =
+            ((!mHints || mHints->ai_family == AF_UNSPEC) && *rv == 0 && onlyIPv4Answers(*res));
+
+    if (!ipv6WantedButNoData && !unspecWantedButNoIPv6) {
+        return;
+    }
+
+    netdutils::IPPrefix prefix{};
+    if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
+        return;
+    }
+
+    if (ipv6WantedButNoData) {
+        // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
+        const uid_t uid = mClient->getUid();
+        if (queryLimiter.start(uid)) {
+            mHints->ai_family = AF_INET;
+            // Don't need to do freeaddrinfo(res) before starting new DNS lookup because previous
+            // DNS lookup is failed with error EAI_NODATA.
+            *rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, res,
+                                                   event);
+            queryLimiter.finish(uid);
+            if (*rv) {
+                *rv = EAI_NODATA;  // return original error code
+                return;
+            }
+        } else {
+            LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
+            return;
+        }
+    }
+
+    if (!synthesizeNat64PrefixWithARecord(prefix, *res)) {
+        if (ipv6WantedButNoData) {
+            // If caller wants IPv6 answers but no data and failed to synthesize IPv6 answers,
+            // don't return the IPv4 answers.
+            *rv = EAI_NODATA;  // return original error code
+            if (*res) {
+                freeaddrinfo(*res);
+                *res = nullptr;
+            }
+        }
+    }
+}
+
+void DnsProxyListener::GetAddrInfoHandler::run() {
+    LOG(DEBUG) << "GetAddrInfoHandler::run: {" << mNetContext.app_netid << " "
+               << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
+               << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
+
+    addrinfo* result = nullptr;
+    Stopwatch s;
+    maybeFixupNetContext(&mNetContext);
+    const uid_t uid = mClient->getUid();
+    int32_t rv = 0;
+    NetworkDnsEventReported event;
+    initDnsEvent(&event);
+    if (queryLimiter.start(uid)) {
+        rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, &result,
+                                              &event);
+        queryLimiter.finish(uid);
+    } else {
+        // Note that this error code is currently not passed down to the client.
+        // android_getaddrinfo_proxy() returns EAI_NODATA on any error.
+        rv = EAI_MEMORY;
+        LOG(ERROR) << "GetAddrInfoHandler::run: from UID " << uid
+                   << ", max concurrent queries reached";
+    }
+
+    doDns64Synthesis(&rv, &result, &event);
+    const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
+    event.set_latency_micros(latencyUs);
+    event.set_event_type(EVENT_GETADDRINFO);
+    event.set_hints_ai_flags((mHints ? mHints->ai_flags : 0));
+
+    if (rv) {
+        // getaddrinfo failed
+        mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv));
+    } else {
+        bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
+        addrinfo* ai = result;
+        while (ai && success) {
+            success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
+            ai = ai->ai_next;
+        }
+        success = success && sendBE32(mClient, 0);
+        if (!success) {
+            LOG(WARNING) << "GetAddrInfoHandler::run: Error writing DNS result to client";
+        }
+    }
+    std::vector<std::string> ip_addrs;
+    const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs);
+    reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost,
+                   ip_addrs, total_ip_addr_count);
+    freeaddrinfo(result);
+    mClient->decRef();
+}
+
+namespace {
+
+void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
+                          socklen_t addrlen) {
+    // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT
+    // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether
+    // some addresses didn't get logged.
+    if (ip_addrs->size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) {
+        char ip_addr[INET6_ADDRSTRLEN];
+        if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) {
+            ip_addrs->push_back(std::string(ip_addr));
+        }
+    }
+}
+
+}  // namespace
+
+DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : FrameworkCommand("getaddrinfo") {}
+
+int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
+                                            int argc, char **argv) {
+    logArguments(argc, argv);
+
+    if (argc != 8) {
+        char* msg = nullptr;
+        asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc);
+        LOG(WARNING) << "GetAddrInfoCmd::runCommand: " << (msg ? msg : "null");
+        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
+        free(msg);
+        return -1;
+    }
+
+    char* name = argv[1];
+    if (strcmp("^", name) == 0) {
+        name = nullptr;
+    } else {
+        name = strdup(name);
+    }
+
+    char* service = argv[2];
+    if (strcmp("^", service) == 0) {
+        service = nullptr;
+    } else {
+        service = strdup(service);
+    }
+
+    addrinfo* hints = nullptr;
+    int ai_flags = strtol(argv[3], nullptr, 10);
+    int ai_family = strtol(argv[4], nullptr, 10);
+    int ai_socktype = strtol(argv[5], nullptr, 10);
+    int ai_protocol = strtol(argv[6], nullptr, 10);
+    unsigned netId = strtoul(argv[7], nullptr, 10);
+    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
+    const uid_t uid = cli->getUid();
+
+    android_net_context netcontext;
+    gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
+
+    if (useLocalNameservers) {
+        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
+    }
+
+    if (ai_flags != -1 || ai_family != -1 ||
+        ai_socktype != -1 || ai_protocol != -1) {
+        hints = (addrinfo*) calloc(1, sizeof(addrinfo));
+        hints->ai_flags = ai_flags;
+        hints->ai_family = ai_family;
+        hints->ai_socktype = ai_socktype;
+        hints->ai_protocol = ai_protocol;
+    }
+
+    DnsProxyListener::GetAddrInfoHandler* handler =
+            new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, netcontext);
+    tryThreadOrError(cli, handler);
+    return 0;
+}
+
+/*******************************************************
+ *                  ResNSendCommand                    *
+ *******************************************************/
+DnsProxyListener::ResNSendCommand::ResNSendCommand() : FrameworkCommand("resnsend") {}
+
+int DnsProxyListener::ResNSendCommand::runCommand(SocketClient* cli, int argc, char** argv) {
+    logArguments(argc, argv);
+
+    const uid_t uid = cli->getUid();
+    if (argc != 4) {
+        LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
+                     << ", invalid number of arguments to resnsend: " << argc;
+        sendBE32(cli, -EINVAL);
+        return -1;
+    }
+
+    unsigned netId;
+    if (!simpleStrtoul(argv[1], &netId)) {
+        LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
+                     << ", invalid netId";
+        sendBE32(cli, -EINVAL);
+        return -1;
+    }
+
+    uint32_t flags;
+    if (!simpleStrtoul(argv[2], &flags)) {
+        LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
+                     << ", invalid flags";
+        sendBE32(cli, -EINVAL);
+        return -1;
+    }
+
+    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
+
+    android_net_context netcontext;
+    gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
+
+    if (useLocalNameservers) {
+        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
+    }
+
+    DnsProxyListener::ResNSendHandler* handler =
+            new DnsProxyListener::ResNSendHandler(cli, argv[3], flags, netcontext);
+    tryThreadOrError(cli, handler);
+    return 0;
+}
+
+DnsProxyListener::ResNSendHandler::ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
+                                                   const android_net_context& netcontext)
+    : mClient(c), mMsg(std::move(msg)), mFlags(flags), mNetContext(netcontext) {}
+
+DnsProxyListener::ResNSendHandler::~ResNSendHandler() {
+    mClient->decRef();
+}
+
+void DnsProxyListener::ResNSendHandler::run() {
+    LOG(DEBUG) << "ResNSendHandler::run: " << mFlags << " / {" << mNetContext.app_netid << " "
+               << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
+               << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
+
+    Stopwatch s;
+    maybeFixupNetContext(&mNetContext);
+
+    // Decode
+    std::vector<uint8_t> msg(MAXPACKET, 0);
+
+    // Max length of mMsg is less than 1024 since the CMD_BUF_SIZE in FrameworkListener is 1024
+    int msgLen = b64_pton(mMsg.c_str(), msg.data(), MAXPACKET);
+    if (msgLen == -1) {
+        // Decode fail
+        sendBE32(mClient, -EILSEQ);
+        return;
+    }
+
+    const uid_t uid = mClient->getUid();
+    int rr_type = 0;
+    std::string rr_name;
+    uint16_t original_query_id = 0;
+
+    // TODO: Handle the case which is msg contains more than one query
+    if (!parseQuery(msg.data(), msgLen, &original_query_id, &rr_type, &rr_name) ||
+        !setQueryId(msg.data(), msgLen, arc4random_uniform(65536))) {
+        // If the query couldn't be parsed, block the request.
+        LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", invalid query";
+        sendBE32(mClient, -EINVAL);
+        return;
+    }
+
+    // Send DNS query
+    std::vector<uint8_t> ansBuf(MAXPACKET, 0);
+    int arcode, nsendAns = -1;
+    NetworkDnsEventReported event;
+    initDnsEvent(&event);
+    if (queryLimiter.start(uid)) {
+        nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET,
+                                    &arcode, static_cast<ResNsendFlags>(mFlags), &event);
+        queryLimiter.finish(uid);
+    } else {
+        LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid
+                     << ", max concurrent queries reached";
+        nsendAns = -EBUSY;
+    }
+
+    const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
+    event.set_latency_micros(latencyUs);
+    event.set_event_type(EVENT_RES_NSEND);
+    event.set_res_nsend_flags(static_cast<ResNsendFlags>(mFlags));
+
+    // Fail, send -errno
+    if (nsendAns < 0) {
+        sendBE32(mClient, nsendAns);
+        if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
+            reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
+                           resNSendToAiError(nsendAns, arcode), event, rr_name);
+        }
+        return;
+    }
+
+    // Send rcode
+    if (!sendBE32(mClient, arcode)) {
+        PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send rcode to uid " << uid;
+        return;
+    }
+
+    // Restore query id and send answer
+    if (!setQueryId(ansBuf.data(), nsendAns, original_query_id) ||
+        !sendLenAndData(mClient, nsendAns, ansBuf.data())) {
+        PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send answer to uid " << uid;
+        return;
+    }
+
+    if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
+        std::vector<std::string> ip_addrs;
+        const int total_ip_addr_count =
+                extractResNsendAnswers((uint8_t*) ansBuf.data(), nsendAns, rr_type, &ip_addrs);
+        reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
+                       resNSendToAiError(nsendAns, arcode), event, rr_name, ip_addrs,
+                       total_ip_addr_count);
+    }
+}
+
+namespace {
+
+bool sendCodeAndBe32(SocketClient* c, int code, int data) {
+    return !c->sendCode(code) && sendBE32(c, data);
+}
+
+}  // namespace
+
+/*******************************************************
+ *                  GetDnsNetId                        *
+ *******************************************************/
+DnsProxyListener::GetDnsNetIdCommand::GetDnsNetIdCommand() : FrameworkCommand("getdnsnetid") {}
+
+int DnsProxyListener::GetDnsNetIdCommand::runCommand(SocketClient* cli, int argc, char** argv) {
+    logArguments(argc, argv);
+
+    const uid_t uid = cli->getUid();
+    if (argc != 2) {
+        LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
+                     << ", invalid number of arguments to getdnsnetid: " << argc;
+        sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
+        return -1;
+    }
+
+    unsigned netId;
+    if (!simpleStrtoul(argv[1], &netId)) {
+        LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
+                     << ", invalid netId";
+        sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
+        return -1;
+    }
+
+    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
+    android_net_context netcontext;
+    gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
+
+    if (useLocalNameservers) {
+        netcontext.app_netid |= NETID_USE_LOCAL_NAMESERVERS;
+    }
+
+    return sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, netcontext.app_netid) ? 0 : -1;
+}
+
+/*******************************************************
+ *                  GetHostByName                      *
+ *******************************************************/
+DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd() : FrameworkCommand("gethostbyname") {}
+
+int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
+                                            int argc, char **argv) {
+    logArguments(argc, argv);
+
+    if (argc != 4) {
+        char* msg = nullptr;
+        asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc);
+        LOG(WARNING) << "GetHostByNameCmd::runCommand: " << (msg ? msg : "null");
+        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
+        free(msg);
+        return -1;
+    }
+
+    uid_t uid = cli->getUid();
+    unsigned netId = strtoul(argv[1], nullptr, 10);
+    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
+    char* name = argv[2];
+    int af = strtol(argv[3], nullptr, 10);
+
+    if (strcmp(name, "^") == 0) {
+        name = nullptr;
+    } else {
+        name = strdup(name);
+    }
+
+    android_net_context netcontext;
+    gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
+
+    if (useLocalNameservers) {
+        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
+    }
+
+    DnsProxyListener::GetHostByNameHandler* handler =
+            new DnsProxyListener::GetHostByNameHandler(cli, name, af, netcontext);
+    tryThreadOrError(cli, handler);
+    return 0;
+}
+
+DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, char* name, int af,
+                                                             const android_net_context& netcontext)
+    : mClient(c), mName(name), mAf(af), mNetContext(netcontext) {}
+
+DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() {
+    free(mName);
+}
+
+void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struct hostent** hpp,
+                                                              NetworkDnsEventReported* event) {
+    // Don't have to consider family AF_UNSPEC case because gethostbyname{, 2} only supports
+    // family AF_INET or AF_INET6.
+    const bool ipv6WantedButNoData = (mAf == AF_INET6 && *rv == EAI_NODATA);
+
+    if (!ipv6WantedButNoData) {
+        return;
+    }
+
+    netdutils::IPPrefix prefix{};
+    if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
+        return;
+    }
+
+    // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
+    const uid_t uid = mClient->getUid();
+    if (queryLimiter.start(uid)) {
+        *rv = android_gethostbynamefornetcontext(mName, AF_INET, &mNetContext, hpp, event);
+        queryLimiter.finish(uid);
+        if (*rv) {
+            *rv = EAI_NODATA;  // return original error code
+            return;
+        }
+    } else {
+        LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
+        return;
+    }
+
+    if (!synthesizeNat64PrefixWithARecord(prefix, *hpp)) {
+        // If caller wants IPv6 answers but no data and failed to synthesize IPv4 answers,
+        // don't return the IPv4 answers.
+        *hpp = nullptr;
+    }
+}
+
+void DnsProxyListener::GetHostByNameHandler::run() {
+    Stopwatch s;
+    maybeFixupNetContext(&mNetContext);
+    const uid_t uid = mClient->getUid();
+    hostent* hp = nullptr;
+    int32_t rv = 0;
+    NetworkDnsEventReported event;
+    initDnsEvent(&event);
+    if (queryLimiter.start(uid)) {
+        rv = android_gethostbynamefornetcontext(mName, mAf, &mNetContext, &hp, &event);
+        queryLimiter.finish(uid);
+    } else {
+        rv = EAI_MEMORY;
+        LOG(ERROR) << "GetHostByNameHandler::run: from UID " << uid
+                   << ", max concurrent queries reached";
+    }
+
+    doDns64Synthesis(&rv, &hp, &event);
+    const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
+    event.set_latency_micros(latencyUs);
+    event.set_event_type(EVENT_GETHOSTBYNAME);
+
+    LOG(DEBUG) << "GetHostByNameHandler::run: errno: " << (hp ? "success" : strerror(errno));
+
+    bool success = true;
+    if (hp) {
+        // hp is not nullptr iff. rv is 0.
+        success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
+        success &= sendhostent(mClient, hp);
+    } else {
+        success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
+    }
+
+    if (!success) {
+        LOG(WARNING) << "GetHostByNameHandler::run: Error writing DNS result to client";
+    }
+
+    std::vector<std::string> ip_addrs;
+    const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs);
+    reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event,
+                   mName, ip_addrs, total_ip_addr_count);
+    mClient->decRef();
+}
+
+
+/*******************************************************
+ *                  GetHostByAddr                      *
+ *******************************************************/
+DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd() : FrameworkCommand("gethostbyaddr") {}
+
+int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
+                                            int argc, char **argv) {
+    logArguments(argc, argv);
+
+    if (argc != 5) {
+        char* msg = nullptr;
+        asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc);
+        LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
+        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
+        free(msg);
+        return -1;
+    }
+
+    char* addrStr = argv[1];
+    int addrLen = strtol(argv[2], nullptr, 10);
+    int addrFamily = strtol(argv[3], nullptr, 10);
+    uid_t uid = cli->getUid();
+    unsigned netId = strtoul(argv[4], nullptr, 10);
+    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
+
+    void* addr = malloc(sizeof(in6_addr));
+    errno = 0;
+    int result = inet_pton(addrFamily, addrStr, addr);
+    if (result <= 0) {
+        char* msg = nullptr;
+        asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno));
+        LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
+        cli->sendMsg(ResponseCode::OperationFailed, msg, false);
+        free(addr);
+        free(msg);
+        return -1;
+    }
+
+    android_net_context netcontext;
+    gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
+
+    if (useLocalNameservers) {
+        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
+    }
+
+    DnsProxyListener::GetHostByAddrHandler* handler = new DnsProxyListener::GetHostByAddrHandler(
+            cli, addr, addrLen, addrFamily, netcontext);
+    tryThreadOrError(cli, handler);
+    return 0;
+}
+
+DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, void* address,
+                                                             int addressLen, int addressFamily,
+                                                             const android_net_context& netcontext)
+    : mClient(c),
+      mAddress(address),
+      mAddressLen(addressLen),
+      mAddressFamily(addressFamily),
+      mNetContext(netcontext) {}
+
+DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() {
+    free(mAddress);
+}
+
+void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent** hpp,
+                                                                  NetworkDnsEventReported* event) {
+    if (*hpp != nullptr || mAddressFamily != AF_INET6 || !mAddress) {
+        return;
+    }
+
+    netdutils::IPPrefix prefix{};
+    if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
+        return;
+    }
+
+    if (!isValidNat64Prefix(prefix)) {
+        return;
+    }
+
+    struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
+    struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
+    struct in6_addr v6addr = *(in6_addr*) mAddress;
+    // Check if address has NAT64 prefix. Only /96 IPv6 NAT64 prefixes are supported
+    if ((v6addr.s6_addr32[0] != v6prefix->sin6_addr.s6_addr32[0]) ||
+        (v6addr.s6_addr32[1] != v6prefix->sin6_addr.s6_addr32[1]) ||
+        (v6addr.s6_addr32[2] != v6prefix->sin6_addr.s6_addr32[2])) {
+        return;
+    }
+
+    const uid_t uid = mClient->getUid();
+    if (queryLimiter.start(uid)) {
+        // Remove NAT64 prefix and do reverse DNS query
+        struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]};
+        android_gethostbyaddrfornetcontext(&v4addr, sizeof(v4addr), AF_INET, &mNetContext, hpp,
+                                           event);
+        queryLimiter.finish(uid);
+        if (*hpp) {
+            // Replace IPv4 address with original queried IPv6 address in place. The space has
+            // reserved by dns_gethtbyaddr() and netbsd_gethostent_r() in
+            // system/netd/resolv/gethnamaddr.cpp.
+            // Note that android_gethostbyaddrfornetcontext returns only one entry in result.
+            memcpy((*hpp)->h_addr_list[0], &v6addr, sizeof(v6addr));
+            (*hpp)->h_addrtype = AF_INET6;
+            (*hpp)->h_length = sizeof(struct in6_addr);
+        }
+    } else {
+        LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
+    }
+}
+
+void DnsProxyListener::GetHostByAddrHandler::run() {
+    Stopwatch s;
+    maybeFixupNetContext(&mNetContext);
+    const uid_t uid = mClient->getUid();
+    hostent* hp = nullptr;
+    int32_t rv = 0;
+    NetworkDnsEventReported event;
+    initDnsEvent(&event);
+    if (queryLimiter.start(uid)) {
+        rv = android_gethostbyaddrfornetcontext(mAddress, mAddressLen, mAddressFamily, &mNetContext,
+                                                &hp, &event);
+        queryLimiter.finish(uid);
+    } else {
+        rv = EAI_MEMORY;
+        LOG(ERROR) << "GetHostByAddrHandler::run: from UID " << uid
+                   << ", max concurrent queries reached";
+    }
+
+    doDns64ReverseLookup(&hp, &event);
+    const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
+    event.set_latency_micros(latencyUs);
+    event.set_event_type(EVENT_GETHOSTBYADDR);
+
+    LOG(DEBUG) << "GetHostByAddrHandler::run: result: " << (hp ? "success" : gai_strerror(rv));
+
+    bool success = true;
+    if (hp) {
+        success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
+        success &= sendhostent(mClient, hp);
+    } else {
+        success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
+    }
+
+    if (!success) {
+        LOG(WARNING) << "GetHostByAddrHandler::run: Error writing DNS result to client";
+    }
+
+    reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event,
+                   (hp && hp->h_name) ? hp->h_name : "null", {}, 0);
+    mClient->decRef();
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/resolv/DnsProxyListener.h b/resolv/DnsProxyListener.h
new file mode 100644
index 0000000..9b71bc5
--- /dev/null
+++ b/resolv/DnsProxyListener.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <netd_resolv/resolv.h>  // android_net_context
+#include <sysutils/FrameworkCommand.h>
+#include <sysutils/FrameworkListener.h>
+
+struct addrinfo;
+struct hostent;
+
+namespace android {
+namespace net {
+
+class NetworkDnsEventReported;
+
+class DnsProxyListener : public FrameworkListener {
+  public:
+    DnsProxyListener();
+    virtual ~DnsProxyListener() {}
+
+    static constexpr const char* SOCKET_NAME = "dnsproxyd";
+
+  private:
+    class GetAddrInfoCmd : public FrameworkCommand {
+      public:
+        GetAddrInfoCmd();
+        virtual ~GetAddrInfoCmd() {}
+        int runCommand(SocketClient* c, int argc, char** argv) override;
+    };
+
+    /* ------ getaddrinfo ------*/
+    class GetAddrInfoHandler {
+      public:
+        // Note: All of host, service, and hints may be NULL
+        GetAddrInfoHandler(SocketClient* c, char* host, char* service, addrinfo* hints,
+                           const android_net_context& netcontext);
+        ~GetAddrInfoHandler();
+
+        void run();
+
+      private:
+        void doDns64Synthesis(int32_t* rv, addrinfo** res, NetworkDnsEventReported* event);
+
+        SocketClient* mClient;  // ref counted
+        char* mHost;            // owned. TODO: convert to std::string.
+        char* mService;         // owned. TODO: convert to std::string.
+        addrinfo* mHints;       // owned
+        android_net_context mNetContext;
+    };
+
+    /* ------ gethostbyname ------*/
+    class GetHostByNameCmd : public FrameworkCommand {
+      public:
+        GetHostByNameCmd();
+        virtual ~GetHostByNameCmd() {}
+        int runCommand(SocketClient* c, int argc, char** argv) override;
+    };
+
+    class GetHostByNameHandler {
+      public:
+        GetHostByNameHandler(SocketClient* c, char* name, int af,
+                             const android_net_context& netcontext);
+        ~GetHostByNameHandler();
+
+        void run();
+
+      private:
+        void doDns64Synthesis(int32_t* rv, hostent** hpp, NetworkDnsEventReported* event);
+
+        SocketClient* mClient;  // ref counted
+        char* mName;            // owned. TODO: convert to std::string.
+        int mAf;
+        android_net_context mNetContext;
+    };
+
+    /* ------ gethostbyaddr ------*/
+    class GetHostByAddrCmd : public FrameworkCommand {
+      public:
+        GetHostByAddrCmd();
+        virtual ~GetHostByAddrCmd() {}
+        int runCommand(SocketClient* c, int argc, char** argv) override;
+    };
+
+    class GetHostByAddrHandler {
+      public:
+        GetHostByAddrHandler(SocketClient* c, void* address, int addressLen, int addressFamily,
+                             const android_net_context& netcontext);
+        ~GetHostByAddrHandler();
+
+        void run();
+
+      private:
+        void doDns64ReverseLookup(hostent** hpp, NetworkDnsEventReported* event);
+
+        SocketClient* mClient;  // ref counted
+        void* mAddress;         // address to lookup; owned
+        int mAddressLen;        // length of address to look up
+        int mAddressFamily;     // address family
+        android_net_context mNetContext;
+    };
+
+    /* ------ resnsend ------*/
+    class ResNSendCommand : public FrameworkCommand {
+      public:
+        ResNSendCommand();
+        virtual ~ResNSendCommand() {}
+        int runCommand(SocketClient* c, int argc, char** argv) override;
+    };
+
+    class ResNSendHandler {
+      public:
+        ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
+                        const android_net_context& netcontext);
+        ~ResNSendHandler();
+
+        void run();
+
+      private:
+        SocketClient* mClient;  // ref counted
+        std::string mMsg;
+        uint32_t mFlags;
+        android_net_context mNetContext;
+    };
+
+    /* ------ getdnsnetid ------*/
+    class GetDnsNetIdCommand : public FrameworkCommand {
+      public:
+        GetDnsNetIdCommand();
+        virtual ~GetDnsNetIdCommand() {}
+        int runCommand(SocketClient* c, int argc, char** argv) override;
+    };
+};
+
+}  // namespace net
+}  // namespace android
diff --git a/resolv/DnsResolver.cpp b/resolv/DnsResolver.cpp
new file mode 100644
index 0000000..092ff3f
--- /dev/null
+++ b/resolv/DnsResolver.cpp
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DnsResolver.h"
+
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+
+#include "DnsProxyListener.h"
+#include "DnsResolverService.h"
+#include "netd_resolv/resolv.h"
+#include "res_debug.h"
+
+bool resolv_init(const ResolverNetdCallbacks* callbacks) {
+    android::base::InitLogging(/*argv=*/nullptr);
+    android::base::SetDefaultTag("libnetd_resolv");
+    LOG(INFO) << __func__ << ": Initializing resolver";
+    resolv_set_log_severity(android::base::WARNING);
+
+    android::net::gResNetdCallbacks = *callbacks;
+    android::net::gDnsResolv = android::net::DnsResolver::getInstance();
+    return android::net::gDnsResolv->start();
+}
+
+namespace android {
+namespace net {
+
+namespace {
+
+bool verifyCallbacks() {
+    return gResNetdCallbacks.check_calling_permission && gResNetdCallbacks.get_network_context &&
+           gResNetdCallbacks.log;
+}
+
+}  // namespace
+
+DnsResolver* gDnsResolv = nullptr;
+ResolverNetdCallbacks gResNetdCallbacks;
+netdutils::Log gDnsResolverLog("dnsResolver");
+
+DnsResolver* DnsResolver::getInstance() {
+    // Instantiated on first use.
+    static DnsResolver instance;
+    return &instance;
+}
+
+bool DnsResolver::start() {
+    if (!verifyCallbacks()) {
+        LOG(ERROR) << __func__ << ": Callback verification failed";
+        return false;
+    }
+    if (mDnsProxyListener.startListener()) {
+        PLOG(ERROR) << __func__ << ": Unable to start DnsProxyListener";
+        return false;
+    }
+    binder_status_t ret;
+    if ((ret = DnsResolverService::start()) != STATUS_OK) {
+        LOG(ERROR) << __func__ << ": Unable to start DnsResolverService: " << ret;
+        return false;
+    }
+    return true;
+}
+
+int DnsResolver::setLogSeverity(int32_t logSeverity) {
+    return resolv_set_log_severity(logSeverity);
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/resolv/DnsResolver.h b/resolv/DnsResolver.h
new file mode 100644
index 0000000..6d8d2ce
--- /dev/null
+++ b/resolv/DnsResolver.h
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_RESOLVER_H_
+#define _DNS_RESOLVER_H_
+
+#include "DnsProxyListener.h"
+#include "ResolverController.h"
+#include "netd_resolv/resolv.h"
+#include "netdutils/Log.h"
+
+namespace android {
+namespace net {
+
+class DnsResolver {
+  public:
+    static DnsResolver* getInstance();
+    bool start();
+    int setLogSeverity(int32_t logSeverity);
+
+    DnsResolver(DnsResolver const&) = delete;
+    void operator=(DnsResolver const&) = delete;
+
+    ResolverController resolverCtrl;
+
+  private:
+    DnsResolver() {}
+    DnsProxyListener mDnsProxyListener;
+};
+
+extern DnsResolver* gDnsResolv;
+extern ResolverNetdCallbacks gResNetdCallbacks;
+extern netdutils::Log gDnsResolverLog;
+
+}  // namespace net
+}  // namespace android
+
+#endif  // _DNS_RESOLVER_H_
diff --git a/resolv/DnsResolverService.cpp b/resolv/DnsResolverService.cpp
new file mode 100644
index 0000000..8eefd22
--- /dev/null
+++ b/resolv/DnsResolverService.cpp
@@ -0,0 +1,297 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DnsResolverService"
+
+#include "DnsResolverService.h"
+
+#include <set>
+#include <vector>
+
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <json/value.h>
+#include <json/writer.h>
+#include <log/log.h>
+#include <netdutils/DumpWriter.h>
+#include <openssl/base64.h>
+#include <private/android_filesystem_config.h>  // AID_SYSTEM
+
+#include "BinderUtil.h"
+#include "DnsResolver.h"
+#include "NetdConstants.h"    // SHA256_SIZE
+#include "NetdPermissions.h"  // PERM_*
+#include "ResolverEventReporter.h"
+#include "resolv_cache.h"
+
+using aidl::android::net::ResolverParamsParcel;
+using android::base::Join;
+using android::base::StringPrintf;
+using android::netdutils::DumpWriter;
+
+namespace android {
+namespace net {
+
+namespace {
+
+#define ENFORCE_ANY_PERMISSION(...)                                      \
+    do {                                                                 \
+        ::ndk::ScopedAStatus status = checkAnyPermission({__VA_ARGS__}); \
+        if (!status.isOk()) {                                            \
+            return status;                                               \
+        }                                                                \
+    } while (0)
+
+#define ENFORCE_INTERNAL_PERMISSIONS() \
+    ENFORCE_ANY_PERMISSION(PERM_CONNECTIVITY_INTERNAL, PERM_MAINLINE_NETWORK_STACK)
+
+#define ENFORCE_NETWORK_STACK_PERMISSIONS() \
+    ENFORCE_ANY_PERMISSION(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK)
+
+inline ::ndk::ScopedAStatus statusFromErrcode(int ret) {
+    if (ret) {
+        return ::ndk::ScopedAStatus(
+                AStatus_fromServiceSpecificErrorWithMessage(-ret, strerror(-ret)));
+    }
+    return ::ndk::ScopedAStatus(AStatus_newOk());
+}
+
+}  // namespace
+
+DnsResolverService::DnsResolverService() {
+    // register log callback to BnDnsResolver::logFunc
+    BnDnsResolver::logFunc =
+            std::bind(binderCallLogFn, std::placeholders::_1,
+                      [](const std::string& msg) { gResNetdCallbacks.log(msg.c_str()); });
+}
+
+binder_status_t DnsResolverService::start() {
+    // TODO: Add disableBackgroundScheduling(true) after libbinder_ndk support it. b/126506010
+    // NetdNativeService does call disableBackgroundScheduling currently, so it is fine now.
+    DnsResolverService* resolverService = new DnsResolverService();
+    binder_status_t status =
+            AServiceManager_addService(resolverService->asBinder().get(), getServiceName());
+    if (status != STATUS_OK) {
+        return status;
+    }
+
+    ABinderProcess_startThreadPool();
+
+    // TODO: register log callback if binder NDK backend support it. b/126501406
+
+    return STATUS_OK;
+}
+
+binder_status_t DnsResolverService::dump(int fd, const char**, uint32_t) {
+    auto dump_permission = checkAnyPermission({PERM_DUMP});
+    if (!dump_permission.isOk()) {
+        return STATUS_PERMISSION_DENIED;
+    }
+
+    // This method does not grab any locks. If individual classes need locking
+    // their dump() methods MUST handle locking appropriately.
+    DumpWriter dw(fd);
+    for (auto netId : resolv_list_caches()) {
+        dw.println("NetId: %u", netId);
+        gDnsResolv->resolverCtrl.dump(dw, netId);
+        dw.blankline();
+    }
+
+    return STATUS_OK;
+}
+
+::ndk::ScopedAStatus DnsResolverService::isAlive(bool* alive) {
+    ENFORCE_INTERNAL_PERMISSIONS();
+
+    *alive = true;
+
+    return ::ndk::ScopedAStatus(AStatus_newOk());
+}
+
+::ndk::ScopedAStatus DnsResolverService::registerEventListener(
+        const std::shared_ptr<aidl::android::net::metrics::INetdEventListener>& listener) {
+    ENFORCE_NETWORK_STACK_PERMISSIONS();
+
+    int res = ResolverEventReporter::getInstance().addListener(listener);
+
+    return statusFromErrcode(res);
+}
+
+::ndk::ScopedAStatus DnsResolverService::checkAnyPermission(
+        const std::vector<const char*>& permissions) {
+    // TODO: Remove callback and move this to unnamed namespace after libbiner_ndk supports
+    // check_permission.
+    if (!gResNetdCallbacks.check_calling_permission) {
+        return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
+                EX_NULL_POINTER, "check_calling_permission is null"));
+    }
+    pid_t pid = AIBinder_getCallingPid();
+    uid_t uid = AIBinder_getCallingUid();
+
+    // If the caller is the system UID, don't check permissions.
+    // Otherwise, if the system server's binder thread pool is full, and all the threads are
+    // blocked on a thread that's waiting for us to complete, we deadlock. http://b/69389492
+    //
+    // From a security perspective, there is currently no difference, because:
+    // 1. The only permissions we check in netd's binder interface are CONNECTIVITY_INTERNAL
+    //    and NETWORK_STACK, which the system server always has (or MAINLINE_NETWORK_STACK, which
+    //    is equivalent to having both CONNECTIVITY_INTERNAL and NETWORK_STACK).
+    // 2. AID_SYSTEM always has all permissions. See ActivityManager#checkComponentPermission.
+    if (uid == AID_SYSTEM) {
+        return ::ndk::ScopedAStatus(AStatus_newOk());
+    }
+
+    for (const char* permission : permissions) {
+        if (gResNetdCallbacks.check_calling_permission(permission)) {
+            return ::ndk::ScopedAStatus(AStatus_newOk());
+        }
+    }
+
+    auto err = StringPrintf("UID %d / PID %d does not have any of the following permissions: %s",
+                            uid, pid, Join(permissions, ',').c_str());
+    return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(EX_SECURITY, err.c_str()));
+}
+
+namespace {
+
+// Parse a base64 encoded string into a vector of bytes.
+// On failure, return an empty vector.
+static std::vector<uint8_t> parseBase64(const std::string& input) {
+    std::vector<uint8_t> decoded;
+    size_t out_len;
+    if (EVP_DecodedLength(&out_len, input.size()) != 1) {
+        return decoded;
+    }
+    // out_len is now an upper bound on the output length.
+    decoded.resize(out_len);
+    if (EVP_DecodeBase64(decoded.data(), &out_len, decoded.size(),
+                         reinterpret_cast<const uint8_t*>(input.data()), input.size()) == 1) {
+        // Possibly shrink the vector if the actual output was smaller than the bound.
+        decoded.resize(out_len);
+    } else {
+        decoded.clear();
+    }
+    if (out_len != SHA256_SIZE) {
+        decoded.clear();
+    }
+    return decoded;
+}
+
+}  // namespace
+
+::ndk::ScopedAStatus DnsResolverService::setResolverConfiguration(
+        const ResolverParamsParcel& resolverParams) {
+    // Locking happens in PrivateDnsConfiguration and res_* functions.
+    ENFORCE_INTERNAL_PERMISSIONS();
+    // TODO: Remove this log after AIDL gen_log supporting more types, b/129732660
+    auto entry =
+            gDnsResolverLog.newEntry()
+                    .prettyFunction(__PRETTY_FUNCTION__)
+                    .args(resolverParams.netId, resolverParams.servers, resolverParams.domains,
+                          resolverParams.sampleValiditySeconds, resolverParams.successThreshold,
+                          resolverParams.minSamples, resolverParams.maxSamples,
+                          resolverParams.baseTimeoutMsec, resolverParams.retryCount,
+                          resolverParams.tlsServers, resolverParams.tlsFingerprints);
+
+    std::set<std::vector<uint8_t>> decoded_fingerprints;
+    for (const std::string& fingerprint : resolverParams.tlsFingerprints) {
+        std::vector<uint8_t> decoded = parseBase64(fingerprint);
+        if (decoded.empty()) {
+            return ::ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    EINVAL, "ResolverController error: bad fingerprint"));
+        }
+        decoded_fingerprints.emplace(decoded);
+    }
+
+    int res =
+            gDnsResolv->resolverCtrl.setResolverConfiguration(resolverParams, decoded_fingerprints);
+
+    gResNetdCallbacks.log(entry.returns(res).withAutomaticDuration().toString().c_str());
+
+    return statusFromErrcode(res);
+}
+
+::ndk::ScopedAStatus DnsResolverService::getResolverInfo(
+        int32_t netId, std::vector<std::string>* servers, std::vector<std::string>* domains,
+        std::vector<std::string>* tlsServers, std::vector<int32_t>* params,
+        std::vector<int32_t>* stats, std::vector<int32_t>* wait_for_pending_req_timeout_count) {
+    // Locking happens in PrivateDnsConfiguration and res_* functions.
+    ENFORCE_NETWORK_STACK_PERMISSIONS();
+
+    int res = gDnsResolv->resolverCtrl.getResolverInfo(netId, servers, domains, tlsServers, params,
+                                                       stats, wait_for_pending_req_timeout_count);
+
+    return statusFromErrcode(res);
+}
+
+::ndk::ScopedAStatus DnsResolverService::startPrefix64Discovery(int32_t netId) {
+    // Locking happens in Dns64Configuration.
+    ENFORCE_NETWORK_STACK_PERMISSIONS();
+
+    gDnsResolv->resolverCtrl.startPrefix64Discovery(netId);
+
+    return ::ndk::ScopedAStatus(AStatus_newOk());
+}
+
+::ndk::ScopedAStatus DnsResolverService::stopPrefix64Discovery(int32_t netId) {
+    // Locking happens in Dns64Configuration.
+    ENFORCE_NETWORK_STACK_PERMISSIONS();
+
+    gDnsResolv->resolverCtrl.stopPrefix64Discovery(netId);
+
+    return ::ndk::ScopedAStatus(AStatus_newOk());
+}
+
+::ndk::ScopedAStatus DnsResolverService::getPrefix64(int netId, std::string* stringPrefix) {
+    ENFORCE_NETWORK_STACK_PERMISSIONS();
+
+    netdutils::IPPrefix prefix{};
+    int res = gDnsResolv->resolverCtrl.getPrefix64(netId, &prefix);
+    *stringPrefix = prefix.toString();
+
+    return statusFromErrcode(res);
+}
+
+::ndk::ScopedAStatus DnsResolverService::setLogSeverity(int32_t logSeverity) {
+    ENFORCE_NETWORK_STACK_PERMISSIONS();
+
+    int res = gDnsResolv->setLogSeverity(logSeverity);
+
+    return statusFromErrcode(res);
+}
+
+::ndk::ScopedAStatus DnsResolverService::destroyNetworkCache(int netId) {
+    // Locking happens in res_cache.cpp functions.
+    ENFORCE_NETWORK_STACK_PERMISSIONS();
+
+    gDnsResolv->resolverCtrl.destroyNetworkCache(netId);
+
+    return ::ndk::ScopedAStatus(AStatus_newOk());
+}
+
+::ndk::ScopedAStatus DnsResolverService::createNetworkCache(int netId) {
+    // Locking happens in res_cache.cpp functions.
+    ENFORCE_NETWORK_STACK_PERMISSIONS();
+
+    int res = gDnsResolv->resolverCtrl.createNetworkCache(netId);
+
+    return statusFromErrcode(res);
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/resolv/DnsResolverService.h b/resolv/DnsResolverService.h
new file mode 100644
index 0000000..1a1c9e7
--- /dev/null
+++ b/resolv/DnsResolverService.h
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_RESOLVER_SERVICE_H_
+#define _DNS_RESOLVER_SERVICE_H_
+
+#include <vector>
+
+#include <aidl/android/net/BnDnsResolver.h>
+#include <aidl/android/net/ResolverParamsParcel.h>
+#include <android/binder_ibinder.h>
+
+#include "netd_resolv/resolv.h"
+
+namespace android {
+namespace net {
+
+class DnsResolverService : public aidl::android::net::BnDnsResolver {
+  public:
+    static binder_status_t start();
+    static char const* getServiceName() { return "dnsresolver"; }
+
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+    ::ndk::ScopedAStatus isAlive(bool* alive) override;
+    ::ndk::ScopedAStatus registerEventListener(
+            const std::shared_ptr<aidl::android::net::metrics::INetdEventListener>& listener)
+            override;
+
+    // Resolver commands.
+    ::ndk::ScopedAStatus setResolverConfiguration(
+            const aidl::android::net::ResolverParamsParcel& resolverParams) override;
+    ::ndk::ScopedAStatus getResolverInfo(
+            int32_t netId, std::vector<std::string>* servers, std::vector<std::string>* domains,
+            std::vector<std::string>* tlsServers, std::vector<int32_t>* params,
+            std::vector<int32_t>* stats,
+            std::vector<int32_t>* wait_for_pending_req_timeout_count) override;
+    ::ndk::ScopedAStatus destroyNetworkCache(int32_t netId) override;
+    ::ndk::ScopedAStatus createNetworkCache(int32_t netId) override;
+
+    // DNS64-related commands
+    ::ndk::ScopedAStatus startPrefix64Discovery(int32_t netId) override;
+    ::ndk::ScopedAStatus stopPrefix64Discovery(int32_t netId) override;
+    // (internal use only)
+    ::ndk::ScopedAStatus getPrefix64(int netId, std::string* stringPrefix) override;
+
+    // Debug log command
+    ::ndk::ScopedAStatus setLogSeverity(int32_t logSeverity) override;
+
+  private:
+    DnsResolverService();
+    // TODO: Remove below items after libbiner_ndk supports check_permission.
+    ::ndk::ScopedAStatus checkAnyPermission(const std::vector<const char*>& permissions);
+};
+
+}  // namespace net
+}  // namespace android
+
+#endif  // _DNS_RESOLVER_SERVICE_H_
diff --git a/resolv/DnsTlsDispatcher.cpp b/resolv/DnsTlsDispatcher.cpp
new file mode 100644
index 0000000..baafa53
--- /dev/null
+++ b/resolv/DnsTlsDispatcher.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DnsTlsDispatcher"
+//#define LOG_NDEBUG 0
+
+#include "DnsTlsDispatcher.h"
+#include <netdutils/Stopwatch.h>
+#include "DnsTlsSocketFactory.h"
+#include "resolv_private.h"
+#include "stats.pb.h"
+
+#include "log/log.h"
+
+namespace android {
+namespace net {
+
+using android::netdutils::Stopwatch;
+using netdutils::Slice;
+
+// static
+std::mutex DnsTlsDispatcher::sLock;
+
+DnsTlsDispatcher::DnsTlsDispatcher() {
+    mFactory.reset(new DnsTlsSocketFactory());
+}
+
+std::list<DnsTlsServer> DnsTlsDispatcher::getOrderedServerList(
+        const std::list<DnsTlsServer> &tlsServers, unsigned mark) const {
+    // Our preferred DnsTlsServer order is:
+    //     1) reuse existing IPv6 connections
+    //     2) reuse existing IPv4 connections
+    //     3) establish new IPv6 connections
+    //     4) establish new IPv4 connections
+    std::list<DnsTlsServer> existing6;
+    std::list<DnsTlsServer> existing4;
+    std::list<DnsTlsServer> new6;
+    std::list<DnsTlsServer> new4;
+
+    // Pull out any servers for which we might have existing connections and
+    // place them at the from the list of servers to try.
+    {
+        std::lock_guard guard(sLock);
+
+        for (const auto& tlsServer : tlsServers) {
+            const Key key = std::make_pair(mark, tlsServer);
+            if (mStore.find(key) != mStore.end()) {
+                switch (tlsServer.ss.ss_family) {
+                    case AF_INET:
+                        existing4.push_back(tlsServer);
+                        break;
+                    case AF_INET6:
+                        existing6.push_back(tlsServer);
+                        break;
+                }
+            } else {
+                switch (tlsServer.ss.ss_family) {
+                    case AF_INET:
+                        new4.push_back(tlsServer);
+                        break;
+                    case AF_INET6:
+                        new6.push_back(tlsServer);
+                        break;
+                }
+            }
+        }
+    }
+
+    auto& out = existing6;
+    out.splice(out.cend(), existing4);
+    out.splice(out.cend(), new6);
+    out.splice(out.cend(), new4);
+    return out;
+}
+
+DnsTlsTransport::Response DnsTlsDispatcher::query(const std::list<DnsTlsServer>& tlsServers,
+                                                  res_state statp, const Slice query,
+                                                  const Slice ans, int* resplen) {
+    const std::list<DnsTlsServer> orderedServers(getOrderedServerList(tlsServers, statp->_mark));
+
+    if (orderedServers.empty()) ALOGW("Empty DnsTlsServer list");
+
+    DnsTlsTransport::Response code = DnsTlsTransport::Response::internal_error;
+    int serverCount = 0;
+    for (const auto& server : orderedServers) {
+        DnsQueryEvent* dnsQueryEvent =
+                statp->event->mutable_dns_query_events()->add_dns_query_event();
+        dnsQueryEvent->set_rcode(NS_R_INTERNAL_ERROR);
+        Stopwatch query_stopwatch;
+        code = this->query(server, statp->_mark, query, ans, resplen);
+
+        dnsQueryEvent->set_latency_micros(saturate_cast<int32_t>(query_stopwatch.timeTakenUs()));
+        dnsQueryEvent->set_dns_server_index(serverCount++);
+        dnsQueryEvent->set_ip_version(ipFamilyToIPVersion(server.ss.ss_family));
+        dnsQueryEvent->set_protocol(PROTO_DOT);
+        dnsQueryEvent->set_type(getQueryType(query.base(), query.size()));
+
+        switch (code) {
+            // These response codes are valid responses and not expected to
+            // change if another server is queried.
+            case DnsTlsTransport::Response::success:
+                dnsQueryEvent->set_rcode(
+                        static_cast<NsRcode>(reinterpret_cast<HEADER*>(ans.base())->rcode));
+                [[fallthrough]];
+            case DnsTlsTransport::Response::limit_error:
+                return code;
+            // These response codes might differ when trying other servers, so
+            // keep iterating to see if we can get a different (better) result.
+            case DnsTlsTransport::Response::network_error:
+                // Sync from res_tls_send in res_send.cpp
+                dnsQueryEvent->set_rcode(NS_R_TIMEOUT);
+                [[fallthrough]];
+            case DnsTlsTransport::Response::internal_error:
+                continue;
+            // No "default" statement.
+        }
+    }
+
+    return code;
+}
+
+DnsTlsTransport::Response DnsTlsDispatcher::query(const DnsTlsServer& server, unsigned mark,
+                                                  const Slice query,
+                                                  const Slice ans, int *resplen) {
+    const Key key = std::make_pair(mark, server);
+    Transport* xport;
+    {
+        std::lock_guard guard(sLock);
+        auto it = mStore.find(key);
+        if (it == mStore.end()) {
+            xport = new Transport(server, mark, mFactory.get());
+            mStore[key].reset(xport);
+        } else {
+            xport = it->second.get();
+        }
+        ++xport->useCount;
+    }
+
+    ALOGV("Sending query of length %zu", query.size());
+    auto res = xport->transport.query(query);
+    ALOGV("Awaiting response");
+    const auto& result = res.get();
+    DnsTlsTransport::Response code = result.code;
+    if (code == DnsTlsTransport::Response::success) {
+        if (result.response.size() > ans.size()) {
+            ALOGV("Response too large: %zu > %zu", result.response.size(), ans.size());
+            code = DnsTlsTransport::Response::limit_error;
+        } else {
+            ALOGV("Got response successfully");
+            *resplen = result.response.size();
+            netdutils::copy(ans, netdutils::makeSlice(result.response));
+        }
+    } else {
+        ALOGV("Query failed: %u", (unsigned int) code);
+    }
+
+    auto now = std::chrono::steady_clock::now();
+    {
+        std::lock_guard guard(sLock);
+        --xport->useCount;
+        xport->lastUsed = now;
+        cleanup(now);
+    }
+    return code;
+}
+
+// This timeout effectively controls how long to keep SSL session tickets.
+static constexpr std::chrono::minutes IDLE_TIMEOUT(5);
+void DnsTlsDispatcher::cleanup(std::chrono::time_point<std::chrono::steady_clock> now) {
+    // To avoid scanning mStore after every query, return early if a cleanup has been
+    // performed recently.
+    if (now - mLastCleanup < IDLE_TIMEOUT) {
+        return;
+    }
+    for (auto it = mStore.begin(); it != mStore.end();) {
+        auto& s = it->second;
+        if (s->useCount == 0 && now - s->lastUsed > IDLE_TIMEOUT) {
+            it = mStore.erase(it);
+        } else {
+            ++it;
+        }
+    }
+    mLastCleanup = now;
+}
+
+}  // end of namespace net
+}  // end of namespace android
diff --git a/resolv/DnsTlsDispatcher.h b/resolv/DnsTlsDispatcher.h
new file mode 100644
index 0000000..b8e9968
--- /dev/null
+++ b/resolv/DnsTlsDispatcher.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_DNSTLSDISPATCHER_H
+#define _DNS_DNSTLSDISPATCHER_H
+
+#include <list>
+#include <map>
+#include <memory>
+#include <mutex>
+
+#include <android-base/thread_annotations.h>
+#include <netdutils/Slice.h>
+
+#include "DnsTlsServer.h"
+#include "DnsTlsTransport.h"
+#include "IDnsTlsSocketFactory.h"
+#include "resolv_private.h"
+
+namespace android {
+namespace net {
+
+// This is a singleton class that manages the collection of active DnsTlsTransports.
+// Queries made here are dispatched to an existing or newly constructed DnsTlsTransport.
+class DnsTlsDispatcher {
+  public:
+    // Default constructor.
+    DnsTlsDispatcher();
+
+    // Constructor with dependency injection for testing.
+    explicit DnsTlsDispatcher(std::unique_ptr<IDnsTlsSocketFactory> factory)
+        : mFactory(std::move(factory)) {}
+
+    // Enqueues |query| for resolution via the given |tlsServers| on the
+    // network indicated by |mark|; writes the response into |ans|, and stores
+    // the count of bytes written in |resplen|. Returns a success or error code.
+    // The order in which servers from |tlsServers| are queried may not be the
+    // order passed in by the caller.
+    DnsTlsTransport::Response query(const std::list<DnsTlsServer>& tlsServers,
+                                    res_state _Nonnull statp, const netdutils::Slice query,
+                                    const netdutils::Slice ans, int* _Nonnull resplen);
+
+    // Given a |query|, sends it to the server on the network indicated by |mark|,
+    // and writes the response into |ans|,  and indicates
+    // the number of bytes written in |resplen|.  Returns a success or error code.
+    DnsTlsTransport::Response query(const DnsTlsServer& server, unsigned mark,
+                                    const netdutils::Slice query, const netdutils::Slice ans,
+                                    int* _Nonnull resplen);
+
+  private:
+    // This lock is static so that it can be used to annotate the Transport struct.
+    // DnsTlsDispatcher is a singleton in practice, so making this static does not change
+    // the locking behavior.
+    static std::mutex sLock;
+
+    // Key = <mark, server>
+    typedef std::pair<unsigned, const DnsTlsServer> Key;
+
+    // Transport is a thin wrapper around DnsTlsTransport, adding reference counting and
+    // usage monitoring so we can expire idle sessions from the cache.
+    struct Transport {
+        Transport(const DnsTlsServer& server, unsigned mark, IDnsTlsSocketFactory* _Nonnull factory)
+            : transport(server, mark, factory) {}
+        // DnsTlsTransport is thread-safe, so it doesn't need to be guarded.
+        DnsTlsTransport transport;
+        // This use counter and timestamp are used to ensure that only idle sessions are
+        // destroyed.
+        int useCount GUARDED_BY(sLock) = 0;
+        // lastUsed is only guaranteed to be meaningful after useCount is decremented to zero.
+        std::chrono::time_point<std::chrono::steady_clock> lastUsed GUARDED_BY(sLock);
+    };
+
+    // Cache of reusable DnsTlsTransports.  Transports stay in cache as long as
+    // they are in use and for a few minutes after.
+    // The key is a (netid, server) pair.  The netid is first for lexicographic comparison speed.
+    std::map<Key, std::unique_ptr<Transport>> mStore GUARDED_BY(sLock);
+
+    // The last time we did a cleanup.  For efficiency, we only perform a cleanup once every
+    // few minutes.
+    std::chrono::time_point<std::chrono::steady_clock> mLastCleanup GUARDED_BY(sLock);
+
+    // Drop any cache entries whose useCount is zero and which have not been used recently.
+    // This function performs a linear scan of mStore.
+    void cleanup(std::chrono::time_point<std::chrono::steady_clock> now) REQUIRES(sLock);
+
+    // Return a sorted list of DnsTlsServers in preference order.
+    std::list<DnsTlsServer> getOrderedServerList(const std::list<DnsTlsServer>& tlsServers,
+                                                 unsigned mark) const;
+
+    // Trivial factory for DnsTlsSockets.  Dependency injection is only used for testing.
+    std::unique_ptr<IDnsTlsSocketFactory> mFactory;
+};
+
+}  // end of namespace net
+}  // end of namespace android
+
+#endif  // _DNS_DNSTLSDISPATCHER_H
diff --git a/resolv/DnsTlsQueryMap.cpp b/resolv/DnsTlsQueryMap.cpp
new file mode 100644
index 0000000..6e6399c
--- /dev/null
+++ b/resolv/DnsTlsQueryMap.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DnsTlsQueryMap"
+//#define LOG_NDEBUG 0
+
+#include "DnsTlsQueryMap.h"
+
+#include "log/log.h"
+
+namespace android {
+namespace net {
+
+std::unique_ptr<DnsTlsQueryMap::QueryFuture> DnsTlsQueryMap::recordQuery(
+        const netdutils::Slice query) {
+    std::lock_guard guard(mLock);
+
+    // Store the query so it can be matched to the response or reissued.
+    if (query.size() < 2) {
+        ALOGW("Query is too short");
+        return nullptr;
+    }
+    int32_t newId = getFreeId();
+    if (newId < 0) {
+        ALOGW("All query IDs are in use");
+        return nullptr;
+    }
+    Query q = { .newId = static_cast<uint16_t>(newId), .query = query };
+    std::map<uint16_t, QueryPromise>::iterator it;
+    bool inserted;
+    std::tie(it, inserted) = mQueries.emplace(newId, q);
+    if (!inserted) {
+        ALOGE("Failed to store pending query");
+        return nullptr;
+    }
+    return std::make_unique<QueryFuture>(q, it->second.result.get_future());
+}
+
+void DnsTlsQueryMap::expire(QueryPromise* p) {
+    Result r = { .code = Response::network_error };
+    p->result.set_value(r);
+}
+
+void DnsTlsQueryMap::markTried(uint16_t newId) {
+    std::lock_guard guard(mLock);
+    auto it = mQueries.find(newId);
+    if (it != mQueries.end()) {
+        it->second.tries++;
+    }
+}
+
+void DnsTlsQueryMap::cleanup() {
+    std::lock_guard guard(mLock);
+    for (auto it = mQueries.begin(); it != mQueries.end();) {
+        auto& p = it->second;
+        if (p.tries >= kMaxTries) {
+            expire(&p);
+            it = mQueries.erase(it);
+        } else {
+            ++it;
+        }
+    }
+}
+
+int32_t DnsTlsQueryMap::getFreeId() {
+    if (mQueries.empty()) {
+        return 0;
+    }
+    uint16_t maxId = mQueries.rbegin()->first;
+    if (maxId < UINT16_MAX) {
+        return maxId + 1;
+    }
+    if (mQueries.size() == UINT16_MAX + 1) {
+        // Map is full.
+        return -1;
+    }
+    // Linear scan.
+    uint16_t nextId = 0;
+    for (auto& pair : mQueries) {
+        uint16_t id = pair.first;
+        if (id != nextId) {
+            // Found a gap.
+            return nextId;
+        }
+        nextId = id + 1;
+    }
+    // Unreachable (but the compiler isn't smart enough to prove it).
+    return -1;
+}
+
+std::vector<DnsTlsQueryMap::Query> DnsTlsQueryMap::getAll() {
+    std::lock_guard guard(mLock);
+    std::vector<DnsTlsQueryMap::Query> queries;
+    for (auto& q : mQueries) {
+        queries.push_back(q.second.query);
+    }
+    return queries;
+}
+
+bool DnsTlsQueryMap::empty() {
+    std::lock_guard guard(mLock);
+    return mQueries.empty();
+}
+
+void DnsTlsQueryMap::clear() {
+    std::lock_guard guard(mLock);
+    for (auto& q : mQueries) {
+        expire(&q.second);
+    }
+    mQueries.clear();
+}
+
+void DnsTlsQueryMap::onResponse(std::vector<uint8_t> response) {
+    ALOGV("Got response of size %zu", response.size());
+    if (response.size() < 2) {
+        ALOGW("Response is too short");
+        return;
+    }
+    uint16_t id = response[0] << 8 | response[1];
+    std::lock_guard guard(mLock);
+    auto it = mQueries.find(id);
+    if (it == mQueries.end()) {
+        ALOGW("Discarding response: unknown ID %d", id);
+        return;
+    }
+    Result r = { .code = Response::success, .response = std::move(response) };
+    // Rewrite ID to match the query
+    const uint8_t* data = it->second.query.query.base();
+    r.response[0] = data[0];
+    r.response[1] = data[1];
+    ALOGV("Sending result to dispatcher");
+    it->second.result.set_value(std::move(r));
+    mQueries.erase(it);
+}
+
+}  // end of namespace net
+}  // end of namespace android
diff --git a/resolv/DnsTlsQueryMap.h b/resolv/DnsTlsQueryMap.h
new file mode 100644
index 0000000..c5ab023
--- /dev/null
+++ b/resolv/DnsTlsQueryMap.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_DNSTLSQUERYMAP_H
+#define _DNS_DNSTLSQUERYMAP_H
+
+#include <future>
+#include <map>
+#include <mutex>
+#include <vector>
+
+#include <android-base/thread_annotations.h>
+#include <netdutils/Slice.h>
+
+#include "DnsTlsServer.h"
+
+namespace android {
+namespace net {
+
+// Keeps track of queries and responses.  This class matches responses with queries.
+// All methods are thread-safe and non-blocking.
+class DnsTlsQueryMap {
+  public:
+    struct Query {
+        // The new ID number assigned to this query.
+        uint16_t newId;
+        // A query that has been passed to recordQuery(), with its original ID number.
+        const netdutils::Slice query;
+    };
+
+    typedef DnsTlsServer::Response Response;
+    typedef DnsTlsServer::Result Result;
+
+    struct QueryFuture {
+        QueryFuture(Query query, std::future<Result> result)
+            : query(query), result(std::move(result)) {}
+        Query query;
+        // A future which will resolve to the result of this query.
+        std::future<Result> result;
+    };
+
+    // Returns an object containing everything needed to complete processing of
+    // this query, or null if the query could not be recorded.
+    std::unique_ptr<QueryFuture> recordQuery(const netdutils::Slice query);
+
+    // Process a response, including a new ID.  If the response
+    // is not recognized as matching any query, it will be ignored.
+    void onResponse(std::vector<uint8_t> response);
+
+    // Clear all map contents.  This causes all pending queries to resolve with failure.
+    void clear();
+
+    // Get all pending queries.  This returns a shallow copy, mostly for thread-safety.
+    std::vector<Query> getAll();
+
+    // Mark a query has having been retried.  If the query hits the retry limit, it will
+    // be expired at the next call to cleanup.
+    void markTried(uint16_t newId);
+    void cleanup();
+
+    // Returns true if there are no pending queries.
+    bool empty();
+
+  private:
+    std::mutex mLock;
+
+    struct QueryPromise {
+        QueryPromise(Query query) : query(query) {}
+        Query query;
+        // Number of times the query has been tried.  Limited to kMaxTries.
+        int tries = 0;
+        // A promise whose future is returned by recordQuery()
+        // It is fulfilled by onResponse().
+        std::promise<Result> result;
+    };
+
+    // The maximum number of times we will send a query before abandoning it.
+    static constexpr int kMaxTries = 3;
+
+    // Outstanding queries by newId.
+    std::map<uint16_t, QueryPromise> mQueries GUARDED_BY(mLock);
+
+    // Get a "newId" number that is not currently in use.  Returns -1 if there are none.
+    int32_t getFreeId() REQUIRES(mLock);
+
+    // Fulfill the result with an error code.
+    static void expire(QueryPromise* _Nonnull p);
+};
+
+}  // end of namespace net
+}  // end of namespace android
+
+#endif  // _DNS_DNSTLSQUERYMAP_H
diff --git a/resolv/DnsTlsServer.cpp b/resolv/DnsTlsServer.cpp
new file mode 100644
index 0000000..a97c672
--- /dev/null
+++ b/resolv/DnsTlsServer.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DnsTlsServer.h"
+
+#include <algorithm>
+
+namespace {
+
+// Returns a tuple of references to the elements of a.
+auto make_tie(const sockaddr_in& a) {
+    return std::tie(a.sin_port, a.sin_addr.s_addr);
+}
+
+// Returns a tuple of references to the elements of a.
+auto make_tie(const sockaddr_in6& a) {
+    // Skip flowinfo, which is not relevant.
+    return std::tie(
+        a.sin6_port,
+        a.sin6_addr,
+        a.sin6_scope_id
+    );
+}
+
+} // namespace
+
+// These binary operators make sockaddr_storage comparable.  They need to be
+// in the global namespace so that the std::tuple < and == operators can see them.
+static bool operator <(const in6_addr& x, const in6_addr& y) {
+    return std::lexicographical_compare(
+            std::begin(x.s6_addr), std::end(x.s6_addr),
+            std::begin(y.s6_addr), std::end(y.s6_addr));
+}
+
+static bool operator ==(const in6_addr& x, const in6_addr& y) {
+    return std::equal(
+            std::begin(x.s6_addr), std::end(x.s6_addr),
+            std::begin(y.s6_addr), std::end(y.s6_addr));
+}
+
+static bool operator <(const sockaddr_storage& x, const sockaddr_storage& y) {
+    if (x.ss_family != y.ss_family) {
+        return x.ss_family < y.ss_family;
+    }
+    // Same address family.
+    if (x.ss_family == AF_INET) {
+        const sockaddr_in& x_sin = reinterpret_cast<const sockaddr_in&>(x);
+        const sockaddr_in& y_sin = reinterpret_cast<const sockaddr_in&>(y);
+        return make_tie(x_sin) < make_tie(y_sin);
+    } else if (x.ss_family == AF_INET6) {
+        const sockaddr_in6& x_sin6 = reinterpret_cast<const sockaddr_in6&>(x);
+        const sockaddr_in6& y_sin6 = reinterpret_cast<const sockaddr_in6&>(y);
+        return make_tie(x_sin6) < make_tie(y_sin6);
+    }
+    return false;  // Unknown address type.  This is an error.
+}
+
+static bool operator ==(const sockaddr_storage& x, const sockaddr_storage& y) {
+    if (x.ss_family != y.ss_family) {
+        return false;
+    }
+    // Same address family.
+    if (x.ss_family == AF_INET) {
+        const sockaddr_in& x_sin = reinterpret_cast<const sockaddr_in&>(x);
+        const sockaddr_in& y_sin = reinterpret_cast<const sockaddr_in&>(y);
+        return make_tie(x_sin) == make_tie(y_sin);
+    } else if (x.ss_family == AF_INET6) {
+        const sockaddr_in6& x_sin6 = reinterpret_cast<const sockaddr_in6&>(x);
+        const sockaddr_in6& y_sin6 = reinterpret_cast<const sockaddr_in6&>(y);
+        return make_tie(x_sin6) == make_tie(y_sin6);
+    }
+    return false;  // Unknown address type.  This is an error.
+}
+
+namespace android {
+namespace net {
+
+// This comparison ignores ports and fingerprints.
+bool AddressComparator::operator() (const DnsTlsServer& x, const DnsTlsServer& y) const {
+    if (x.ss.ss_family != y.ss.ss_family) {
+        return x.ss.ss_family < y.ss.ss_family;
+    }
+    // Same address family.
+    if (x.ss.ss_family == AF_INET) {
+        const sockaddr_in& x_sin = reinterpret_cast<const sockaddr_in&>(x.ss);
+        const sockaddr_in& y_sin = reinterpret_cast<const sockaddr_in&>(y.ss);
+        return x_sin.sin_addr.s_addr < y_sin.sin_addr.s_addr;
+    } else if (x.ss.ss_family == AF_INET6) {
+        const sockaddr_in6& x_sin6 = reinterpret_cast<const sockaddr_in6&>(x.ss);
+        const sockaddr_in6& y_sin6 = reinterpret_cast<const sockaddr_in6&>(y.ss);
+        return std::tie(x_sin6.sin6_addr, x_sin6.sin6_scope_id) <
+                std::tie(y_sin6.sin6_addr, y_sin6.sin6_scope_id);
+    }
+    return false;  // Unknown address type.  This is an error.
+}
+
+// Returns a tuple of references to the elements of s.
+auto make_tie(const DnsTlsServer& s) {
+    return std::tie(
+        s.ss,
+        s.name,
+        s.fingerprints,
+        s.protocol
+    );
+}
+
+bool DnsTlsServer::operator <(const DnsTlsServer& other) const {
+    return make_tie(*this) < make_tie(other);
+}
+
+bool DnsTlsServer::operator ==(const DnsTlsServer& other) const {
+    return make_tie(*this) == make_tie(other);
+}
+
+bool DnsTlsServer::wasExplicitlyConfigured() const {
+    return !name.empty() || !fingerprints.empty();
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/resolv/DnsTlsServer.h b/resolv/DnsTlsServer.h
new file mode 100644
index 0000000..7fc4a35
--- /dev/null
+++ b/resolv/DnsTlsServer.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_DNSTLSSERVER_H
+#define _DNS_DNSTLSSERVER_H
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include <netinet/in.h>
+
+#include <netd_resolv/params.h>
+
+namespace android {
+namespace net {
+
+// DnsTlsServer represents a recursive resolver that supports, or may support, a
+// secure protocol.
+struct DnsTlsServer {
+    // Default constructor.
+    DnsTlsServer() {}
+
+    // Allow sockaddr_storage to be promoted to DnsTlsServer automatically.
+    DnsTlsServer(const sockaddr_storage& ss) : ss(ss) {}
+
+    enum class Response : uint8_t { success, network_error, limit_error, internal_error };
+
+    struct Result {
+        Response code;
+        std::vector<uint8_t> response;
+    };
+
+    // The server location, including IP and port.
+    sockaddr_storage ss = {};
+
+    // A set of SHA256 public key fingerprints.  If this set is nonempty, the server
+    // must present a self-consistent certificate chain that contains a certificate
+    // whose public key matches one of these fingerprints.  Otherwise, the client will
+    // terminate the connection.
+    std::set<std::vector<uint8_t>> fingerprints;
+
+    // The server's hostname.  If this string is nonempty, the server must present a
+    // certificate that indicates this name and has a valid chain to a trusted root CA.
+    std::string name;
+
+    // Placeholder.  More protocols might be defined in the future.
+    int protocol = IPPROTO_TCP;
+
+    // Exact comparison of DnsTlsServer objects
+    bool operator<(const DnsTlsServer& other) const;
+    bool operator==(const DnsTlsServer& other) const;
+
+    bool wasExplicitlyConfigured() const;
+};
+
+// This comparison only checks the IP address.  It ignores ports, names, and fingerprints.
+struct AddressComparator {
+    bool operator()(const DnsTlsServer& x, const DnsTlsServer& y) const;
+};
+
+}  // namespace net
+}  // namespace android
+
+#endif  // _DNS_DNSTLSSERVER_H
diff --git a/resolv/DnsTlsSessionCache.cpp b/resolv/DnsTlsSessionCache.cpp
new file mode 100644
index 0000000..8d6dc6b
--- /dev/null
+++ b/resolv/DnsTlsSessionCache.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DnsTlsSessionCache.h"
+
+#define LOG_TAG "DnsTlsSessionCache"
+//#define LOG_NDEBUG 0
+
+#include "log/log.h"
+
+namespace android {
+namespace net {
+
+bool DnsTlsSessionCache::prepareSsl(SSL* ssl) {
+    // Add this cache as the 0-index extra data for the socket.
+    // This is used by newSessionCallback.
+    int ret = SSL_set_ex_data(ssl, 0, this);
+    return ret == 1;
+}
+
+void DnsTlsSessionCache::prepareSslContext(SSL_CTX* ssl_ctx) {
+    SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_CLIENT);
+    SSL_CTX_sess_set_new_cb(ssl_ctx, &DnsTlsSessionCache::newSessionCallback);
+}
+
+// static
+int DnsTlsSessionCache::newSessionCallback(SSL* ssl, SSL_SESSION* session) {
+    if (!ssl || !session) {
+        ALOGE("Null SSL object in new session callback");
+        return 0;
+    }
+    DnsTlsSessionCache* cache = reinterpret_cast<DnsTlsSessionCache*>(
+            SSL_get_ex_data(ssl, 0));
+    if (!cache) {
+        ALOGE("null transport in new session callback");
+        return 0;
+    }
+    ALOGV("Recording session");
+    cache->recordSession(session);
+    return 1;  // Increment the refcount of session.
+}
+
+void DnsTlsSessionCache::recordSession(SSL_SESSION* session) {
+    std::lock_guard guard(mLock);
+    mSessions.emplace_front(session);
+    if (mSessions.size() > kMaxSize) {
+        ALOGV("Too many sessions; trimming");
+        mSessions.pop_back();
+    }
+}
+
+bssl::UniquePtr<SSL_SESSION> DnsTlsSessionCache::getSession() {
+    std::lock_guard guard(mLock);
+    if (mSessions.size() == 0) {
+        ALOGV("No known sessions");
+        return nullptr;
+    }
+    bssl::UniquePtr<SSL_SESSION> ret = std::move(mSessions.front());
+    mSessions.pop_front();
+    return ret;
+}
+
+}  // end of namespace net
+}  // end of namespace android
diff --git a/resolv/DnsTlsSessionCache.h b/resolv/DnsTlsSessionCache.h
new file mode 100644
index 0000000..e1a88cf
--- /dev/null
+++ b/resolv/DnsTlsSessionCache.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_DNSTLSSESSIONCACHE_H
+#define _DNS_DNSTLSSESSIONCACHE_H
+
+#include <deque>
+#include <mutex>
+
+#include <openssl/ssl.h>
+
+#include <android-base/thread_annotations.h>
+
+namespace android {
+namespace net {
+
+// Cache of recently seen SSL_SESSIONs.  This is used to support session tickets.
+// This class is thread-safe.
+class DnsTlsSessionCache {
+  public:
+    // Prepare SSL objects to use this session cache.  These methods must be called
+    // before making use of either object.
+    void prepareSslContext(SSL_CTX* _Nonnull ssl_ctx);
+    bool prepareSsl(SSL* _Nonnull ssl);
+
+    // Get the most recently discovered session.  For TLS 1.3 compatibility and
+    // maximum privacy, each session will only be returned once, so the caller
+    // gains ownership of the session.  (Here and throughout,
+    // bssl::UniquePtr<SSL_SESSION> is actually serving as a reference counted
+    // pointer.)
+    bssl::UniquePtr<SSL_SESSION> getSession() EXCLUDES(mLock);
+
+  private:
+    static constexpr size_t kMaxSize = 5;
+    static int newSessionCallback(SSL* _Nullable ssl, SSL_SESSION* _Nullable session);
+
+    std::mutex mLock;
+    void recordSession(SSL_SESSION* _Nullable session) EXCLUDES(mLock);
+
+    // Queue of sessions, from least recently added to most recently.
+    std::deque<bssl::UniquePtr<SSL_SESSION>> mSessions GUARDED_BY(mLock);
+};
+
+}  // end of namespace net
+}  // end of namespace android
+
+#endif  // _DNS_DNSTLSSESSIONCACHE_H
diff --git a/resolv/DnsTlsSocket.cpp b/resolv/DnsTlsSocket.cpp
new file mode 100644
index 0000000..a63d221
--- /dev/null
+++ b/resolv/DnsTlsSocket.cpp
@@ -0,0 +1,548 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DnsTlsSocket"
+//#define LOG_NDEBUG 0
+
+#include "DnsTlsSocket.h"
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <linux/tcp.h>
+#include <openssl/err.h>
+#include <openssl/sha.h>
+#include <sys/eventfd.h>
+#include <sys/poll.h>
+#include <algorithm>
+
+#include "DnsTlsSessionCache.h"
+#include "IDnsTlsSocketObserver.h"
+
+#include "log/log.h"
+#include "netdutils/SocketOption.h"
+
+namespace android {
+
+using netdutils::enableSockopt;
+using netdutils::enableTcpKeepAlives;
+using netdutils::isOk;
+using netdutils::Slice;
+using netdutils::Status;
+
+namespace net {
+namespace {
+
+constexpr const char kCaCertDir[] = "/system/etc/security/cacerts";
+constexpr size_t SHA256_SIZE = SHA256_DIGEST_LENGTH;
+
+int waitForReading(int fd) {
+    struct pollfd fds = { .fd = fd, .events = POLLIN };
+    const int ret = TEMP_FAILURE_RETRY(poll(&fds, 1, -1));
+    return ret;
+}
+
+int waitForWriting(int fd) {
+    struct pollfd fds = { .fd = fd, .events = POLLOUT };
+    const int ret = TEMP_FAILURE_RETRY(poll(&fds, 1, -1));
+    return ret;
+}
+
+}  // namespace
+
+Status DnsTlsSocket::tcpConnect() {
+    ALOGV("%u connecting TCP socket", mMark);
+    int type = SOCK_NONBLOCK | SOCK_CLOEXEC;
+    switch (mServer.protocol) {
+        case IPPROTO_TCP:
+            type |= SOCK_STREAM;
+            break;
+        default:
+            return Status(EPROTONOSUPPORT);
+    }
+
+    mSslFd.reset(socket(mServer.ss.ss_family, type, mServer.protocol));
+    if (mSslFd.get() == -1) {
+        ALOGE("Failed to create socket");
+        return Status(errno);
+    }
+
+    const socklen_t len = sizeof(mMark);
+    if (setsockopt(mSslFd.get(), SOL_SOCKET, SO_MARK, &mMark, len) == -1) {
+        ALOGE("Failed to set socket mark");
+        mSslFd.reset();
+        return Status(errno);
+    }
+
+    const Status tfo = enableSockopt(mSslFd.get(), SOL_TCP, TCP_FASTOPEN_CONNECT);
+    if (!isOk(tfo) && tfo.code() != ENOPROTOOPT) {
+        ALOGI("Failed to enable TFO: %s", tfo.msg().c_str());
+    }
+
+    // Send 5 keepalives, 3 seconds apart, after 15 seconds of inactivity.
+    enableTcpKeepAlives(mSslFd.get(), 15U, 5U, 3U).ignoreError();
+
+    if (connect(mSslFd.get(), reinterpret_cast<const struct sockaddr *>(&mServer.ss),
+                sizeof(mServer.ss)) != 0 &&
+            errno != EINPROGRESS) {
+        ALOGV("Socket failed to connect");
+        mSslFd.reset();
+        return Status(errno);
+    }
+
+    return netdutils::status::ok;
+}
+
+bool getSPKIDigest(const X509* cert, std::vector<uint8_t>* out) {
+    int spki_len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), nullptr);
+    unsigned char spki[spki_len];
+    unsigned char* temp = spki;
+    if (spki_len != i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp)) {
+        ALOGW("SPKI length mismatch");
+        return false;
+    }
+    out->resize(SHA256_SIZE);
+    unsigned int digest_len = 0;
+    int ret = EVP_Digest(spki, spki_len, out->data(), &digest_len, EVP_sha256(), nullptr);
+    if (ret != 1) {
+        ALOGW("Server cert digest extraction failed");
+        return false;
+    }
+    if (digest_len != out->size()) {
+        ALOGW("Wrong digest length: %d", digest_len);
+        return false;
+    }
+    return true;
+}
+
+bool DnsTlsSocket::initialize() {
+    // This method should only be called once, at the beginning, so locking should be
+    // unnecessary.  This lock only serves to help catch bugs in code that calls this method.
+    std::lock_guard guard(mLock);
+    if (mSslCtx) {
+        // This is a bug in the caller.
+        return false;
+    }
+    mSslCtx.reset(SSL_CTX_new(TLS_method()));
+    if (!mSslCtx) {
+        return false;
+    }
+
+    // Load system CA certs for hostname verification.
+    //
+    // For discussion of alternative, sustainable approaches see b/71909242.
+    if (SSL_CTX_load_verify_locations(mSslCtx.get(), nullptr, kCaCertDir) != 1) {
+        ALOGE("Failed to load CA cert dir: %s", kCaCertDir);
+        return false;
+    }
+
+    // Enable TLS false start
+    SSL_CTX_set_false_start_allowed_without_alpn(mSslCtx.get(), 1);
+    SSL_CTX_set_mode(mSslCtx.get(), SSL_MODE_ENABLE_FALSE_START);
+
+    // Enable session cache
+    mCache->prepareSslContext(mSslCtx.get());
+
+    // Connect
+    Status status = tcpConnect();
+    if (!status.ok()) {
+        return false;
+    }
+    mSsl = sslConnect(mSslFd.get());
+    if (!mSsl) {
+        return false;
+    }
+
+    mEventFd.reset(eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC));
+
+    // Start the I/O loop.
+    mLoopThread.reset(new std::thread(&DnsTlsSocket::loop, this));
+
+    return true;
+}
+
+bssl::UniquePtr<SSL> DnsTlsSocket::sslConnect(int fd) {
+    if (!mSslCtx) {
+        ALOGE("Internal error: context is null in sslConnect");
+        return nullptr;
+    }
+    if (!SSL_CTX_set_min_proto_version(mSslCtx.get(), TLS1_2_VERSION)) {
+        ALOGE("Failed to set minimum TLS version");
+        return nullptr;
+    }
+
+    bssl::UniquePtr<SSL> ssl(SSL_new(mSslCtx.get()));
+    // This file descriptor is owned by mSslFd, so don't let libssl close it.
+    bssl::UniquePtr<BIO> bio(BIO_new_socket(fd, BIO_NOCLOSE));
+    SSL_set_bio(ssl.get(), bio.get(), bio.get());
+    bio.release();
+
+    if (!mCache->prepareSsl(ssl.get())) {
+        return nullptr;
+    }
+
+    if (!mServer.name.empty()) {
+        if (SSL_set_tlsext_host_name(ssl.get(), mServer.name.c_str()) != 1) {
+            ALOGE("Failed to set SNI to %s", mServer.name.c_str());
+            return nullptr;
+        }
+        X509_VERIFY_PARAM* param = SSL_get0_param(ssl.get());
+        if (X509_VERIFY_PARAM_set1_host(param, mServer.name.data(), mServer.name.size()) != 1) {
+            ALOGE("Failed to set verify host param to %s", mServer.name.c_str());
+            return nullptr;
+        }
+        // This will cause the handshake to fail if certificate verification fails.
+        SSL_set_verify(ssl.get(), SSL_VERIFY_PEER, nullptr);
+    }
+
+    bssl::UniquePtr<SSL_SESSION> session = mCache->getSession();
+    if (session) {
+        ALOGV("Setting session");
+        SSL_set_session(ssl.get(), session.get());
+    } else {
+        ALOGV("No session available");
+    }
+
+    for (;;) {
+        ALOGV("%u Calling SSL_connect", mMark);
+        int ret = SSL_connect(ssl.get());
+        ALOGV("%u SSL_connect returned %d", mMark, ret);
+        if (ret == 1) break;  // SSL handshake complete;
+
+        const int ssl_err = SSL_get_error(ssl.get(), ret);
+        switch (ssl_err) {
+            case SSL_ERROR_WANT_READ:
+                if (waitForReading(fd) != 1) {
+                    ALOGW("SSL_connect read error: %d", errno);
+                    return nullptr;
+                }
+                break;
+            case SSL_ERROR_WANT_WRITE:
+                if (waitForWriting(fd) != 1) {
+                    ALOGW("SSL_connect write error");
+                    return nullptr;
+                }
+                break;
+            default:
+                ALOGW("SSL_connect error %d, errno=%d", ssl_err, errno);
+                return nullptr;
+        }
+    }
+
+    // TODO: Call SSL_shutdown before discarding the session if validation fails.
+    if (!mServer.fingerprints.empty()) {
+        ALOGV("Checking DNS over TLS fingerprint");
+
+        // We only care that the chain is internally self-consistent, not that
+        // it chains to a trusted root, so we can ignore some kinds of errors.
+        // TODO: Add a CA root verification mode that respects these errors.
+        int verify_result = SSL_get_verify_result(ssl.get());
+        switch (verify_result) {
+            case X509_V_OK:
+            case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+            case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+            case X509_V_ERR_CERT_UNTRUSTED:
+                break;
+            default:
+                ALOGW("Invalid certificate chain, error %d", verify_result);
+                return nullptr;
+        }
+
+        STACK_OF(X509) *chain = SSL_get_peer_cert_chain(ssl.get());
+        if (!chain) {
+            ALOGW("Server has null certificate");
+            return nullptr;
+        }
+        // Chain and its contents are owned by ssl, so we don't need to free explicitly.
+        bool matched = false;
+        for (size_t i = 0; i < sk_X509_num(chain); ++i) {
+            // This appears to be O(N^2), but there doesn't seem to be a straightforward
+            // way to walk a STACK_OF nondestructively in linear time.
+            X509* cert = sk_X509_value(chain, i);
+            std::vector<uint8_t> digest;
+            if (!getSPKIDigest(cert, &digest)) {
+                ALOGE("Digest computation failed");
+                return nullptr;
+            }
+
+            if (mServer.fingerprints.count(digest) > 0) {
+                matched = true;
+                break;
+            }
+        }
+
+        if (!matched) {
+            ALOGW("No matching fingerprint");
+            return nullptr;
+        }
+
+        ALOGV("DNS over TLS fingerprint is correct");
+    }
+
+    ALOGV("%u handshake complete", mMark);
+
+    return ssl;
+}
+
+void DnsTlsSocket::sslDisconnect() {
+    if (mSsl) {
+        SSL_shutdown(mSsl.get());
+        mSsl.reset();
+    }
+    mSslFd.reset();
+}
+
+bool DnsTlsSocket::sslWrite(const Slice buffer) {
+    ALOGV("%u Writing %zu bytes", mMark, buffer.size());
+    for (;;) {
+        int ret = SSL_write(mSsl.get(), buffer.base(), buffer.size());
+        if (ret == int(buffer.size())) break;  // SSL write complete;
+
+        if (ret < 1) {
+            const int ssl_err = SSL_get_error(mSsl.get(), ret);
+            switch (ssl_err) {
+                case SSL_ERROR_WANT_WRITE:
+                    if (waitForWriting(mSslFd.get()) != 1) {
+                        ALOGV("SSL_write error");
+                        return false;
+                    }
+                    continue;
+                case 0:
+                    break;  // SSL write complete;
+                default:
+                    ALOGV("SSL_write error %d", ssl_err);
+                    return false;
+            }
+        }
+    }
+    ALOGV("%u Wrote %zu bytes", mMark, buffer.size());
+    return true;
+}
+
+void DnsTlsSocket::loop() {
+    std::lock_guard guard(mLock);
+    std::deque<std::vector<uint8_t>> q;
+
+    const int timeout_msecs = DnsTlsSocket::kIdleTimeout.count() * 1000;
+    while (true) {
+        // poll() ignores negative fds
+        struct pollfd fds[2] = { { .fd = -1 }, { .fd = -1 } };
+        enum { SSLFD = 0, EVENTFD = 1 };
+
+        // Always listen for a response from server.
+        fds[SSLFD].fd = mSslFd.get();
+        fds[SSLFD].events = POLLIN;
+
+        // If we have pending queries, wait for space to write one.
+        // Otherwise, listen for new queries.
+        // Note: This blocks the destructor until q is empty, i.e. until all pending
+        // queries are sent or have failed to send.
+        if (!q.empty()) {
+            fds[SSLFD].events |= POLLOUT;
+        } else {
+            fds[EVENTFD].fd = mEventFd.get();
+            fds[EVENTFD].events = POLLIN;
+        }
+
+        const int s = TEMP_FAILURE_RETRY(poll(fds, std::size(fds), timeout_msecs));
+        if (s == 0) {
+            ALOGV("Idle timeout");
+            break;
+        }
+        if (s < 0) {
+            ALOGV("Poll failed: %d", errno);
+            break;
+        }
+        if (fds[SSLFD].revents & (POLLIN | POLLERR | POLLHUP)) {
+            if (!readResponse()) {
+                ALOGV("SSL remote close or read error.");
+                break;
+            }
+        }
+        if (fds[EVENTFD].revents & (POLLIN | POLLERR)) {
+            int64_t num_queries;
+            ssize_t res = read(mEventFd.get(), &num_queries, sizeof(num_queries));
+            if (res < 0) {
+                ALOGW("Error during eventfd read");
+                break;
+            } else if (res == 0) {
+                ALOGW("eventfd closed; disconnecting");
+                break;
+            } else if (res != sizeof(num_queries)) {
+                ALOGE("Int size mismatch: %zd != %zu", res, sizeof(num_queries));
+                break;
+            } else if (num_queries < 0) {
+                ALOGV("Negative eventfd read indicates destructor-initiated shutdown");
+                break;
+            }
+            // Take ownership of all pending queries.  (q is always empty here.)
+            mQueue.swap(q);
+        } else if (fds[SSLFD].revents & POLLOUT) {
+            // q cannot be empty here.
+            // Sending the entire queue here would risk a TCP flow control deadlock, so
+            // we only send a single query on each cycle of this loop.
+            // TODO: Coalesce multiple pending queries if there is enough space in the
+            // write buffer.
+            if (!sendQuery(q.front())) {
+                break;
+            }
+            q.pop_front();
+        }
+    }
+    ALOGV("Disconnecting");
+    sslDisconnect();
+    ALOGV("Calling onClosed");
+    mObserver->onClosed();
+    ALOGV("Ending loop");
+}
+
+DnsTlsSocket::~DnsTlsSocket() {
+    ALOGV("Destructor");
+    // This will trigger an orderly shutdown in loop().
+    requestLoopShutdown();
+    {
+        // Wait for the orderly shutdown to complete.
+        std::lock_guard guard(mLock);
+        if (mLoopThread && std::this_thread::get_id() == mLoopThread->get_id()) {
+            ALOGE("Violation of re-entrance precondition");
+            return;
+        }
+    }
+    if (mLoopThread) {
+        ALOGV("Waiting for loop thread to terminate");
+        mLoopThread->join();
+        mLoopThread.reset();
+    }
+    ALOGV("Destructor completed");
+}
+
+bool DnsTlsSocket::query(uint16_t id, const Slice query) {
+    // Compose the entire message in a single buffer, so that it can be
+    // sent as a single TLS record.
+    std::vector<uint8_t> buf(query.size() + 4);
+    // Write 2-byte length
+    uint16_t len = query.size() + 2;  // + 2 for the ID.
+    buf[0] = len >> 8;
+    buf[1] = len;
+    // Write 2-byte ID
+    buf[2] = id >> 8;
+    buf[3] = id;
+    // Copy body
+    std::memcpy(buf.data() + 4, query.base(), query.size());
+
+    mQueue.push(std::move(buf));
+    // Increment the mEventFd counter by 1.
+    return incrementEventFd(1);
+}
+
+void DnsTlsSocket::requestLoopShutdown() {
+    if (mEventFd != -1) {
+        // Write a negative number to the eventfd.  This triggers an immediate shutdown.
+        incrementEventFd(INT64_MIN);
+    }
+}
+
+bool DnsTlsSocket::incrementEventFd(const int64_t count) {
+    if (mEventFd == -1) {
+        ALOGE("eventfd is not initialized");
+        return false;
+    }
+    ssize_t written = write(mEventFd.get(), &count, sizeof(count));
+    if (written != sizeof(count)) {
+        ALOGE("Failed to increment eventfd by %" PRId64, count);
+        return false;
+    }
+    return true;
+}
+
+// Read exactly len bytes into buffer or fail with an SSL error code
+int DnsTlsSocket::sslRead(const Slice buffer, bool wait) {
+    size_t remaining = buffer.size();
+    while (remaining > 0) {
+        int ret = SSL_read(mSsl.get(), buffer.limit() - remaining, remaining);
+        if (ret == 0) {
+            ALOGW_IF(remaining < buffer.size(), "SSL closed with %zu of %zu bytes remaining",
+                     remaining, buffer.size());
+            return SSL_ERROR_ZERO_RETURN;
+        }
+
+        if (ret < 0) {
+            const int ssl_err = SSL_get_error(mSsl.get(), ret);
+            if (wait && ssl_err == SSL_ERROR_WANT_READ) {
+                if (waitForReading(mSslFd.get()) != 1) {
+                    ALOGV("Poll failed in sslRead: %d", errno);
+                    return SSL_ERROR_SYSCALL;
+                }
+                continue;
+            } else {
+                ALOGV("SSL_read error %d", ssl_err);
+                return ssl_err;
+            }
+        }
+
+        remaining -= ret;
+        wait = true;  // Once a read is started, try to finish.
+    }
+    return SSL_ERROR_NONE;
+}
+
+bool DnsTlsSocket::sendQuery(const std::vector<uint8_t>& buf) {
+    if (!sslWrite(netdutils::makeSlice(buf))) {
+        return false;
+    }
+    ALOGV("%u SSL_write complete", mMark);
+    return true;
+}
+
+bool DnsTlsSocket::readResponse() {
+    ALOGV("reading response");
+    uint8_t responseHeader[2];
+    int err = sslRead(Slice(responseHeader, 2), false);
+    if (err == SSL_ERROR_WANT_READ) {
+        ALOGV("Ignoring spurious wakeup from server");
+        return true;
+    }
+    if (err != SSL_ERROR_NONE) {
+        return false;
+    }
+    // Truncate responses larger than MAX_SIZE.  This is safe because a DNS packet is
+    // always invalid when truncated, so the response will be treated as an error.
+    constexpr uint16_t MAX_SIZE = 8192;
+    const uint16_t responseSize = (responseHeader[0] << 8) | responseHeader[1];
+    ALOGV("%u Expecting response of size %i", mMark, responseSize);
+    std::vector<uint8_t> response(std::min(responseSize, MAX_SIZE));
+    if (sslRead(netdutils::makeSlice(response), true) != SSL_ERROR_NONE) {
+        ALOGV("%u Failed to read %zu bytes", mMark, response.size());
+        return false;
+    }
+    uint16_t remainingBytes = responseSize - response.size();
+    while (remainingBytes > 0) {
+        constexpr uint16_t CHUNK_SIZE = 2048;
+        std::vector<uint8_t> discard(std::min(remainingBytes, CHUNK_SIZE));
+        if (sslRead(netdutils::makeSlice(discard), true) != SSL_ERROR_NONE) {
+            ALOGV("%u Failed to discard %zu bytes", mMark, discard.size());
+            return false;
+        }
+        remainingBytes -= discard.size();
+    }
+    ALOGV("%u SSL_read complete", mMark);
+
+    mObserver->onResponse(std::move(response));
+    return true;
+}
+
+}  // end of namespace net
+}  // end of namespace android
diff --git a/resolv/DnsTlsSocket.h b/resolv/DnsTlsSocket.h
new file mode 100644
index 0000000..2940500
--- /dev/null
+++ b/resolv/DnsTlsSocket.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_DNSTLSSOCKET_H
+#define _DNS_DNSTLSSOCKET_H
+
+#include <openssl/ssl.h>
+#include <future>
+#include <mutex>
+
+#include <android-base/thread_annotations.h>
+#include <android-base/unique_fd.h>
+#include <netdutils/Slice.h>
+#include <netdutils/Status.h>
+
+#include "DnsTlsServer.h"
+#include "IDnsTlsSocket.h"
+#include "LockedQueue.h"
+
+namespace android {
+namespace net {
+
+class IDnsTlsSocketObserver;
+class DnsTlsSessionCache;
+
+// A class for managing a TLS socket that sends and receives messages in
+// [length][value] format, with a 2-byte length (i.e. DNS-over-TCP format).
+// This class is not aware of query-response pairing or anything else about DNS.
+// For the observer:
+// This class is not re-entrant: the observer is not permitted to wait for a call to query()
+// or the destructor in a callback.  Doing so will result in deadlocks.
+// This class may call the observer at any time after initialize(), until the destructor
+// returns (but not after).
+class DnsTlsSocket : public IDnsTlsSocket {
+  public:
+    DnsTlsSocket(const DnsTlsServer& server, unsigned mark,
+                 IDnsTlsSocketObserver* _Nonnull observer, DnsTlsSessionCache* _Nonnull cache)
+        : mMark(mark), mServer(server), mObserver(observer), mCache(cache) {}
+    ~DnsTlsSocket();
+
+    // Creates the SSL context for this session and connect.  Returns false on failure.
+    // This method should be called after construction and before use of a DnsTlsSocket.
+    // Only call this method once per DnsTlsSocket.
+    bool initialize() EXCLUDES(mLock);
+
+    // Send a query on the provided SSL socket.  |query| contains
+    // the body of a query, not including the ID header. This function will typically return before
+    // the query is actually sent.  If this function fails, DnsTlsSocketObserver will be
+    // notified that the socket is closed.
+    // Note that success here indicates successful sending, not receipt of a response.
+    // Thread-safe.
+    bool query(uint16_t id, const netdutils::Slice query) override EXCLUDES(mLock);
+
+  private:
+    // Lock to be held by the SSL event loop thread.  This is not normally in contention.
+    std::mutex mLock;
+
+    // Forwards queries and receives responses.  Blocks until the idle timeout.
+    void loop() EXCLUDES(mLock);
+    std::unique_ptr<std::thread> mLoopThread GUARDED_BY(mLock);
+
+    // On success, sets mSslFd to a socket connected to mAddr (the
+    // connection will likely be in progress if mProtocol is IPPROTO_TCP).
+    // On error, returns the errno.
+    netdutils::Status tcpConnect() REQUIRES(mLock);
+
+    // Connect an SSL session on the provided socket.  If connection fails, closing the
+    // socket remains the caller's responsibility.
+    bssl::UniquePtr<SSL> sslConnect(int fd) REQUIRES(mLock);
+
+    // Disconnect the SSL session and close the socket.
+    void sslDisconnect() REQUIRES(mLock);
+
+    // Writes a buffer to the socket.
+    bool sslWrite(const netdutils::Slice buffer) REQUIRES(mLock);
+
+    // Reads exactly the specified number of bytes from the socket, or fails.
+    // Returns SSL_ERROR_NONE on success.
+    // If |wait| is true, then this function always blocks.  Otherwise, it
+    // will return SSL_ERROR_WANT_READ if there is no data from the server to read.
+    int sslRead(const netdutils::Slice buffer, bool wait) REQUIRES(mLock);
+
+    bool sendQuery(const std::vector<uint8_t>& buf) REQUIRES(mLock);
+    bool readResponse() REQUIRES(mLock);
+
+    // Similar to query(), this function uses incrementEventFd to send a message to the
+    // loop thread.  However, instead of incrementing the counter by one (indicating a
+    // new query), it wraps the counter to negative, which we use to indicate a shutdown
+    // request.
+    void requestLoopShutdown() EXCLUDES(mLock);
+
+    // This function sends a message to the loop thread by incrementing mEventFd.
+    bool incrementEventFd(int64_t count) EXCLUDES(mLock);
+
+    // Queue of pending queries.  query() pushes items onto the queue and notifies
+    // the loop thread by incrementing mEventFd.  loop() reads items off the queue.
+    LockedQueue<std::vector<uint8_t>> mQueue;
+
+    // eventfd socket used for notifying the SSL thread when queries are ready to send.
+    // This socket acts similarly to an atomic counter, incremented by query() and cleared
+    // by loop().  We have to use a socket because the SSL thread needs to wait in poll()
+    // for input from either a remote server or a query thread.  Since eventfd does not have
+    // EOF, we indicate a close request by setting the counter to a negative number.
+    // This file descriptor is opened by initialize(), and closed implicitly after
+    // destruction.
+    base::unique_fd mEventFd;
+
+    // SSL Socket fields.
+    bssl::UniquePtr<SSL_CTX> mSslCtx GUARDED_BY(mLock);
+    base::unique_fd mSslFd GUARDED_BY(mLock);
+    bssl::UniquePtr<SSL> mSsl GUARDED_BY(mLock);
+    static constexpr std::chrono::seconds kIdleTimeout = std::chrono::seconds(20);
+
+    const unsigned mMark;  // Socket mark
+    const DnsTlsServer mServer;
+    IDnsTlsSocketObserver* _Nonnull const mObserver;
+    DnsTlsSessionCache* _Nonnull const mCache;
+};
+
+}  // end of namespace net
+}  // end of namespace android
+
+#endif  // _DNS_DNSTLSSOCKET_H
diff --git a/resolv/DnsTlsSocketFactory.h b/resolv/DnsTlsSocketFactory.h
new file mode 100644
index 0000000..af4011d
--- /dev/null
+++ b/resolv/DnsTlsSocketFactory.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_DNSTLSSOCKETFACTORY_H
+#define _DNS_DNSTLSSOCKETFACTORY_H
+
+#include <memory>
+
+#include "DnsTlsSocket.h"
+#include "IDnsTlsSocketFactory.h"
+
+namespace android {
+namespace net {
+
+class IDnsTlsSocketObserver;
+class DnsTlsSessionCache;
+struct DnsTlsServer;
+
+// Trivial RAII factory for DnsTlsSocket.  This is owned by DnsTlsDispatcher.
+class DnsTlsSocketFactory : public IDnsTlsSocketFactory {
+  public:
+    std::unique_ptr<IDnsTlsSocket> createDnsTlsSocket(const DnsTlsServer& server, unsigned mark,
+                                                      IDnsTlsSocketObserver* _Nonnull observer,
+                                                      DnsTlsSessionCache* _Nonnull cache) override {
+        auto socket = std::make_unique<DnsTlsSocket>(server, mark, observer, cache);
+        if (!socket->initialize()) {
+            return nullptr;
+        }
+        return std::move(socket);
+    }
+};
+
+}  // end of namespace net
+}  // end of namespace android
+
+#endif  // _DNS_DNSTLSSOCKETFACTORY_H
diff --git a/resolv/DnsTlsTransport.cpp b/resolv/DnsTlsTransport.cpp
new file mode 100644
index 0000000..0f9042e
--- /dev/null
+++ b/resolv/DnsTlsTransport.cpp
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DnsTlsTransport"
+//#define LOG_NDEBUG 0
+
+#include "DnsTlsTransport.h"
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include "DnsTlsSocketFactory.h"
+#include "IDnsTlsSocketFactory.h"
+
+#include "log/log.h"
+
+namespace android {
+namespace net {
+
+std::future<DnsTlsTransport::Result> DnsTlsTransport::query(const netdutils::Slice query) {
+    std::lock_guard guard(mLock);
+
+    auto record = mQueries.recordQuery(query);
+    if (!record) {
+        return std::async(std::launch::deferred, []{
+            return (Result) { .code = Response::internal_error };
+        });
+    }
+
+    if (!mSocket) {
+        ALOGV("No socket for query.  Opening socket and sending.");
+        doConnect();
+    } else {
+        sendQuery(record->query);
+    }
+
+    return std::move(record->result);
+}
+
+bool DnsTlsTransport::sendQuery(const DnsTlsQueryMap::Query q) {
+    // Strip off the ID number and send the new ID instead.
+    bool sent = mSocket->query(q.newId, netdutils::drop(q.query, 2));
+    if (sent) {
+        mQueries.markTried(q.newId);
+    }
+    return sent;
+}
+
+void DnsTlsTransport::doConnect() {
+    ALOGV("Constructing new socket");
+    mSocket = mFactory->createDnsTlsSocket(mServer, mMark, this, &mCache);
+
+    if (mSocket) {
+        auto queries = mQueries.getAll();
+        ALOGV("Initialization succeeded.  Reissuing %zu queries.", queries.size());
+        for(auto& q : queries) {
+            if (!sendQuery(q)) {
+                break;
+            }
+        }
+    } else {
+        ALOGV("Initialization failed.");
+        mSocket.reset();
+        ALOGV("Failing all pending queries.");
+        mQueries.clear();
+    }
+}
+
+void DnsTlsTransport::onResponse(std::vector<uint8_t> response) {
+    mQueries.onResponse(std::move(response));
+}
+
+void DnsTlsTransport::onClosed() {
+    std::lock_guard guard(mLock);
+    if (mClosing) {
+        return;
+    }
+    // Move remaining operations to a new thread.
+    // This is necessary because
+    // 1. onClosed is currently running on a thread that blocks mSocket's destructor
+    // 2. doReconnect will call that destructor
+    if (mReconnectThread) {
+        // Complete cleanup of a previous reconnect thread, if present.
+        mReconnectThread->join();
+        // Joining a thread that is trying to acquire mLock, while holding mLock,
+        // looks like it risks a deadlock.  However, a deadlock will not occur because
+        // once onClosed is called, it cannot be called again until after doReconnect
+        // acquires mLock.
+    }
+    mReconnectThread.reset(new std::thread(&DnsTlsTransport::doReconnect, this));
+}
+
+void DnsTlsTransport::doReconnect() {
+    std::lock_guard guard(mLock);
+    if (mClosing) {
+        return;
+    }
+    mQueries.cleanup();
+    if (!mQueries.empty()) {
+        ALOGV("Fast reconnect to retry remaining queries");
+        doConnect();
+    } else {
+        ALOGV("No pending queries.  Going idle.");
+        mSocket.reset();
+    }
+}
+
+DnsTlsTransport::~DnsTlsTransport() {
+    ALOGV("Destructor");
+    {
+        std::lock_guard guard(mLock);
+        ALOGV("Locked destruction procedure");
+        mQueries.clear();
+        mClosing = true;
+    }
+    // It's possible that a reconnect thread was spawned and waiting for mLock.
+    // It's safe for that thread to run now because mClosing is true (and mQueries is empty),
+    // but we need to wait for it to finish before allowing destruction to proceed.
+    if (mReconnectThread) {
+        ALOGV("Waiting for reconnect thread to terminate");
+        mReconnectThread->join();
+        mReconnectThread.reset();
+    }
+    // Ensure that the socket is destroyed, and can clean up its callback threads,
+    // before any of this object's fields become invalid.
+    mSocket.reset();
+    ALOGV("Destructor completed");
+}
+
+// static
+// TODO: Use this function to preheat the session cache.
+// That may require moving it to DnsTlsDispatcher.
+bool DnsTlsTransport::validate(const DnsTlsServer& server, unsigned netid, uint32_t mark) {
+    ALOGV("Beginning validation on %u", netid);
+    // Generate "<random>-dnsotls-ds.metric.gstatic.com", which we will lookup through |ss| in
+    // order to prove that it is actually a working DNS over TLS server.
+    static const char kDnsSafeChars[] =
+            "abcdefhijklmnopqrstuvwxyz"
+            "ABCDEFHIJKLMNOPQRSTUVWXYZ"
+            "0123456789";
+    const auto c = [](uint8_t rnd) -> uint8_t {
+        return kDnsSafeChars[(rnd % std::size(kDnsSafeChars))];
+    };
+    uint8_t rnd[8];
+    arc4random_buf(rnd, std::size(rnd));
+    // We could try to use res_mkquery() here, but it's basically the same.
+    uint8_t query[] = {
+        rnd[6], rnd[7],  // [0-1]   query ID
+        1, 0,  // [2-3]   flags; query[2] = 1 for recursion desired (RD).
+        0, 1,  // [4-5]   QDCOUNT (number of queries)
+        0, 0,  // [6-7]   ANCOUNT (number of answers)
+        0, 0,  // [8-9]   NSCOUNT (number of name server records)
+        0, 0,  // [10-11] ARCOUNT (number of additional records)
+        17, c(rnd[0]), c(rnd[1]), c(rnd[2]), c(rnd[3]), c(rnd[4]), c(rnd[5]),
+            '-', 'd', 'n', 's', 'o', 't', 'l', 's', '-', 'd', 's',
+        6, 'm', 'e', 't', 'r', 'i', 'c',
+        7, 'g', 's', 't', 'a', 't', 'i', 'c',
+        3, 'c', 'o', 'm',
+        0,  // null terminator of FQDN (root TLD)
+        0, ns_t_aaaa,  // QTYPE
+        0, ns_c_in     // QCLASS
+    };
+    const int qlen = std::size(query);
+
+    int replylen = 0;
+    DnsTlsSocketFactory factory;
+    DnsTlsTransport transport(server, mark, &factory);
+    auto r = transport.query(netdutils::Slice(query, qlen)).get();
+    if (r.code != Response::success) {
+        ALOGV("query failed");
+        return false;
+    }
+
+    const std::vector<uint8_t>& recvbuf = r.response;
+    if (recvbuf.size() < NS_HFIXEDSZ) {
+        ALOGW("short response: %d", replylen);
+        return false;
+    }
+
+    const int qdcount = (recvbuf[4] << 8) | recvbuf[5];
+    if (qdcount != 1) {
+        ALOGW("reply query count != 1: %d", qdcount);
+        return false;
+    }
+
+    const int ancount = (recvbuf[6] << 8) | recvbuf[7];
+    ALOGV("%u answer count: %d", netid, ancount);
+
+    // TODO: Further validate the response contents (check for valid AAAA record, ...).
+    // Note that currently, integration tests rely on this function accepting a
+    // response with zero records.
+#if 0
+    for (int i = 0; i < resplen; i++) {
+        ALOGD("recvbuf[%d] = %d %c", i, recvbuf[i], recvbuf[i]);
+    }
+#endif
+    return true;
+}
+
+}  // end of namespace net
+}  // end of namespace android
diff --git a/resolv/DnsTlsTransport.h b/resolv/DnsTlsTransport.h
new file mode 100644
index 0000000..6c98fa6
--- /dev/null
+++ b/resolv/DnsTlsTransport.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_DNSTLSTRANSPORT_H
+#define _DNS_DNSTLSTRANSPORT_H
+
+#include <future>
+#include <map>
+#include <mutex>
+#include <vector>
+
+#include <android-base/thread_annotations.h>
+#include <android-base/unique_fd.h>
+#include <netdutils/Slice.h>
+
+#include "DnsTlsQueryMap.h"
+#include "DnsTlsServer.h"
+#include "DnsTlsSessionCache.h"
+#include "IDnsTlsSocket.h"
+#include "IDnsTlsSocketObserver.h"
+
+namespace android {
+namespace net {
+
+class IDnsTlsSocketFactory;
+
+// Manages at most one DnsTlsSocket at a time.  This class handles socket lifetime issues,
+// such as reopening the socket and reissuing pending queries.
+class DnsTlsTransport : public IDnsTlsSocketObserver {
+  public:
+    DnsTlsTransport(const DnsTlsServer& server, unsigned mark,
+                    IDnsTlsSocketFactory* _Nonnull factory)
+        : mMark(mark), mServer(server), mFactory(factory) {}
+    ~DnsTlsTransport();
+
+    typedef DnsTlsServer::Response Response;
+    typedef DnsTlsServer::Result Result;
+
+    // Given a |query|, this method sends it to the server and returns the result asynchronously.
+    std::future<Result> query(const netdutils::Slice query) EXCLUDES(mLock);
+
+    // Check that a given TLS server is fully working on the specified netid, and has the
+    // provided SHA-256 fingerprint (if nonempty).  This function is used in ResolverController
+    // to ensure that we don't enable DNS over TLS on networks where it doesn't actually work.
+    static bool validate(const DnsTlsServer& server, unsigned netid, uint32_t mark);
+
+    // Implement IDnsTlsSocketObserver
+    void onResponse(std::vector<uint8_t> response) override;
+    void onClosed() override EXCLUDES(mLock);
+
+  private:
+    std::mutex mLock;
+
+    DnsTlsSessionCache mCache;
+    DnsTlsQueryMap mQueries;
+
+    const unsigned mMark;  // Socket mark
+    const DnsTlsServer mServer;
+    IDnsTlsSocketFactory* _Nonnull const mFactory;
+
+    void doConnect() REQUIRES(mLock);
+
+    // doReconnect is used by onClosed.  It runs on the reconnect thread.
+    void doReconnect() EXCLUDES(mLock);
+    std::unique_ptr<std::thread> mReconnectThread GUARDED_BY(mLock);
+
+    // Used to prevent onClosed from starting a reconnect during the destructor.
+    bool mClosing GUARDED_BY(mLock) = false;
+
+    // Sending queries on the socket is thread-safe, but construction/destruction is not.
+    std::unique_ptr<IDnsTlsSocket> mSocket GUARDED_BY(mLock);
+
+    // Send a query to the socket.
+    bool sendQuery(const DnsTlsQueryMap::Query q) REQUIRES(mLock);
+};
+
+}  // end of namespace net
+}  // end of namespace android
+
+#endif  // _DNS_DNSTLSTRANSPORT_H
diff --git a/resolv/IDnsTlsSocket.h b/resolv/IDnsTlsSocket.h
new file mode 100644
index 0000000..0f2800e
--- /dev/null
+++ b/resolv/IDnsTlsSocket.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_IDNSTLSSOCKET_H
+#define _DNS_IDNSTLSSOCKET_H
+
+#include <cstddef>
+#include <cstdint>
+
+#include <netdutils/Slice.h>
+
+namespace android {
+namespace net {
+
+class IDnsTlsSocketObserver;
+class DnsTlsSessionCache;
+
+// A class for managing a TLS socket that sends and receives messages in
+// [length][value] format, with a 2-byte length (i.e. DNS-over-TCP format).
+// This interface is not aware of query-response pairing or anything else about DNS.
+class IDnsTlsSocket {
+  public:
+    virtual ~IDnsTlsSocket(){};
+    // Send a query on the provided SSL socket.  |query| contains
+    // the body of a query, not including the ID bytes.  This function will typically return before
+    // the query is actually sent.  If this function fails, the observer will be
+    // notified that the socket is closed.
+    // Note that a true return value indicates successful sending, not receipt of a response.
+    virtual bool query(uint16_t id, const netdutils::Slice query) = 0;
+};
+
+}  // end of namespace net
+}  // end of namespace android
+
+#endif  // _DNS_IDNSTLSSOCKET_H
diff --git a/resolv/IDnsTlsSocketFactory.h b/resolv/IDnsTlsSocketFactory.h
new file mode 100644
index 0000000..a391f59
--- /dev/null
+++ b/resolv/IDnsTlsSocketFactory.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_IDNSTLSSOCKETFACTORY_H
+#define _DNS_IDNSTLSSOCKETFACTORY_H
+
+#include "IDnsTlsSocket.h"
+
+namespace android {
+namespace net {
+
+class IDnsTlsSocketObserver;
+class DnsTlsSessionCache;
+struct DnsTlsServer;
+
+// Dependency injection interface for DnsTlsSocketFactory.
+// This pattern allows mocking of DnsTlsSocket for tests.
+class IDnsTlsSocketFactory {
+  public:
+    virtual ~IDnsTlsSocketFactory(){};
+    virtual std::unique_ptr<IDnsTlsSocket> createDnsTlsSocket(
+            const DnsTlsServer& server, unsigned mark, IDnsTlsSocketObserver* _Nonnull observer,
+            DnsTlsSessionCache* _Nonnull cache) = 0;
+};
+
+}  // end of namespace net
+}  // end of namespace android
+
+#endif  // _DNS_IDNSTLSSOCKETFACTORY_H
diff --git a/resolv/IDnsTlsSocketObserver.h b/resolv/IDnsTlsSocketObserver.h
new file mode 100644
index 0000000..980f74a
--- /dev/null
+++ b/resolv/IDnsTlsSocketObserver.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_IDNSTLSSOCKETOBSERVER_H
+#define _DNS_IDNSTLSSOCKETOBSERVER_H
+
+namespace android {
+namespace net {
+
+// Interface to listen for DNS query responses on a socket, and to be notified
+// when the socket is closed by the remote peer.  This is only implemented by
+// DnsTlsTransport, but it is a separate interface for clarity and to avoid a
+// circular dependency with DnsTlsSocket.
+class IDnsTlsSocketObserver {
+  public:
+    virtual ~IDnsTlsSocketObserver(){};
+    virtual void onResponse(std::vector<uint8_t> response) = 0;
+
+    virtual void onClosed() = 0;
+};
+
+}  // namespace net
+}  // namespace android
+
+#endif  // _DNS_IDNSTLSSOCKETOBSERVER_H
diff --git a/resolv/LockedQueue.h b/resolv/LockedQueue.h
new file mode 100644
index 0000000..0481eda
--- /dev/null
+++ b/resolv/LockedQueue.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNS_LOCKED_QUEUE_H
+#define _DNS_LOCKED_QUEUE_H
+
+#include <algorithm>
+#include <deque>
+#include <mutex>
+
+#include <android-base/thread_annotations.h>
+
+namespace android {
+namespace net {
+
+template <typename T>
+class LockedQueue {
+  public:
+    // Push an item onto the queue.
+    void push(T item) {
+        std::lock_guard guard(mLock);
+        mQueue.push_front(std::move(item));
+    }
+
+    // Swap out the contents of the queue
+    void swap(std::deque<T>& other) {
+        std::lock_guard guard(mLock);
+        mQueue.swap(other);
+    }
+
+  private:
+    std::mutex mLock;
+    std::deque<T> mQueue GUARDED_BY(mLock);
+};
+
+}  // end of namespace net
+}  // end of namespace android
+
+#endif  // _DNS_LOCKEDQUEUE_H
diff --git a/resolv/NOTICE b/resolv/NOTICE
new file mode 100644
index 0000000..7504f4d
--- /dev/null
+++ b/resolv/NOTICE
@@ -0,0 +1,418 @@
+Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the project nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2008 The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2014 The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2016 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1983, 1987, 1989
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1985
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement:
+    This product includes software developed by the University of
+    California, Berkeley and its contributors.
+4. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1985, 1988, 1993
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+Portions Copyright (c) 1993 by Digital Equipment Corporation.
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies, and that
+the name of Digital Equipment Corporation not be used in advertising or
+publicity pertaining to distribution of the document or software without
+specific, written prior permission.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1985, 1989, 1993
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement:
+    This product includes software developed by the University of
+    California, Berkeley and its contributors.
+4. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1985, 1993
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement:
+    This product includes software developed by the University of
+    California, Berkeley and its contributors.
+4. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1985, 1993
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+Copyright (c) 1995-1999 by Internet Software Consortium.
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+Copyright (c) 1999 by Internet Software Consortium.
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-------------------------------------------------------------------
+
+Portions Copyright (C) 2004, 2005, 2008, 2009  Internet Systems Consortium, Inc. ("ISC")
+Portions Copyright (C) 1996-2003  Internet Software Consortium.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+-------------------------------------------------------------------
+
+Portions Copyright (c) 1993 by Digital Equipment Corporation.
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies, and that
+the name of Digital Equipment Corporation not be used in advertising or
+publicity pertaining to distribution of the document or software without
+specific, written prior permission.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+-------------------------------------------------------------------
+
+Portions Copyright (c) 1995 by International Business Machines, Inc.
+
+International Business Machines, Inc. (hereinafter called IBM) grants
+permission under its copyrights to use, copy, modify, and distribute this
+Software with or without fee, provided that the above copyright notice and
+all paragraphs of this notice appear in all copies, and that the name of IBM
+not be used in connection with the marketing of any product incorporating
+the Software or modifications thereof, without specific, written prior
+permission.
+
+To the extent it has a right to do so, IBM grants an immunity from suit
+under its patents, if any, for the use, sale or manufacture of products to
+the extent that such products are used for performing Domain Name System
+dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+granted for any product per se or for any other function of any product.
+
+THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+-------------------------------------------------------------------
+
diff --git a/resolv/PrivateDnsConfiguration.cpp b/resolv/PrivateDnsConfiguration.cpp
new file mode 100644
index 0000000..1a88275
--- /dev/null
+++ b/resolv/PrivateDnsConfiguration.cpp
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "PrivateDnsConfiguration"
+#define DBG 0
+
+#include "PrivateDnsConfiguration.h"
+
+#include <log/log.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+#include "DnsTlsTransport.h"
+#include "ResolverEventReporter.h"
+#include "netd_resolv/resolv.h"
+#include "netdutils/BackoffSequence.h"
+
+namespace android {
+namespace net {
+
+std::string addrToString(const sockaddr_storage* addr) {
+    char out[INET6_ADDRSTRLEN] = {0};
+    getnameinfo((const sockaddr*) addr, sizeof(sockaddr_storage), out, INET6_ADDRSTRLEN, nullptr, 0,
+                NI_NUMERICHOST);
+    return std::string(out);
+}
+
+bool parseServer(const char* server, sockaddr_storage* parsed) {
+    addrinfo hints = {.ai_family = AF_UNSPEC, .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV};
+    addrinfo* res;
+
+    int err = getaddrinfo(server, "853", &hints, &res);
+    if (err != 0) {
+        ALOGW("Failed to parse server address (%s): %s", server, gai_strerror(err));
+        return false;
+    }
+
+    memcpy(parsed, res->ai_addr, res->ai_addrlen);
+    freeaddrinfo(res);
+    return true;
+}
+
+int PrivateDnsConfiguration::set(int32_t netId, uint32_t mark,
+                                 const std::vector<std::string>& servers, const std::string& name,
+                                 const std::set<std::vector<uint8_t>>& fingerprints) {
+    if (DBG) {
+        ALOGD("PrivateDnsConfiguration::set(%u, 0x%x, %zu, %s, %zu)", netId, mark, servers.size(),
+              name.c_str(), fingerprints.size());
+    }
+
+    const bool explicitlyConfigured = !name.empty() || !fingerprints.empty();
+
+    // Parse the list of servers that has been passed in
+    std::set<DnsTlsServer> tlsServers;
+    for (size_t i = 0; i < servers.size(); ++i) {
+        sockaddr_storage parsed;
+        if (!parseServer(servers[i].c_str(), &parsed)) {
+            return -EINVAL;
+        }
+        DnsTlsServer server(parsed);
+        server.name = name;
+        server.fingerprints = fingerprints;
+        tlsServers.insert(server);
+    }
+
+    std::lock_guard guard(mPrivateDnsLock);
+    if (explicitlyConfigured) {
+        mPrivateDnsModes[netId] = PrivateDnsMode::STRICT;
+    } else if (!tlsServers.empty()) {
+        mPrivateDnsModes[netId] = PrivateDnsMode::OPPORTUNISTIC;
+    } else {
+        mPrivateDnsModes[netId] = PrivateDnsMode::OFF;
+        mPrivateDnsTransports.erase(netId);
+        return 0;
+    }
+
+    // Create the tracker if it was not present
+    auto netPair = mPrivateDnsTransports.find(netId);
+    if (netPair == mPrivateDnsTransports.end()) {
+        // No TLS tracker yet for this netId.
+        bool added;
+        std::tie(netPair, added) = mPrivateDnsTransports.emplace(netId, PrivateDnsTracker());
+        if (!added) {
+            ALOGE("Memory error while recording private DNS for netId %d", netId);
+            return -ENOMEM;
+        }
+    }
+    auto& tracker = netPair->second;
+
+    // Remove any servers from the tracker that are not in |servers| exactly.
+    for (auto it = tracker.begin(); it != tracker.end();) {
+        if (tlsServers.count(it->first) == 0) {
+            it = tracker.erase(it);
+        } else {
+            ++it;
+        }
+    }
+
+    // Add any new or changed servers to the tracker, and initiate async checks for them.
+    for (const auto& server : tlsServers) {
+        if (needsValidation(tracker, server)) {
+            validatePrivateDnsProvider(server, tracker, netId, mark);
+        }
+    }
+    return 0;
+}
+
+PrivateDnsStatus PrivateDnsConfiguration::getStatus(unsigned netId) {
+    PrivateDnsStatus status{PrivateDnsMode::OFF, {}};
+    std::lock_guard guard(mPrivateDnsLock);
+
+    const auto mode = mPrivateDnsModes.find(netId);
+    if (mode == mPrivateDnsModes.end()) return status;
+    status.mode = mode->second;
+
+    const auto netPair = mPrivateDnsTransports.find(netId);
+    if (netPair != mPrivateDnsTransports.end()) {
+        for (const auto& serverPair : netPair->second) {
+            if (serverPair.second == Validation::success) {
+                status.validatedServers.push_back(serverPair.first);
+            }
+        }
+    }
+
+    return status;
+}
+
+void PrivateDnsConfiguration::getStatus(unsigned netId, ExternalPrivateDnsStatus* status) {
+    std::lock_guard guard(mPrivateDnsLock);
+
+    const auto mode = mPrivateDnsModes.find(netId);
+    if (mode == mPrivateDnsModes.end()) return;
+    status->mode = mode->second;
+
+    const auto netPair = mPrivateDnsTransports.find(netId);
+    if (netPair != mPrivateDnsTransports.end()) {
+        int count = 0;
+        for (const auto& serverPair : netPair->second) {
+            status->serverStatus[count].ss = serverPair.first.ss;
+            status->serverStatus[count].hostname =
+                    serverPair.first.name.empty() ? "" : serverPair.first.name.c_str();
+            status->serverStatus[count].validation = serverPair.second;
+            count++;
+            if (count >= MAXNS) break;  // Lose the rest
+        }
+        status->numServers = count;
+    }
+}
+
+void PrivateDnsConfiguration::clear(unsigned netId) {
+    if (DBG) {
+        ALOGD("PrivateDnsConfiguration::clear(%u)", netId);
+    }
+    std::lock_guard guard(mPrivateDnsLock);
+    mPrivateDnsModes.erase(netId);
+    mPrivateDnsTransports.erase(netId);
+}
+
+void PrivateDnsConfiguration::validatePrivateDnsProvider(const DnsTlsServer& server,
+                                                         PrivateDnsTracker& tracker, unsigned netId,
+                                                         uint32_t mark) REQUIRES(mPrivateDnsLock) {
+    if (DBG) {
+        ALOGD("validatePrivateDnsProvider(%s, %u)", addrToString(&server.ss).c_str(), netId);
+    }
+
+    tracker[server] = Validation::in_process;
+    if (DBG) {
+        ALOGD("Server %s marked as in_process.  Tracker now has size %zu",
+              addrToString(&server.ss).c_str(), tracker.size());
+    }
+    // Note that capturing |server| and |netId| in this lambda create copies.
+    std::thread validate_thread([this, server, netId, mark] {
+        // cat /proc/sys/net/ipv4/tcp_syn_retries yields "6".
+        //
+        // Start with a 1 minute delay and backoff to once per hour.
+        //
+        // Assumptions:
+        //     [1] Each TLS validation is ~10KB of certs+handshake+payload.
+        //     [2] Network typically provision clients with <=4 nameservers.
+        //     [3] Average month has 30 days.
+        //
+        // Each validation pass in a given hour is ~1.2MB of data. And 24
+        // such validation passes per day is about ~30MB per month, in the
+        // worst case. Otherwise, this will cost ~600 SYNs per month
+        // (6 SYNs per ip, 4 ips per validation pass, 24 passes per day).
+        auto backoff = netdutils::BackoffSequence<>::Builder()
+                               .withInitialRetransmissionTime(std::chrono::seconds(60))
+                               .withMaximumRetransmissionTime(std::chrono::seconds(3600))
+                               .build();
+
+        while (true) {
+            // ::validate() is a blocking call that performs network operations.
+            // It can take milliseconds to minutes, up to the SYN retry limit.
+            const bool success = DnsTlsTransport::validate(server, netId, mark);
+            if (DBG) {
+                ALOGD("validateDnsTlsServer returned %d for %s", success,
+                      addrToString(&server.ss).c_str());
+            }
+
+            const bool needs_reeval = this->recordPrivateDnsValidation(server, netId, success);
+            if (!needs_reeval) {
+                break;
+            }
+
+            if (backoff.hasNextTimeout()) {
+                std::this_thread::sleep_for(backoff.getNextTimeout());
+            } else {
+                break;
+            }
+        }
+    });
+    validate_thread.detach();
+}
+
+bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId,
+                                                         bool success) {
+    constexpr bool NEEDS_REEVALUATION = true;
+    constexpr bool DONT_REEVALUATE = false;
+
+    std::lock_guard guard(mPrivateDnsLock);
+
+    auto netPair = mPrivateDnsTransports.find(netId);
+    if (netPair == mPrivateDnsTransports.end()) {
+        ALOGW("netId %u was erased during private DNS validation", netId);
+        return DONT_REEVALUATE;
+    }
+
+    const auto mode = mPrivateDnsModes.find(netId);
+    if (mode == mPrivateDnsModes.end()) {
+        ALOGW("netId %u has no private DNS validation mode", netId);
+        return DONT_REEVALUATE;
+    }
+    const bool modeDoesReevaluation = (mode->second == PrivateDnsMode::STRICT);
+
+    bool reevaluationStatus =
+            (success || !modeDoesReevaluation) ? DONT_REEVALUATE : NEEDS_REEVALUATION;
+
+    auto& tracker = netPair->second;
+    auto serverPair = tracker.find(server);
+    if (serverPair == tracker.end()) {
+        ALOGW("Server %s was removed during private DNS validation",
+              addrToString(&server.ss).c_str());
+        success = false;
+        reevaluationStatus = DONT_REEVALUATE;
+    } else if (!(serverPair->first == server)) {
+        // TODO: It doesn't seem correct to overwrite the tracker entry for
+        // |server| down below in this circumstance... Fix this.
+        ALOGW("Server %s was changed during private DNS validation",
+              addrToString(&server.ss).c_str());
+        success = false;
+        reevaluationStatus = DONT_REEVALUATE;
+    }
+
+    // Send a validation event to NetdEventListenerService.
+    const auto& listeners = ResolverEventReporter::getInstance().getListeners();
+    if (listeners.size() != 0) {
+        for (const auto& it : listeners) {
+            it->onPrivateDnsValidationEvent(netId, addrToString(&server.ss), server.name, success);
+        }
+        if (DBG) {
+            ALOGD("Sent validation %s event on netId %u for %s with hostname %s",
+                  success ? "success" : "failure", netId, addrToString(&server.ss).c_str(),
+                  server.name.c_str());
+        }
+    } else {
+        ALOGE("Validation event not sent since no INetdEventListener receiver is available.");
+    }
+
+    if (success) {
+        tracker[server] = Validation::success;
+        if (DBG) {
+            ALOGD("Validation succeeded for %s! Tracker now has %zu entries.",
+                  addrToString(&server.ss).c_str(), tracker.size());
+        }
+    } else {
+        // Validation failure is expected if a user is on a captive portal.
+        // TODO: Trigger a second validation attempt after captive portal login
+        // succeeds.
+        tracker[server] = (reevaluationStatus == NEEDS_REEVALUATION) ? Validation::in_process
+                                                                     : Validation::fail;
+        if (DBG) {
+            ALOGD("Validation failed for %s!", addrToString(&server.ss).c_str());
+        }
+    }
+
+    return reevaluationStatus;
+}
+
+// Start validation for newly added servers as well as any servers that have
+// landed in Validation::fail state. Note that servers that have failed
+// multiple validation attempts but for which there is still a validating
+// thread running are marked as being Validation::in_process.
+bool PrivateDnsConfiguration::needsValidation(const PrivateDnsTracker& tracker,
+                                              const DnsTlsServer& server) {
+    const auto& iter = tracker.find(server);
+    return (iter == tracker.end()) || (iter->second == Validation::fail);
+}
+
+PrivateDnsConfiguration gPrivateDnsConfiguration;
+
+}  // namespace net
+}  // namespace android
diff --git a/resolv/PrivateDnsConfiguration.h b/resolv/PrivateDnsConfiguration.h
new file mode 100644
index 0000000..50fb54d
--- /dev/null
+++ b/resolv/PrivateDnsConfiguration.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NETD_RESOLV_PRIVATEDNSCONFIGURATION_H
+#define NETD_RESOLV_PRIVATEDNSCONFIGURATION_H
+
+#include <list>
+#include <map>
+#include <mutex>
+#include <vector>
+
+#include <android-base/thread_annotations.h>
+
+#include "DnsTlsServer.h"
+
+namespace android {
+namespace net {
+
+// The DNS over TLS mode on a specific netId.
+enum class PrivateDnsMode : uint8_t { OFF, OPPORTUNISTIC, STRICT };
+
+// Validation status of a DNS over TLS server (on a specific netId).
+enum class Validation : uint8_t { in_process, success, fail, unknown_server, unknown_netid };
+
+struct PrivateDnsStatus {
+    PrivateDnsMode mode;
+    std::list<DnsTlsServer> validatedServers;
+};
+
+// TODO: remove this C-style struct and use PrivateDnsStatus everywhere.
+struct ExternalPrivateDnsStatus {
+    PrivateDnsMode mode;
+    int numServers;
+    struct PrivateDnsInfo {
+        sockaddr_storage ss;
+        const char* hostname;
+        Validation validation;
+    } serverStatus[MAXNS];
+};
+
+class PrivateDnsConfiguration {
+  public:
+    int set(int32_t netId, uint32_t mark, const std::vector<std::string>& servers,
+            const std::string& name, const std::set<std::vector<uint8_t>>& fingerprints);
+
+    PrivateDnsStatus getStatus(unsigned netId);
+
+    // DEPRECATED, use getStatus() above.
+    void getStatus(unsigned netId, ExternalPrivateDnsStatus* status);
+
+    void clear(unsigned netId);
+
+  private:
+    typedef std::map<DnsTlsServer, Validation, AddressComparator> PrivateDnsTracker;
+
+    void validatePrivateDnsProvider(const DnsTlsServer& server, PrivateDnsTracker& tracker,
+                                    unsigned netId, uint32_t mark) REQUIRES(mPrivateDnsLock);
+
+    bool recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool success);
+
+    // Start validation for newly added servers as well as any servers that have
+    // landed in Validation::fail state. Note that servers that have failed
+    // multiple validation attempts but for which there is still a validating
+    // thread running are marked as being Validation::in_process.
+    bool needsValidation(const PrivateDnsTracker& tracker, const DnsTlsServer& server);
+
+    std::mutex mPrivateDnsLock;
+    std::map<unsigned, PrivateDnsMode> mPrivateDnsModes GUARDED_BY(mPrivateDnsLock);
+    // Structure for tracking the validation status of servers on a specific netId.
+    // Using the AddressComparator ensures at most one entry per IP address.
+    std::map<unsigned, PrivateDnsTracker> mPrivateDnsTransports GUARDED_BY(mPrivateDnsLock);
+};
+
+extern PrivateDnsConfiguration gPrivateDnsConfiguration;
+
+}  // namespace net
+}  // namespace android
+
+#endif /* NETD_RESOLV_PRIVATEDNSCONFIGURATION_H */
diff --git a/resolv/README.md b/resolv/README.md
new file mode 100644
index 0000000..8fe4c89
--- /dev/null
+++ b/resolv/README.md
@@ -0,0 +1,134 @@
+# DNS-over-TLS query forwarder design
+
+## Overview
+
+The DNS-over-TLS query forwarder consists of five classes:
+ * `DnsTlsDispatcher`
+ * `DnsTlsTransport`
+ * `DnsTlsQueryMap`
+ * `DnsTlsSessionCache`
+ * `DnsTlsSocket`
+
+`DnsTlsDispatcher` is a singleton class whose `query` method is the DnsTls's
+only public interface.  `DnsTlsDispatcher` is just a table holding the
+`DnsTlsTransport` for each server (represented by a `DnsTlsServer` struct) and
+network.  `DnsTlsDispatcher` also blocks each query thread, waiting on a
+`std::future` returned by `DnsTlsTransport` that represents the response.
+
+`DnsTlsTransport` sends each query over a `DnsTlsSocket`, opening a
+new one if necessary.  It also has to listen for responses from the
+`DnsTlsSocket`, which happen on a different thread.
+`IDnsTlsSocketObserver` is an interface defining how `DnsTlsSocket` returns
+responses to `DnsTlsTransport`.
+
+`DnsTlsQueryMap` and `DnsTlsSessionCache` are helper classes owned by `DnsTlsTransport`.
+`DnsTlsQueryMap` handles ID renumbering and query-response pairing.
+`DnsTlsSessionCache` allows TLS session resumption.
+
+`DnsTlsSocket` interleaves all queries onto a single socket, and reports all
+responses to `DnsTlsTransport` (through the `IDnsTlsObserver` interface).  It doesn't
+know anything about which queries correspond to which responses, and does not retain
+state to indicate whether there is an outstanding query.
+
+## Threading
+
+### Overall patterns
+
+For clarity, each of the five classes in this design is thread-safe and holds one lock.
+Classes that spawn a helper thread call `thread::join()` in their destructor to ensure
+that it is cleaned up appropriately.
+
+All the classes here make full use of Clang thread annotations (and also null-pointer
+annotations) to minimize the likelihood of a latent threading bug.  The unit tests are
+also heavily threaded to exercise this functionality.
+
+This code creates O(1) threads per socket, and does not create a new thread for each
+query or response.  However, DnsProxyListener does create a thread for each query.
+
+### Threading in `DnsTlsSocket`
+
+`DnsTlsSocket` can receive queries on any thread, and send them over a
+"reliable datagram pipe" (`socketpair()` in `SOCK_SEQPACKET` mode).
+The query method writes a struct (containing a pointer to the query) to the pipe
+from its thread, and the loop thread (which owns the SSL socket)
+reads off the other end of the pipe.  The pipe doesn't actually have a queue "inside";
+instead, any queueing happens by blocking the query thread until the
+socket thread can read the datagram off the other end.
+
+We need to pass messages between threads using a pipe, and not a condition variable
+or a thread-safe queue, because the socket thread has to be blocked
+in `poll()` waiting for data from the server, but also has to be woken
+up on inputs from the query threads.  Therefore, inputs from the query
+threads have to arrive on a socket, so that `poll()` can listen for them.
+(There can only be a single thread because [you can't use different threads
+to read and write in OpenSSL](https://www.openssl.org/blog/blog/2017/02/21/threads/)).
+
+## ID renumbering
+
+`DnsTlsDispatcher` accepts queries that have colliding ID numbers and still sends them on
+a single socket.  To avoid confusion at the server, `DnsTlsQueryMap` assigns each
+query a new ID for transmission, records the mapping from input IDs to sent IDs, and
+applies the inverse mapping to responses before returning them to the caller.
+
+`DnsTlsQueryMap` assigns each new query the ID number one greater than the largest
+ID number of an outstanding query.  This means that ID numbers are initially sequential
+and usually small.  If the largest possible ID number is already in use,
+`DnsTlsQueryMap` will scan the ID space to find an available ID, or fail the query
+if there are no available IDs.  Queries will not block waiting for an ID number to
+become available.
+
+## Time constants
+
+`DnsTlsSocket` imposes a 20-second inactivity timeout.  A socket that has been idle for
+20 seconds will be closed.  This sets the limit of tolerance for slow replies,
+which could happen as a result of malfunctioning authoritative DNS servers.
+If there are any pending queries, `DnsTlsTransport` will retry them.
+
+`DnsTlsQueryMap` imposes a retry limit of 3.  `DnsTlsTransport` will retry the query up
+to 3 times before reporting failure to `DnsTlsDispatcher`.
+This limit helps to ensure proper functioning in the case of a recursive resolver that
+is malfunctioning or is flooded with requests that are stalled due to malfunctioning
+authoritative servers.
+
+`DnsTlsDispatcher` maintains a 5-minute timeout.  Any `DnsTlsTransport` that has had no
+outstanding queries for 5 minutes will be destroyed at the next query on a different
+transport.
+This sets the limit on how long session tickets will be preserved during idle periods,
+because each `DnsTlsTransport` owns a `DnsTlsSessionCache`.  Imposing this timeout
+increases latency on the first query after an idle period, but also helps to avoid
+unbounded memory usage.
+
+`DnsTlsSessionCache` sets a limit of 5 sessions in each cache, expiring the oldest one
+when the limit is reached.  However, because the client code does not currently
+reuse sessions more than once, it should not be possible to hit this limit.
+
+## Testing
+
+Unit tests are in `dns_tls_test.cpp`. They cover all the classes except
+`DnsTlsSocket` (which requires `CAP_NET_ADMIN` because it uses `setsockopt(SO_MARK)`) and
+`DnsTlsSessionCache` (which requires integration with libssl).  These classes are
+exercised by the integration tests in `../tests/resolv_test.cpp`.
+
+### Dependency Injection
+
+For unit testing, we would like to be able to mock out `DnsTlsSocket`.  This is
+particularly required for unit testing of `DnsTlsDispatcher` and `DnsTlsTransport`.
+To make these unit tests possible, this code uses a dependency injection pattern:
+`DnsTlsSocket` is produced by a `DnsTlsSocketFactory`, and both of these have a
+defined interface.
+
+`DnsTlsDispatcher`'s constructor takes an `IDnsTlsSocketFactory`,
+which in production is a `DnsTlsSocketFactory`.  However, in unit tests, we can
+substitute a test factory that returns a fake socket, so that the unit tests can
+run without actually connecting over TLS to a test server.  (The integration tests
+do actual TLS.)
+
+## Logging
+
+This code uses `ALOGV` throughout for low-priority logging, and does not use
+`ALOGD`.  `ALOGV` is disabled by default, unless activated by `#define LOG_NDEBUG 0`.
+(`ALOGD` is not disabled by default, requiring extra measures to avoid spamming the
+system log in production builds.)
+
+## Reference
+ * [BoringSSL API docs](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html)
diff --git a/resolv/ResolverController.cpp b/resolv/ResolverController.cpp
new file mode 100644
index 0000000..ac24259
--- /dev/null
+++ b/resolv/ResolverController.cpp
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ResolverController"
+
+#include "ResolverController.h"
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include <netdb.h>
+
+#include <aidl/android/net/IDnsResolver.h>
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+
+#include "Dns64Configuration.h"
+#include "DnsResolver.h"
+#include "Fwmark.h"
+#include "PrivateDnsConfiguration.h"
+#include "ResolverEventReporter.h"
+#include "ResolverStats.h"
+#include "netd_resolv/stats.h"
+#include "resolv_cache.h"
+
+using namespace std::placeholders;
+using aidl::android::net::ResolverParamsParcel;
+
+namespace android {
+
+using netdutils::DumpWriter;
+
+namespace net {
+
+namespace {
+
+std::string addrToString(const sockaddr_storage* addr) {
+    char out[INET6_ADDRSTRLEN] = {0};
+    getnameinfo((const sockaddr*)addr, sizeof(sockaddr_storage), out, INET6_ADDRSTRLEN, nullptr, 0,
+                NI_NUMERICHOST);
+    return std::string(out);
+}
+
+const char* getPrivateDnsModeString(PrivateDnsMode mode) {
+    switch (mode) {
+        case PrivateDnsMode::OFF:
+            return "OFF";
+        case PrivateDnsMode::OPPORTUNISTIC:
+            return "OPPORTUNISTIC";
+        case PrivateDnsMode::STRICT:
+            return "STRICT";
+    }
+}
+
+constexpr const char* validationStatusToString(Validation value) {
+    switch (value) {
+        case Validation::in_process:
+            return "in_process";
+        case Validation::success:
+            return "success";
+        case Validation::fail:
+            return "fail";
+        case Validation::unknown_server:
+            return "unknown_server";
+        case Validation::unknown_netid:
+            return "unknown_netid";
+        default:
+            return "unknown_status";
+    }
+}
+
+void sendNat64PrefixEvent(const Dns64Configuration::Nat64PrefixInfo& args) {
+    const auto& listeners = ResolverEventReporter::getInstance().getListeners();
+    if (listeners.size() == 0) {
+        LOG(ERROR) << __func__ << ": No available listener. dropping NAT64 prefix event";
+        return;
+    }
+    for (const auto& it : listeners) {
+        it->onNat64PrefixEvent(args.netId, args.added, args.prefixString, args.prefixLength);
+    }
+}
+
+int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<std::string>* domains,
+               res_params* params, std::vector<android::net::ResolverStats>* stats,
+               std::vector<int32_t>* wait_for_pending_req_timeout_count) {
+    using aidl::android::net::IDnsResolver;
+    using android::net::ResolverStats;
+    static_assert(ResolverStats::STATS_SUCCESSES == IDnsResolver::RESOLVER_STATS_SUCCESSES &&
+                          ResolverStats::STATS_ERRORS == IDnsResolver::RESOLVER_STATS_ERRORS &&
+                          ResolverStats::STATS_TIMEOUTS == IDnsResolver::RESOLVER_STATS_TIMEOUTS &&
+                          ResolverStats::STATS_INTERNAL_ERRORS ==
+                                  IDnsResolver::RESOLVER_STATS_INTERNAL_ERRORS &&
+                          ResolverStats::STATS_RTT_AVG == IDnsResolver::RESOLVER_STATS_RTT_AVG &&
+                          ResolverStats::STATS_LAST_SAMPLE_TIME ==
+                                  IDnsResolver::RESOLVER_STATS_LAST_SAMPLE_TIME &&
+                          ResolverStats::STATS_USABLE == IDnsResolver::RESOLVER_STATS_USABLE &&
+                          ResolverStats::STATS_COUNT == IDnsResolver::RESOLVER_STATS_COUNT,
+                  "AIDL and ResolverStats.h out of sync");
+    int nscount = -1;
+    sockaddr_storage res_servers[MAXNS];
+    int dcount = -1;
+    char res_domains[MAXDNSRCH][MAXDNSRCHPATH];
+    res_stats res_stats[MAXNS];
+    servers->clear();
+    domains->clear();
+    *params = res_params{};
+    stats->clear();
+    int res_wait_for_pending_req_timeout_count;
+    int revision_id = android_net_res_stats_get_info_for_net(
+            netId, &nscount, res_servers, &dcount, res_domains, params, res_stats,
+            &res_wait_for_pending_req_timeout_count);
+
+    // If the netId is unknown (which can happen for valid net IDs for which no DNS servers have
+    // yet been configured), there is no revision ID. In this case there is no data to return.
+    if (revision_id < 0) {
+        return 0;
+    }
+
+    // Verify that the returned data is sane.
+    if (nscount < 0 || nscount > MAXNS || dcount < 0 || dcount > MAXDNSRCH) {
+        LOG(ERROR) << __func__ << ": nscount = " << nscount << ", dcount = " << dcount;
+        return -ENOTRECOVERABLE;
+    }
+
+    // Determine which servers are considered usable by the resolver.
+    bool valid_servers[MAXNS];
+    std::fill_n(valid_servers, MAXNS, false);
+    android_net_res_stats_get_usable_servers(params, res_stats, nscount, valid_servers);
+
+    // Convert the server sockaddr structures to std::string.
+    stats->resize(nscount);
+    for (int i = 0; i < nscount; ++i) {
+        char hbuf[NI_MAXHOST];
+        int rv =
+                getnameinfo(reinterpret_cast<const sockaddr*>(&res_servers[i]),
+                            sizeof(res_servers[i]), hbuf, sizeof(hbuf), nullptr, 0, NI_NUMERICHOST);
+        std::string server_str;
+        if (rv == 0) {
+            server_str.assign(hbuf);
+        } else {
+            LOG(ERROR) << "getnameinfo() failed for server #" << i << ": " << gai_strerror(rv);
+            server_str.assign("<invalid>");
+        }
+        servers->push_back(std::move(server_str));
+        android::net::ResolverStats& cur_stats = (*stats)[i];
+        android_net_res_stats_aggregate(&res_stats[i], &cur_stats.successes, &cur_stats.errors,
+                                        &cur_stats.timeouts, &cur_stats.internal_errors,
+                                        &cur_stats.rtt_avg, &cur_stats.last_sample_time);
+        cur_stats.usable = valid_servers[i];
+    }
+
+    // Convert the stack-allocated search domain strings to std::string.
+    for (int i = 0; i < dcount; ++i) {
+        domains->push_back(res_domains[i]);
+    }
+
+    (*wait_for_pending_req_timeout_count)[0] = res_wait_for_pending_req_timeout_count;
+    return 0;
+}
+
+}  // namespace
+
+ResolverController::ResolverController()
+    : mDns64Configuration(
+              [](uint32_t netId, uint32_t uid, android_net_context* netcontext) {
+                  gResNetdCallbacks.get_network_context(netId, uid, netcontext);
+              },
+              std::bind(sendNat64PrefixEvent, _1)) {}
+
+void ResolverController::destroyNetworkCache(unsigned netId) {
+    LOG(VERBOSE) << __func__ << ": netId = " << netId;
+
+    resolv_delete_cache_for_net(netId);
+    mDns64Configuration.stopPrefixDiscovery(netId);
+    gPrivateDnsConfiguration.clear(netId);
+}
+
+int ResolverController::createNetworkCache(unsigned netId) {
+    LOG(VERBOSE) << __func__ << ": netId = " << netId;
+
+    return resolv_create_cache_for_net(netId);
+}
+
+int ResolverController::setResolverConfiguration(
+        const ResolverParamsParcel& resolverParams,
+        const std::set<std::vector<uint8_t>>& tlsFingerprints) {
+    using aidl::android::net::IDnsResolver;
+
+    // At private DNS validation time, we only know the netId, so we have to guess/compute the
+    // corresponding socket mark.
+    Fwmark fwmark;
+    fwmark.netId = resolverParams.netId;
+    fwmark.explicitlySelected = true;
+    fwmark.protectedFromVpn = true;
+    fwmark.permission = PERMISSION_SYSTEM;
+
+    // Allow at most MAXNS private DNS servers in a network to prevent too many broken servers.
+    std::vector<std::string> tlsServers = resolverParams.tlsServers;
+    if (tlsServers.size() > MAXNS) {
+        tlsServers.resize(MAXNS);
+    }
+    const int err = gPrivateDnsConfiguration.set(resolverParams.netId, fwmark.intValue, tlsServers,
+                                                 resolverParams.tlsName, tlsFingerprints);
+    if (err != 0) {
+        return err;
+    }
+
+    // Convert network-assigned server list to bionic's format.
+    const size_t serverCount = std::min<size_t>(MAXNS, resolverParams.servers.size());
+    std::vector<const char*> server_ptrs;
+    for (size_t i = 0; i < serverCount; ++i) {
+        server_ptrs.push_back(resolverParams.servers[i].c_str());
+    }
+
+    std::string domains_str = android::base::Join(resolverParams.domains, " ");
+
+    // TODO: Change resolv_set_nameservers_for_net() to use ResolverParamsParcel directly.
+    res_params res_params = {};
+    res_params.sample_validity = resolverParams.sampleValiditySeconds;
+    res_params.success_threshold = resolverParams.successThreshold;
+    res_params.min_samples = resolverParams.minSamples;
+    res_params.max_samples = resolverParams.maxSamples;
+    res_params.base_timeout_msec = resolverParams.baseTimeoutMsec;
+    res_params.retry_count = resolverParams.retryCount;
+
+    LOG(VERBOSE) << "setDnsServers netId = " << resolverParams.netId
+                 << ", numservers = " << resolverParams.domains.size();
+
+    return -resolv_set_nameservers_for_net(resolverParams.netId, server_ptrs.data(),
+                                           server_ptrs.size(), domains_str.c_str(), &res_params);
+}
+
+int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* servers,
+                                        std::vector<std::string>* domains,
+                                        std::vector<std::string>* tlsServers,
+                                        std::vector<int32_t>* params, std::vector<int32_t>* stats,
+                                        std::vector<int32_t>* wait_for_pending_req_timeout_count) {
+    using aidl::android::net::IDnsResolver;
+    using android::net::ResolverStats;
+    res_params res_params;
+    std::vector<ResolverStats> res_stats;
+    int ret = getDnsInfo(netId, servers, domains, &res_params, &res_stats,
+                         wait_for_pending_req_timeout_count);
+    if (ret != 0) {
+        return ret;
+    }
+
+    // Serialize the information for binder.
+    ResolverStats::encodeAll(res_stats, stats);
+
+    ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}};
+    gPrivateDnsConfiguration.getStatus(netId, &privateDnsStatus);
+    for (int i = 0; i < privateDnsStatus.numServers; i++) {
+        std::string tlsServer_str = addrToString(&(privateDnsStatus.serverStatus[i].ss));
+        tlsServers->push_back(std::move(tlsServer_str));
+    }
+
+    params->resize(IDnsResolver::RESOLVER_PARAMS_COUNT);
+    (*params)[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY] = res_params.sample_validity;
+    (*params)[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD] = res_params.success_threshold;
+    (*params)[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES] = res_params.min_samples;
+    (*params)[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES] = res_params.max_samples;
+    (*params)[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC] = res_params.base_timeout_msec;
+    (*params)[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT] = res_params.retry_count;
+    return 0;
+}
+
+void ResolverController::startPrefix64Discovery(int32_t netId) {
+    mDns64Configuration.startPrefixDiscovery(netId);
+}
+
+void ResolverController::stopPrefix64Discovery(int32_t netId) {
+    return mDns64Configuration.stopPrefixDiscovery(netId);
+}
+
+// TODO: use StatusOr<T> to wrap the result.
+int ResolverController::getPrefix64(unsigned netId, netdutils::IPPrefix* prefix) {
+    netdutils::IPPrefix p = mDns64Configuration.getPrefix64(netId);
+    if (p.family() != AF_INET6 || p.length() == 0) {
+        LOG(ERROR) << "No valid NAT64 prefix (" << netId << ", " << p.toString().c_str() << ")";
+
+        return -ENOENT;
+    }
+    *prefix = p;
+    return 0;
+}
+
+void ResolverController::dump(DumpWriter& dw, unsigned netId) {
+    // No lock needed since Bionic's resolver locks all accessed data structures internally.
+    using android::net::ResolverStats;
+    std::vector<std::string> servers;
+    std::vector<std::string> domains;
+    res_params params = {};
+    std::vector<ResolverStats> stats;
+    std::vector<int32_t> wait_for_pending_req_timeout_count(1, 0);
+    time_t now = time(nullptr);
+    int rv = getDnsInfo(netId, &servers, &domains, &params, &stats,
+                        &wait_for_pending_req_timeout_count);
+    dw.incIndent();
+    if (rv != 0) {
+        dw.println("getDnsInfo() failed for netid %u", netId);
+    } else {
+        if (servers.empty()) {
+            dw.println("No DNS servers defined");
+        } else {
+            dw.println("DnsEvent subsampling map: " +
+                       android::base::Join(resolv_cache_dump_subsampling_map(netId), ' '));
+            dw.println(
+                    "DNS servers: # IP (total, successes, errors, timeouts, internal errors, "
+                    "RTT avg, last sample)");
+            dw.incIndent();
+            for (size_t i = 0; i < servers.size(); ++i) {
+                if (i < stats.size()) {
+                    const ResolverStats& s = stats[i];
+                    int total = s.successes + s.errors + s.timeouts + s.internal_errors;
+                    if (total > 0) {
+                        int time_delta = (s.last_sample_time > 0) ? now - s.last_sample_time : -1;
+                        dw.println("%s (%d, %d, %d, %d, %d, %dms, %ds)%s", servers[i].c_str(),
+                                   total, s.successes, s.errors, s.timeouts, s.internal_errors,
+                                   s.rtt_avg, time_delta, s.usable ? "" : " BROKEN");
+                    } else {
+                        dw.println("%s <no data>", servers[i].c_str());
+                    }
+                } else {
+                    dw.println("%s <no stats>", servers[i].c_str());
+                }
+            }
+            dw.decIndent();
+        }
+        if (domains.empty()) {
+            dw.println("No search domains defined");
+        } else {
+            std::string domains_str = android::base::Join(domains, ", ");
+            dw.println("search domains: %s", domains_str.c_str());
+        }
+        if (params.sample_validity != 0) {
+            dw.println(
+                    "DNS parameters: sample validity = %us, success threshold = %u%%, "
+                    "samples (min, max) = (%u, %u), base_timeout = %dmsec, retry count = "
+                    "%dtimes",
+                    params.sample_validity, params.success_threshold, params.min_samples,
+                    params.max_samples, params.base_timeout_msec, params.retry_count);
+        }
+
+        mDns64Configuration.dump(dw, netId);
+        ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}};
+        gPrivateDnsConfiguration.getStatus(netId, &privateDnsStatus);
+        dw.println("Private DNS mode: %s", getPrivateDnsModeString(privateDnsStatus.mode));
+        if (!privateDnsStatus.numServers) {
+            dw.println("No Private DNS servers configured");
+        } else {
+            dw.println("Private DNS configuration (%u entries)", privateDnsStatus.numServers);
+            dw.incIndent();
+            for (int i = 0; i < privateDnsStatus.numServers; i++) {
+                dw.println("%s name{%s} status{%s}",
+                           addrToString(&(privateDnsStatus.serverStatus[i].ss)).c_str(),
+                           privateDnsStatus.serverStatus[i].hostname,
+                           validationStatusToString(static_cast<Validation>(
+                                   privateDnsStatus.serverStatus[i].validation)));
+            }
+            dw.decIndent();
+        }
+        dw.println("Concurrent DNS query timeout: %d", wait_for_pending_req_timeout_count[0]);
+    }
+    dw.decIndent();
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/resolv/ResolverController.h b/resolv/ResolverController.h
new file mode 100644
index 0000000..6d08cdb
--- /dev/null
+++ b/resolv/ResolverController.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _RESOLVER_CONTROLLER_H_
+#define _RESOLVER_CONTROLLER_H_
+
+#include <list>
+#include <set>
+#include <vector>
+
+#include <aidl/android/net/ResolverParamsParcel.h>
+#include "Dns64Configuration.h"
+#include "netd_resolv/resolv.h"
+#include "netdutils/DumpWriter.h"
+
+struct res_params;
+
+namespace android {
+namespace net {
+
+struct ResolverStats;
+
+class ResolverController {
+  public:
+    ResolverController();
+    ~ResolverController() = default;
+
+    void destroyNetworkCache(unsigned netid);
+    int createNetworkCache(unsigned netid);
+
+    int getPrefix64(unsigned netId, netdutils::IPPrefix* prefix);
+
+    // Binder specific functions, which convert between the ResolverParamsParcel and the
+    // actual data structures, and call setDnsServer() / getDnsInfo() for the actual processing.
+    int setResolverConfiguration(const aidl::android::net::ResolverParamsParcel& resolverParams,
+                                 const std::set<std::vector<uint8_t>>& tlsFingerprints);
+
+    int getResolverInfo(int32_t netId, std::vector<std::string>* servers,
+                        std::vector<std::string>* domains, std::vector<std::string>* tlsServers,
+                        std::vector<int32_t>* params, std::vector<int32_t>* stats,
+                        std::vector<int32_t>* wait_for_pending_req_timeout_count);
+
+    void startPrefix64Discovery(int32_t netId);
+    void stopPrefix64Discovery(int32_t netId);
+
+    void dump(netdutils::DumpWriter& dw, unsigned netId);
+
+  private:
+    Dns64Configuration mDns64Configuration;
+};
+}  // namespace net
+}  // namespace android
+
+#endif /* _RESOLVER_CONTROLLER_H_ */
diff --git a/resolv/ResolverEventReporter.cpp b/resolv/ResolverEventReporter.cpp
new file mode 100644
index 0000000..ccec08b
--- /dev/null
+++ b/resolv/ResolverEventReporter.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "ResolverEventReporter"
+
+#include "ResolverEventReporter.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+using aidl::android::net::metrics::INetdEventListener;
+
+ResolverEventReporter& ResolverEventReporter::getInstance() {
+    // It should be initialized only once.
+    static ResolverEventReporter instance;
+
+    // Add framework metrics listener. Because the binder service "netd_listener" may be launched
+    // later than Netd, try to get binder handler in every instance query if any. The framework
+    // metrics listener should be added only once if it has been already added successfully.
+    instance.addDefaultListener();
+
+    return instance;
+}
+
+ResolverEventReporter::ListenerSet ResolverEventReporter::getListeners() const {
+    return getListenersImpl();
+}
+
+int ResolverEventReporter::addListener(const std::shared_ptr<INetdEventListener>& listener) {
+    return addListenerImpl(listener);
+}
+
+// TODO: Consider registering metrics listener from framework and remove this function.
+// Currently, the framework listener "netd_listener" is shared by netd and libnetd_resolv.
+// Consider breaking it into two listeners. Once it has done, may let framework register
+// the listener proactively.
+void ResolverEventReporter::addDefaultListener() {
+    std::lock_guard lock(mMutex);
+
+    static bool added = false;
+    if (added) return;
+
+    // Use the non-blocking call AServiceManager_checkService in order not to delay DNS
+    // lookup threads when the netd_listener service is not ready.
+    ndk::SpAIBinder binder = ndk::SpAIBinder(AServiceManager_checkService("netd_listener"));
+    std::shared_ptr<INetdEventListener> listener = INetdEventListener::fromBinder(binder);
+
+    if (listener == nullptr) return;
+
+    if (!addListenerImplLocked(listener)) added = true;
+}
+
+void ResolverEventReporter::handleBinderDied(const void* who) {
+    std::lock_guard lock(mMutex);
+
+    // Use the raw binder pointer address to be the identification of dead binder. Treat "who"
+    // which passes the raw address of dead binder as an identification only.
+    auto found = std::find_if(mListeners.begin(), mListeners.end(),
+                              [=](const auto& it) { return static_cast<void*>(it.get()) == who; });
+
+    if (found != mListeners.end()) mListeners.erase(found);
+}
+
+ResolverEventReporter::ListenerSet ResolverEventReporter::getListenersImpl() const {
+    std::lock_guard lock(mMutex);
+    return mListeners;
+}
+
+int ResolverEventReporter::addListenerImpl(const std::shared_ptr<INetdEventListener>& listener) {
+    std::lock_guard lock(mMutex);
+    return addListenerImplLocked(listener);
+}
+
+int ResolverEventReporter::addListenerImplLocked(
+        const std::shared_ptr<INetdEventListener>& listener) {
+    if (listener == nullptr) {
+        LOG(ERROR) << "The listener should not be null";
+        return -EINVAL;
+    }
+
+    // TODO: Perhaps ignore the listener which comes from the same binder.
+    const auto& it = mListeners.find(listener);
+    if (it != mListeners.end()) {
+        LOG(WARNING) << "The listener was already subscribed";
+        return -EEXIST;
+    }
+
+    static AIBinder_DeathRecipient* deathRecipient = nullptr;
+    if (deathRecipient == nullptr) {
+        // The AIBinder_DeathRecipient object is used to manage all death recipients for multiple
+        // binder objects. It doesn't released because there should have at least one binder object
+        // from framework.
+        // TODO: Considering to remove death recipient for the binder object from framework because
+        // it doesn't need death recipient actually.
+        deathRecipient = AIBinder_DeathRecipient_new([](void* cookie) {
+            ResolverEventReporter::getInstance().handleBinderDied(cookie);
+        });
+    }
+
+    // Pass the raw binder pointer address to be the cookie of the death recipient. While the death
+    // notification is fired, the cookie is used for identifying which binder was died. Because
+    // the NDK binder doesn't pass dead binder pointer to binder death handler, the binder death
+    // handler can't know who was died via wp<IBinder>. The reason for wp<IBinder> is not passed
+    // is that NDK binder can't transform a wp<IBinder> to a wp<AIBinder> in some cases.
+    // See more information in b/128712772.
+    auto binder = listener->asBinder().get();
+    auto cookie = static_cast<void*>(listener.get());  // Used for dead binder identification.
+    binder_status_t status = AIBinder_linkToDeath(binder, deathRecipient, cookie);
+
+    if (STATUS_OK != status) {
+        LOG(ERROR) << "Failed to register death notification for INetdEventListener";
+        return -EAGAIN;
+    }
+
+    mListeners.insert(listener);
+    return 0;
+}
\ No newline at end of file
diff --git a/resolv/ResolverEventReporter.h b/resolv/ResolverEventReporter.h
new file mode 100644
index 0000000..eb0d9cf
--- /dev/null
+++ b/resolv/ResolverEventReporter.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NETD_RESOLV_EVENT_REPORTER_H
+#define NETD_RESOLV_EVENT_REPORTER_H
+
+#include <set>
+
+#include <android-base/thread_annotations.h>
+
+#include "aidl/android/net/metrics/INetdEventListener.h"
+
+/*
+ * This class can be used to get the binder reference to the netd events listener service
+ * via stable runtime ABI which is achieved from libbinder_ndk. It also allows that
+ * register an event listener.
+ */
+class ResolverEventReporter {
+  public:
+    ResolverEventReporter(ResolverEventReporter const&) = delete;
+    ResolverEventReporter(ResolverEventReporter&&) = delete;
+    ResolverEventReporter& operator=(ResolverEventReporter const&) = delete;
+    ResolverEventReporter& operator=(ResolverEventReporter&&) = delete;
+
+    using ListenerSet = std::set<std::shared_ptr<aidl::android::net::metrics::INetdEventListener>>;
+
+    // Get the instance of the singleton ResolverEventReporter.
+    static ResolverEventReporter& getInstance();
+
+    // Return the binder from the singleton ResolverEventReporter. This method is threadsafe.
+    ListenerSet getListeners() const;
+
+    // Add the binder to the singleton ResolverEventReporter. This method is threadsafe.
+    int addListener(
+            const std::shared_ptr<aidl::android::net::metrics::INetdEventListener>& listener);
+
+  private:
+    ResolverEventReporter() = default;
+    ~ResolverEventReporter() = default;
+
+    void addDefaultListener() EXCLUDES(mMutex);
+    int addListenerImpl(
+            const std::shared_ptr<aidl::android::net::metrics::INetdEventListener>& listener)
+            EXCLUDES(mMutex);
+    int addListenerImplLocked(
+            const std::shared_ptr<aidl::android::net::metrics::INetdEventListener>& listener)
+            REQUIRES(mMutex);
+    ListenerSet getListenersImpl() const EXCLUDES(mMutex);
+    void handleBinderDied(const void* who) EXCLUDES(mMutex);
+
+    mutable std::mutex mMutex;
+    ListenerSet mListeners GUARDED_BY(mMutex);
+};
+
+#endif  // NETD_RESOLV_EVENT_REPORTER_H
diff --git a/resolv/ResolverStats.h b/resolv/ResolverStats.h
new file mode 100644
index 0000000..9140af8
--- /dev/null
+++ b/resolv/ResolverStats.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _RESOLVER_STATS_H_
+#define _RESOLVER_STATS_H_
+
+#include <time.h>
+
+namespace android {
+namespace net {
+
+struct ResolverStats {
+    // Offsets into the per-server resolver stats as encoded in vector<int32_t> stats of
+    // getResolverInfo() of Netd's binder interface. The stats are based on data reported by
+    // android_net_res_stats_get_info_for_net(), the usability is calculated by applying
+    // android_net_res_stats_get_usable_servers() to this data.
+    enum ResolverStatsOffsets {
+        STATS_SUCCESSES = 0,     // # successes counted for this server
+        STATS_ERRORS,            // # errors
+        STATS_TIMEOUTS,          // # timeouts
+        STATS_INTERNAL_ERRORS,   // # internal errors
+        STATS_RTT_AVG,           // average round-trip-time
+        STATS_LAST_SAMPLE_TIME,  // time in s when the last sample was recorded
+        STATS_USABLE,            // whether the server is considered usable
+        STATS_COUNT              // total count of integers in the per-server data
+    };
+
+    int successes{-1};
+    int errors{-1};
+    int timeouts{-1};
+    int internal_errors{-1};
+    int rtt_avg{-1};
+    time_t last_sample_time{0};
+    bool usable{false};
+
+    // Serialize the resolver stats to the end of |out|.
+    void encode(std::vector<int32_t>* out) const;
+
+    // Read the serialized resolverstats starting at |in[ofs]|.
+    ssize_t decode(const std::vector<int32_t>& in, ssize_t ofs);
+
+    // Serialize the contents of |stats| and append them to the end of |out|. Multiple arrays
+    // can be written to the same output vector in sequence, however, the corresponding call
+    // to decodeAll() will return the combined contents in one vector.
+    static void encodeAll(const std::vector<ResolverStats>& stats, std::vector<int32_t>* out);
+
+    // Decodes the serialized ResolverStats from |in| and appends them to stats.
+    static bool decodeAll(const std::vector<int32_t>& in, std::vector<ResolverStats>* stats);
+};
+
+inline void ResolverStats::encode(std::vector<int32_t>* out) const {
+    size_t ofs = out->size();
+    out->resize(ofs + STATS_COUNT);
+    int32_t* cur = &(*out)[ofs];
+    cur[STATS_SUCCESSES] = successes;
+    cur[STATS_ERRORS] = errors;
+    cur[STATS_TIMEOUTS] = timeouts;
+    cur[STATS_INTERNAL_ERRORS] = internal_errors;
+    cur[STATS_RTT_AVG] = rtt_avg;
+    cur[STATS_LAST_SAMPLE_TIME] = last_sample_time;
+    cur[STATS_USABLE] = usable;
+}
+
+// Read the serialized resolverstats starting at |in[ofs]|.
+inline ssize_t ResolverStats::decode(const std::vector<int32_t>& in, ssize_t ofs) {
+    if (ofs < 0 || static_cast<size_t>(ofs) + STATS_COUNT > in.size()) {
+        return -1;
+    }
+    const int32_t* cur = &in[ofs];
+    successes = cur[STATS_SUCCESSES];
+    errors = cur[STATS_ERRORS];
+    timeouts = cur[STATS_TIMEOUTS];
+    internal_errors = cur[STATS_INTERNAL_ERRORS];
+    rtt_avg = cur[STATS_RTT_AVG];
+    last_sample_time = cur[STATS_LAST_SAMPLE_TIME];
+    usable = cur[STATS_USABLE];
+    return ofs + STATS_COUNT;
+}
+
+inline void ResolverStats::encodeAll(const std::vector<ResolverStats>& stats,
+                                     std::vector<int32_t>* out) {
+    for (const auto& s : stats) {
+        s.encode(out);
+    }
+}
+
+// TODO: Replace with a better representation, e.g. a Parcelable.
+inline bool ResolverStats::decodeAll(const std::vector<int32_t>& in,
+                                     std::vector<ResolverStats>* stats) {
+    ssize_t size = in.size();
+    if (size % STATS_COUNT) {
+        return false;
+    }
+    stats->resize(size / STATS_COUNT);
+    ssize_t ofs = 0;
+    for (auto& s : *stats) {
+        ofs = s.decode(in, ofs);
+        if (ofs < 0) {
+            return false;
+        }
+    }
+    return true;
+}
+
+}  // namespace net
+}  // namespace android
+
+#endif /* _RESOLVER_STATS_H_ */
diff --git a/resolv/aidl/dnsresolver/1/android/net/IDnsResolver.aidl b/resolv/aidl/dnsresolver/1/android/net/IDnsResolver.aidl
new file mode 100644
index 0000000..c4b2b6d
--- /dev/null
+++ b/resolv/aidl/dnsresolver/1/android/net/IDnsResolver.aidl
@@ -0,0 +1,27 @@
+package android.net;
+interface IDnsResolver {
+  boolean isAlive();
+  void registerEventListener(android.net.metrics.INetdEventListener listener);
+  void setResolverConfiguration(in android.net.ResolverParamsParcel resolverParams);
+  void getResolverInfo(int netId, out @utf8InCpp String[] servers, out @utf8InCpp String[] domains, out @utf8InCpp String[] tlsServers, out int[] params, out int[] stats, out int[] wait_for_pending_req_timeout_count);
+  void startPrefix64Discovery(int netId);
+  void stopPrefix64Discovery(int netId);
+  @utf8InCpp String getPrefix64(int netId);
+  void createNetworkCache(int netId);
+  void destroyNetworkCache(int netId);
+  const int RESOLVER_PARAMS_SAMPLE_VALIDITY = 0;
+  const int RESOLVER_PARAMS_SUCCESS_THRESHOLD = 1;
+  const int RESOLVER_PARAMS_MIN_SAMPLES = 2;
+  const int RESOLVER_PARAMS_MAX_SAMPLES = 3;
+  const int RESOLVER_PARAMS_BASE_TIMEOUT_MSEC = 4;
+  const int RESOLVER_PARAMS_RETRY_COUNT = 5;
+  const int RESOLVER_PARAMS_COUNT = 6;
+  const int RESOLVER_STATS_SUCCESSES = 0;
+  const int RESOLVER_STATS_ERRORS = 1;
+  const int RESOLVER_STATS_TIMEOUTS = 2;
+  const int RESOLVER_STATS_INTERNAL_ERRORS = 3;
+  const int RESOLVER_STATS_RTT_AVG = 4;
+  const int RESOLVER_STATS_LAST_SAMPLE_TIME = 5;
+  const int RESOLVER_STATS_USABLE = 6;
+  const int RESOLVER_STATS_COUNT = 7;
+}
diff --git a/resolv/aidl/dnsresolver/1/android/net/ResolverParamsParcel.aidl b/resolv/aidl/dnsresolver/1/android/net/ResolverParamsParcel.aidl
new file mode 100644
index 0000000..b808bae
--- /dev/null
+++ b/resolv/aidl/dnsresolver/1/android/net/ResolverParamsParcel.aidl
@@ -0,0 +1,15 @@
+package android.net;
+parcelable ResolverParamsParcel {
+  int netId;
+  int sampleValiditySeconds;
+  int successThreshold;
+  int minSamples;
+  int maxSamples;
+  int baseTimeoutMsec;
+  int retryCount;
+  @utf8InCpp String[] servers;
+  @utf8InCpp String[] domains;
+  @utf8InCpp String tlsName;
+  @utf8InCpp String[] tlsServers;
+  @utf8InCpp String[] tlsFingerprints;
+}
diff --git a/resolv/aidl/dnsresolver/2/android/net/IDnsResolver.aidl b/resolv/aidl/dnsresolver/2/android/net/IDnsResolver.aidl
new file mode 100644
index 0000000..846bbec
--- /dev/null
+++ b/resolv/aidl/dnsresolver/2/android/net/IDnsResolver.aidl
@@ -0,0 +1,50 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+interface IDnsResolver {
+  boolean isAlive();
+  void registerEventListener(android.net.metrics.INetdEventListener listener);
+  void setResolverConfiguration(in android.net.ResolverParamsParcel resolverParams);
+  void getResolverInfo(int netId, out @utf8InCpp String[] servers, out @utf8InCpp String[] domains, out @utf8InCpp String[] tlsServers, out int[] params, out int[] stats, out int[] wait_for_pending_req_timeout_count);
+  void startPrefix64Discovery(int netId);
+  void stopPrefix64Discovery(int netId);
+  @utf8InCpp String getPrefix64(int netId);
+  void createNetworkCache(int netId);
+  void destroyNetworkCache(int netId);
+  void setLogSeverity(int logSeverity);
+  const int RESOLVER_PARAMS_SAMPLE_VALIDITY = 0;
+  const int RESOLVER_PARAMS_SUCCESS_THRESHOLD = 1;
+  const int RESOLVER_PARAMS_MIN_SAMPLES = 2;
+  const int RESOLVER_PARAMS_MAX_SAMPLES = 3;
+  const int RESOLVER_PARAMS_BASE_TIMEOUT_MSEC = 4;
+  const int RESOLVER_PARAMS_RETRY_COUNT = 5;
+  const int RESOLVER_PARAMS_COUNT = 6;
+  const int RESOLVER_STATS_SUCCESSES = 0;
+  const int RESOLVER_STATS_ERRORS = 1;
+  const int RESOLVER_STATS_TIMEOUTS = 2;
+  const int RESOLVER_STATS_INTERNAL_ERRORS = 3;
+  const int RESOLVER_STATS_RTT_AVG = 4;
+  const int RESOLVER_STATS_LAST_SAMPLE_TIME = 5;
+  const int RESOLVER_STATS_USABLE = 6;
+  const int RESOLVER_STATS_COUNT = 7;
+  const int DNS_RESOLVER_LOG_VERBOSE = 0;
+  const int DNS_RESOLVER_LOG_DEBUG = 1;
+  const int DNS_RESOLVER_LOG_INFO = 2;
+  const int DNS_RESOLVER_LOG_WARNING = 3;
+  const int DNS_RESOLVER_LOG_ERROR = 4;
+}
diff --git a/resolv/aidl/dnsresolver/2/android/net/ResolverParamsParcel.aidl b/resolv/aidl/dnsresolver/2/android/net/ResolverParamsParcel.aidl
new file mode 100644
index 0000000..a37f938
--- /dev/null
+++ b/resolv/aidl/dnsresolver/2/android/net/ResolverParamsParcel.aidl
@@ -0,0 +1,32 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable ResolverParamsParcel {
+  int netId;
+  int sampleValiditySeconds;
+  int successThreshold;
+  int minSamples;
+  int maxSamples;
+  int baseTimeoutMsec;
+  int retryCount;
+  @utf8InCpp String[] servers;
+  @utf8InCpp String[] domains;
+  @utf8InCpp String tlsName;
+  @utf8InCpp String[] tlsServers;
+  @utf8InCpp String[] tlsFingerprints;
+}
diff --git a/resolv/binder/android/net/IDnsResolver.aidl b/resolv/binder/android/net/IDnsResolver.aidl
new file mode 100644
index 0000000..f6f4092
--- /dev/null
+++ b/resolv/binder/android/net/IDnsResolver.aidl
@@ -0,0 +1,164 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.net.ResolverParamsParcel;
+import android.net.metrics.INetdEventListener;
+
+/** {@hide} */
+interface IDnsResolver {
+    /**
+     * Returns true if the service is responding.
+     */
+    boolean isAlive();
+
+   /**
+    * Register event listener
+    * DnsResolver supports multiple event listeners, but only one per unique address of the
+    * binder interface. A newer listener won't be registered if DnsResolver has an old one on
+    * the same address of the binder interface.
+    *
+    * @param listener event listener to register.
+    * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
+    *         unix errno.
+    */
+    void registerEventListener(INetdEventListener listener);
+
+    // TODO: Delete these from the public interface
+    // Array indices for resolver parameters.
+    const int RESOLVER_PARAMS_SAMPLE_VALIDITY = 0;
+    const int RESOLVER_PARAMS_SUCCESS_THRESHOLD = 1;
+    const int RESOLVER_PARAMS_MIN_SAMPLES = 2;
+    const int RESOLVER_PARAMS_MAX_SAMPLES = 3;
+    const int RESOLVER_PARAMS_BASE_TIMEOUT_MSEC = 4;
+    const int RESOLVER_PARAMS_RETRY_COUNT = 5;
+    const int RESOLVER_PARAMS_COUNT = 6;
+
+    /**
+     * Sets the name servers, search domains and resolver params for the given network. Flushes the
+     * cache as needed (i.e. when the servers or the number of samples to store changes).
+     *
+     * @param resolverParams the resolver parameters to be wrapped into parcel.
+     * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
+     *         unix errno.
+     */
+    void setResolverConfiguration(in ResolverParamsParcel resolverParams);
+
+    // Array indices for resolver stats.
+    const int RESOLVER_STATS_SUCCESSES = 0;
+    const int RESOLVER_STATS_ERRORS = 1;
+    const int RESOLVER_STATS_TIMEOUTS = 2;
+    const int RESOLVER_STATS_INTERNAL_ERRORS = 3;
+    const int RESOLVER_STATS_RTT_AVG = 4;
+    const int RESOLVER_STATS_LAST_SAMPLE_TIME = 5;
+    const int RESOLVER_STATS_USABLE = 6;
+    const int RESOLVER_STATS_COUNT = 7;
+
+    /**
+     * Retrieves the name servers, search domains and resolver stats associated with the given
+     * network ID.
+     *
+     * @param netId the network ID of the network for which information should be retrieved.
+     * @param servers the DNS servers that are currently configured for the network.
+     * @param domains the search domains currently configured.
+     * @param tlsServers the DNS-over-TLS servers that are currently configured for the network.
+     * @param params the resolver parameters configured, i.e. the contents of __res_params in order.
+     * @param stats the stats for each server in the order specified by RESOLVER_STATS_XXX
+     *         constants, serialized as an int array. The contents of this array are the number of
+     *         <ul>
+     *           <li> successes,
+     *           <li> errors,
+     *           <li> timeouts,
+     *           <li> internal errors,
+     *           <li> the RTT average,
+     *           <li> the time of the last recorded sample,
+     *           <li> and an integer indicating whether the server is usable (1) or broken (0).
+     *         </ul>
+     *         in this order. For example, the timeout counter for server N is stored at position
+     *         RESOLVER_STATS_COUNT*N + RESOLVER_STATS_TIMEOUTS
+     * @param wait_for_pending_req_timeout_count an internal counter used to count the number of
+     *        timeouts while resolver is handling concurrent DNS queries on the same hostname.
+     * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
+     *         unix errno.
+     *
+     * TODO: Consider replacing stats and params with parcelables.
+     */
+    void getResolverInfo(int netId, out @utf8InCpp String[] servers,
+            out @utf8InCpp String[] domains, out @utf8InCpp String[] tlsServers, out int[] params,
+            out int[] stats, out int[] wait_for_pending_req_timeout_count);
+
+    /**
+     * Starts NAT64 prefix discovery on the given network.
+     *
+     * @param netId the netId to start prefix discovery on.
+     */
+    void startPrefix64Discovery(int netId);
+
+    /**
+     * Stops NAT64 prefix discovery on the given network.
+     *
+     * @param netId the netId to stop prefix discovery on.
+     */
+    void stopPrefix64Discovery(int netId);
+
+    /**
+     * Get NAT64 prefix in format Pref64::/n which is described in RFC6147 section 2. This
+     * interface is used for internal test only. Don't use it for other purposes because doing so
+     * would cause race conditions with the NAT64 prefix notifications.
+     *
+     * @param netId the network ID of the network to get the prefix
+     * @return the NAT64 prefix if the query operation was successful
+     * @throws ServiceSpecificException in case of failure, with an error code indicating the
+     *         cause of the the failure.
+     *
+     * TODO: Remove this once the tests have been updated to listen for onNat64PrefixEvent.
+     */
+    @utf8InCpp String getPrefix64(int netId);
+
+    /**
+     * Create cache for the given network.
+     *
+     * @param netId the network ID of the network to create.
+     * @throws ServiceSpecificException in case of failure, with an error code indicating the
+     *         cause of the failure.
+     */
+    void createNetworkCache(int netId);
+
+    /**
+     * Destroy cache for the given network.
+     *
+     * @param netId the network ID of the network to destroy.
+     */
+    void destroyNetworkCache(int netId);
+
+    // Refer to enum LogSeverity from system/core/base/include/android-base/logging.h
+    const int DNS_RESOLVER_LOG_VERBOSE = 0;
+    const int DNS_RESOLVER_LOG_DEBUG = 1;
+    const int DNS_RESOLVER_LOG_INFO = 2;
+    const int DNS_RESOLVER_LOG_WARNING = 3;
+    const int DNS_RESOLVER_LOG_ERROR = 4;
+
+    /**
+     * Set DNS resolver log severity
+     *
+     * @param logSeverity print log in "VERBOSE", "DEBUG", "INFO", "WARNING", "ERROR".
+     *
+     * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
+     *         POSIX errno.
+     */
+    void setLogSeverity(int logSeverity);
+}
diff --git a/resolv/binder/android/net/ResolverParamsParcel.aidl b/resolv/binder/android/net/ResolverParamsParcel.aidl
new file mode 100644
index 0000000..d25880f
--- /dev/null
+++ b/resolv/binder/android/net/ResolverParamsParcel.aidl
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+/**
+ * Configuration for a resolver parameters.
+ *
+ * {@hide}
+ */
+parcelable ResolverParamsParcel {
+    /**
+     * The network ID of the network for which information should be configured.
+     */
+    int netId;
+
+    /**
+     * Sample lifetime in seconds.
+     */
+    int sampleValiditySeconds;
+
+    /**
+     * Use to judge if the server is considered broken.
+     */
+    int successThreshold;
+
+    /**
+     * Min. # samples.
+     */
+    int minSamples;
+
+    /**
+     * Max # samples.
+     */
+    int maxSamples;
+
+    /**
+     * Retransmission interval in milliseconds.
+     */
+    int baseTimeoutMsec;
+
+    /**
+     * Number of retries.
+     */
+    int retryCount;
+
+    /**
+     * The DNS servers to configure for the network.
+     */
+    @utf8InCpp String[] servers;
+
+    /**
+     * The search domains to configure.
+     */
+    @utf8InCpp String[] domains;
+
+    /**
+     * The TLS subject name to require for all servers, or empty if there is none.
+     */
+    @utf8InCpp String   tlsName;
+
+    /**
+     * The DNS servers to configure for strict mode Private DNS.
+     */
+    @utf8InCpp String[] tlsServers;
+
+    /**
+     * An array containing TLS public key fingerprints (pins) of which each server must match
+     * at least one, or empty if there are no pinned keys.
+     */
+    // DEPRECATED: remove tlsFingerprints in new code
+    @utf8InCpp String[] tlsFingerprints;
+}
diff --git a/resolv/dns_responder/Android.bp b/resolv/dns_responder/Android.bp
new file mode 100644
index 0000000..4c28c21
--- /dev/null
+++ b/resolv/dns_responder/Android.bp
@@ -0,0 +1,24 @@
+cc_library_static {
+    name: "libnetd_test_dnsresponder",
+    defaults: ["netd_defaults"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "liblog",
+        "libnetd_client",
+        "libnetdutils",
+        "libssl",
+        "dnsresolver_aidl_interface-V2-cpp",
+        "netd_aidl_interface-V2-cpp",
+    ],
+    static_libs: ["libutils"],
+    include_dirs: [
+        "system/netd/server",
+    ],
+    srcs: [
+        "dns_responder.cpp",
+        "dns_responder_client.cpp",
+        "dns_tls_frontend.cpp",
+    ],
+    export_include_dirs: ["."],
+}
diff --git a/resolv/dns_responder/dns_responder.cpp b/resolv/dns_responder/dns_responder.cpp
new file mode 100644
index 0000000..5047255
--- /dev/null
+++ b/resolv/dns_responder/dns_responder.cpp
@@ -0,0 +1,994 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dns_responder.h"
+
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <set>
+
+#include <iostream>
+#include <vector>
+
+#define LOG_TAG "DNSResponder"
+#include <android-base/strings.h>
+#include <log/log.h>
+#include <netdutils/SocketOption.h>
+
+#include "NetdConstants.h"
+
+using android::netdutils::enableSockopt;
+
+namespace test {
+
+std::string errno2str() {
+    char error_msg[512] = { 0 };
+    // It actually calls __gnu_strerror_r() which returns the type |char*| rather than |int|.
+    // PLOG is an option though it requires lots of changes from ALOGx() to LOG(x).
+    return strerror_r(errno, error_msg, sizeof(error_msg));
+}
+
+#define APLOGI(fmt, ...) ALOGI(fmt ": [%d] %s", __VA_ARGS__, errno, errno2str().c_str())
+
+#if 0
+#define DBGLOG(fmt, ...) ALOGI(fmt, __VA_ARGS__)
+#else
+#define DBGLOG(fmt, ...)
+#endif
+
+std::string str2hex(const char* buffer, size_t len) {
+    std::string str(len*2, '\0');
+    for (size_t i = 0 ; i < len ; ++i) {
+        static const char* hex = "0123456789ABCDEF";
+        uint8_t c = buffer[i];
+        str[i*2] = hex[c >> 4];
+        str[i*2 + 1] = hex[c & 0x0F];
+    }
+    return str;
+}
+
+std::string addr2str(const sockaddr* sa, socklen_t sa_len) {
+    char host_str[NI_MAXHOST] = { 0 };
+    int rv = getnameinfo(sa, sa_len, host_str, sizeof(host_str), nullptr, 0,
+                         NI_NUMERICHOST);
+    if (rv == 0) return std::string(host_str);
+    return std::string();
+}
+
+/* DNS struct helpers */
+
+const char* dnstype2str(unsigned dnstype) {
+    static std::unordered_map<unsigned, const char*> kTypeStrs = {
+        { ns_type::ns_t_a, "A" },
+        { ns_type::ns_t_ns, "NS" },
+        { ns_type::ns_t_md, "MD" },
+        { ns_type::ns_t_mf, "MF" },
+        { ns_type::ns_t_cname, "CNAME" },
+        { ns_type::ns_t_soa, "SOA" },
+        { ns_type::ns_t_mb, "MB" },
+        { ns_type::ns_t_mb, "MG" },
+        { ns_type::ns_t_mr, "MR" },
+        { ns_type::ns_t_null, "NULL" },
+        { ns_type::ns_t_wks, "WKS" },
+        { ns_type::ns_t_ptr, "PTR" },
+        { ns_type::ns_t_hinfo, "HINFO" },
+        { ns_type::ns_t_minfo, "MINFO" },
+        { ns_type::ns_t_mx, "MX" },
+        { ns_type::ns_t_txt, "TXT" },
+        { ns_type::ns_t_rp, "RP" },
+        { ns_type::ns_t_afsdb, "AFSDB" },
+        { ns_type::ns_t_x25, "X25" },
+        { ns_type::ns_t_isdn, "ISDN" },
+        { ns_type::ns_t_rt, "RT" },
+        { ns_type::ns_t_nsap, "NSAP" },
+        { ns_type::ns_t_nsap_ptr, "NSAP-PTR" },
+        { ns_type::ns_t_sig, "SIG" },
+        { ns_type::ns_t_key, "KEY" },
+        { ns_type::ns_t_px, "PX" },
+        { ns_type::ns_t_gpos, "GPOS" },
+        { ns_type::ns_t_aaaa, "AAAA" },
+        { ns_type::ns_t_loc, "LOC" },
+        { ns_type::ns_t_nxt, "NXT" },
+        { ns_type::ns_t_eid, "EID" },
+        { ns_type::ns_t_nimloc, "NIMLOC" },
+        { ns_type::ns_t_srv, "SRV" },
+        { ns_type::ns_t_naptr, "NAPTR" },
+        { ns_type::ns_t_kx, "KX" },
+        { ns_type::ns_t_cert, "CERT" },
+        { ns_type::ns_t_a6, "A6" },
+        { ns_type::ns_t_dname, "DNAME" },
+        { ns_type::ns_t_sink, "SINK" },
+        { ns_type::ns_t_opt, "OPT" },
+        { ns_type::ns_t_apl, "APL" },
+        { ns_type::ns_t_tkey, "TKEY" },
+        { ns_type::ns_t_tsig, "TSIG" },
+        { ns_type::ns_t_ixfr, "IXFR" },
+        { ns_type::ns_t_axfr, "AXFR" },
+        { ns_type::ns_t_mailb, "MAILB" },
+        { ns_type::ns_t_maila, "MAILA" },
+        { ns_type::ns_t_any, "ANY" },
+        { ns_type::ns_t_zxfr, "ZXFR" },
+    };
+    auto it = kTypeStrs.find(dnstype);
+    static const char* kUnknownStr{ "UNKNOWN" };
+    if (it == kTypeStrs.end()) return kUnknownStr;
+    return it->second;
+}
+
+const char* dnsclass2str(unsigned dnsclass) {
+    static std::unordered_map<unsigned, const char*> kClassStrs = {
+        { ns_class::ns_c_in , "Internet" },
+        { 2, "CSNet" },
+        { ns_class::ns_c_chaos, "ChaosNet" },
+        { ns_class::ns_c_hs, "Hesiod" },
+        { ns_class::ns_c_none, "none" },
+        { ns_class::ns_c_any, "any" }
+    };
+    auto it = kClassStrs.find(dnsclass);
+    static const char* kUnknownStr{ "UNKNOWN" };
+    if (it == kClassStrs.end()) return kUnknownStr;
+    return it->second;
+}
+
+struct DNSName {
+    std::string name;
+    const char* read(const char* buffer, const char* buffer_end);
+    char* write(char* buffer, const char* buffer_end) const;
+    const char* toString() const;
+private:
+    const char* parseField(const char* buffer, const char* buffer_end,
+                           bool* last);
+};
+
+const char* DNSName::toString() const {
+    return name.c_str();
+}
+
+const char* DNSName::read(const char* buffer, const char* buffer_end) {
+    const char* cur = buffer;
+    bool last = false;
+    do {
+        cur = parseField(cur, buffer_end, &last);
+        if (cur == nullptr) {
+            ALOGI("parsing failed at line %d", __LINE__);
+            return nullptr;
+        }
+    } while (!last);
+    return cur;
+}
+
+char* DNSName::write(char* buffer, const char* buffer_end) const {
+    char* buffer_cur = buffer;
+    for (size_t pos = 0 ; pos < name.size() ; ) {
+        size_t dot_pos = name.find('.', pos);
+        if (dot_pos == std::string::npos) {
+            // Sanity check, should never happen unless parseField is broken.
+            ALOGI("logic error: all names are expected to end with a '.'");
+            return nullptr;
+        }
+        size_t len = dot_pos - pos;
+        if (len >= 256) {
+            ALOGI("name component '%s' is %zu long, but max is 255",
+                    name.substr(pos, dot_pos - pos).c_str(), len);
+            return nullptr;
+        }
+        if (buffer_cur + sizeof(uint8_t) + len > buffer_end) {
+            ALOGI("buffer overflow at line %d", __LINE__);
+            return nullptr;
+        }
+        *buffer_cur++ = len;
+        buffer_cur = std::copy(std::next(name.begin(), pos),
+                               std::next(name.begin(), dot_pos),
+                               buffer_cur);
+        pos = dot_pos + 1;
+    }
+    // Write final zero.
+    *buffer_cur++ = 0;
+    return buffer_cur;
+}
+
+const char* DNSName::parseField(const char* buffer, const char* buffer_end,
+                                bool* last) {
+    if (buffer + sizeof(uint8_t) > buffer_end) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    unsigned field_type = *buffer >> 6;
+    unsigned ofs = *buffer & 0x3F;
+    const char* cur = buffer + sizeof(uint8_t);
+    if (field_type == 0) {
+        // length + name component
+        if (ofs == 0) {
+            *last = true;
+            return cur;
+        }
+        if (cur + ofs > buffer_end) {
+            ALOGI("parsing failed at line %d", __LINE__);
+            return nullptr;
+        }
+        name.append(cur, ofs);
+        name.push_back('.');
+        return cur + ofs;
+    } else if (field_type == 3) {
+        ALOGI("name compression not implemented");
+        return nullptr;
+    }
+    ALOGI("invalid name field type");
+    return nullptr;
+}
+
+struct DNSQuestion {
+    DNSName qname;
+    unsigned qtype;
+    unsigned qclass;
+    const char* read(const char* buffer, const char* buffer_end);
+    char* write(char* buffer, const char* buffer_end) const;
+    std::string toString() const;
+};
+
+const char* DNSQuestion::read(const char* buffer, const char* buffer_end) {
+    const char* cur = qname.read(buffer, buffer_end);
+    if (cur == nullptr) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    if (cur + 2*sizeof(uint16_t) > buffer_end) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    qtype = ntohs(*reinterpret_cast<const uint16_t*>(cur));
+    qclass = ntohs(*reinterpret_cast<const uint16_t*>(cur + sizeof(uint16_t)));
+    return cur + 2*sizeof(uint16_t);
+}
+
+char* DNSQuestion::write(char* buffer, const char* buffer_end) const {
+    char* buffer_cur = qname.write(buffer, buffer_end);
+    if (buffer_cur == nullptr) return nullptr;
+    if (buffer_cur + 2*sizeof(uint16_t) > buffer_end) {
+        ALOGI("buffer overflow on line %d", __LINE__);
+        return nullptr;
+    }
+    *reinterpret_cast<uint16_t*>(buffer_cur) = htons(qtype);
+    *reinterpret_cast<uint16_t*>(buffer_cur + sizeof(uint16_t)) =
+            htons(qclass);
+    return buffer_cur + 2*sizeof(uint16_t);
+}
+
+std::string DNSQuestion::toString() const {
+    char buffer[4096];
+    int len = snprintf(buffer, sizeof(buffer), "Q<%s,%s,%s>", qname.toString(),
+                       dnstype2str(qtype), dnsclass2str(qclass));
+    return std::string(buffer, len);
+}
+
+struct DNSRecord {
+    DNSName name;
+    unsigned rtype;
+    unsigned rclass;
+    unsigned ttl;
+    std::vector<char> rdata;
+    const char* read(const char* buffer, const char* buffer_end);
+    char* write(char* buffer, const char* buffer_end) const;
+    std::string toString() const;
+private:
+    struct IntFields {
+        uint16_t rtype;
+        uint16_t rclass;
+        uint32_t ttl;
+        uint16_t rdlen;
+    } __attribute__((__packed__));
+
+    const char* readIntFields(const char* buffer, const char* buffer_end,
+            unsigned* rdlen);
+    char* writeIntFields(unsigned rdlen, char* buffer,
+                         const char* buffer_end) const;
+};
+
+const char* DNSRecord::read(const char* buffer, const char* buffer_end) {
+    const char* cur = name.read(buffer, buffer_end);
+    if (cur == nullptr) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    unsigned rdlen = 0;
+    cur = readIntFields(cur, buffer_end, &rdlen);
+    if (cur == nullptr) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    if (cur + rdlen > buffer_end) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    rdata.assign(cur, cur + rdlen);
+    return cur + rdlen;
+}
+
+char* DNSRecord::write(char* buffer, const char* buffer_end) const {
+    char* buffer_cur = name.write(buffer, buffer_end);
+    if (buffer_cur == nullptr) return nullptr;
+    buffer_cur = writeIntFields(rdata.size(), buffer_cur, buffer_end);
+    if (buffer_cur == nullptr) return nullptr;
+    if (buffer_cur + rdata.size() > buffer_end) {
+        ALOGI("buffer overflow on line %d", __LINE__);
+        return nullptr;
+    }
+    return std::copy(rdata.begin(), rdata.end(), buffer_cur);
+}
+
+std::string DNSRecord::toString() const {
+    char buffer[4096];
+    int len = snprintf(buffer, sizeof(buffer), "R<%s,%s,%s>", name.toString(),
+                       dnstype2str(rtype), dnsclass2str(rclass));
+    return std::string(buffer, len);
+}
+
+const char* DNSRecord::readIntFields(const char* buffer, const char* buffer_end,
+                                     unsigned* rdlen) {
+    if (buffer + sizeof(IntFields) > buffer_end ) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    const auto& intfields = *reinterpret_cast<const IntFields*>(buffer);
+    rtype = ntohs(intfields.rtype);
+    rclass = ntohs(intfields.rclass);
+    ttl = ntohl(intfields.ttl);
+    *rdlen = ntohs(intfields.rdlen);
+    return buffer + sizeof(IntFields);
+}
+
+char* DNSRecord::writeIntFields(unsigned rdlen, char* buffer,
+                                const char* buffer_end) const {
+    if (buffer + sizeof(IntFields) > buffer_end ) {
+        ALOGI("buffer overflow on line %d", __LINE__);
+        return nullptr;
+    }
+    auto& intfields = *reinterpret_cast<IntFields*>(buffer);
+    intfields.rtype = htons(rtype);
+    intfields.rclass = htons(rclass);
+    intfields.ttl = htonl(ttl);
+    intfields.rdlen = htons(rdlen);
+    return buffer + sizeof(IntFields);
+}
+
+struct DNSHeader {
+    unsigned id;
+    bool ra;
+    uint8_t rcode;
+    bool qr;
+    uint8_t opcode;
+    bool aa;
+    bool tr;
+    bool rd;
+    bool ad;
+    std::vector<DNSQuestion> questions;
+    std::vector<DNSRecord> answers;
+    std::vector<DNSRecord> authorities;
+    std::vector<DNSRecord> additionals;
+    const char* read(const char* buffer, const char* buffer_end);
+    char* write(char* buffer, const char* buffer_end) const;
+    std::string toString() const;
+
+private:
+    struct Header {
+        uint16_t id;
+        uint8_t flags0;
+        uint8_t flags1;
+        uint16_t qdcount;
+        uint16_t ancount;
+        uint16_t nscount;
+        uint16_t arcount;
+    } __attribute__((__packed__));
+
+    const char* readHeader(const char* buffer, const char* buffer_end,
+                           unsigned* qdcount, unsigned* ancount,
+                           unsigned* nscount, unsigned* arcount);
+};
+
+const char* DNSHeader::read(const char* buffer, const char* buffer_end) {
+    unsigned qdcount;
+    unsigned ancount;
+    unsigned nscount;
+    unsigned arcount;
+    const char* cur = readHeader(buffer, buffer_end, &qdcount, &ancount,
+                                 &nscount, &arcount);
+    if (cur == nullptr) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    if (qdcount) {
+        questions.resize(qdcount);
+        for (unsigned i = 0 ; i < qdcount ; ++i) {
+            cur = questions[i].read(cur, buffer_end);
+            if (cur == nullptr) {
+                ALOGI("parsing failed at line %d", __LINE__);
+                return nullptr;
+            }
+        }
+    }
+    if (ancount) {
+        answers.resize(ancount);
+        for (unsigned i = 0 ; i < ancount ; ++i) {
+            cur = answers[i].read(cur, buffer_end);
+            if (cur == nullptr) {
+                ALOGI("parsing failed at line %d", __LINE__);
+                return nullptr;
+            }
+        }
+    }
+    if (nscount) {
+        authorities.resize(nscount);
+        for (unsigned i = 0 ; i < nscount ; ++i) {
+            cur = authorities[i].read(cur, buffer_end);
+            if (cur == nullptr) {
+                ALOGI("parsing failed at line %d", __LINE__);
+                return nullptr;
+            }
+        }
+    }
+    if (arcount) {
+        additionals.resize(arcount);
+        for (unsigned i = 0 ; i < arcount ; ++i) {
+            cur = additionals[i].read(cur, buffer_end);
+            if (cur == nullptr) {
+                ALOGI("parsing failed at line %d", __LINE__);
+                return nullptr;
+            }
+        }
+    }
+    return cur;
+}
+
+char* DNSHeader::write(char* buffer, const char* buffer_end) const {
+    if (buffer + sizeof(Header) > buffer_end) {
+        ALOGI("buffer overflow on line %d", __LINE__);
+        return nullptr;
+    }
+    Header& header = *reinterpret_cast<Header*>(buffer);
+    // bytes 0-1
+    header.id = htons(id);
+    // byte 2: 7:qr, 3-6:opcode, 2:aa, 1:tr, 0:rd
+    header.flags0 = (qr << 7) | (opcode << 3) | (aa << 2) | (tr << 1) | rd;
+    // byte 3: 7:ra, 6:zero, 5:ad, 4:cd, 0-3:rcode
+    // Fake behavior: if the query set the "ad" bit, set it in the response too.
+    // In a real server, this should be set only if the data is authentic and the
+    // query contained an "ad" bit or DNSSEC extensions.
+    header.flags1 = (ad << 5) | rcode;
+    // rest of header
+    header.qdcount = htons(questions.size());
+    header.ancount = htons(answers.size());
+    header.nscount = htons(authorities.size());
+    header.arcount = htons(additionals.size());
+    char* buffer_cur = buffer + sizeof(Header);
+    for (const DNSQuestion& question : questions) {
+        buffer_cur = question.write(buffer_cur, buffer_end);
+        if (buffer_cur == nullptr) return nullptr;
+    }
+    for (const DNSRecord& answer : answers) {
+        buffer_cur = answer.write(buffer_cur, buffer_end);
+        if (buffer_cur == nullptr) return nullptr;
+    }
+    for (const DNSRecord& authority : authorities) {
+        buffer_cur = authority.write(buffer_cur, buffer_end);
+        if (buffer_cur == nullptr) return nullptr;
+    }
+    for (const DNSRecord& additional : additionals) {
+        buffer_cur = additional.write(buffer_cur, buffer_end);
+        if (buffer_cur == nullptr) return nullptr;
+    }
+    return buffer_cur;
+}
+
+std::string DNSHeader::toString() const {
+    // TODO
+    return std::string();
+}
+
+const char* DNSHeader::readHeader(const char* buffer, const char* buffer_end,
+                                  unsigned* qdcount, unsigned* ancount,
+                                  unsigned* nscount, unsigned* arcount) {
+    if (buffer + sizeof(Header) > buffer_end)
+        return nullptr;
+    const auto& header = *reinterpret_cast<const Header*>(buffer);
+    // bytes 0-1
+    id = ntohs(header.id);
+    // byte 2: 7:qr, 3-6:opcode, 2:aa, 1:tr, 0:rd
+    qr = header.flags0 >> 7;
+    opcode = (header.flags0 >> 3) & 0x0F;
+    aa = (header.flags0 >> 2) & 1;
+    tr = (header.flags0 >> 1) & 1;
+    rd = header.flags0 & 1;
+    // byte 3: 7:ra, 6:zero, 5:ad, 4:cd, 0-3:rcode
+    ra = header.flags1 >> 7;
+    ad = (header.flags1 >> 5) & 1;
+    rcode = header.flags1 & 0xF;
+    // rest of header
+    *qdcount = ntohs(header.qdcount);
+    *ancount = ntohs(header.ancount);
+    *nscount = ntohs(header.nscount);
+    *arcount = ntohs(header.arcount);
+    return buffer + sizeof(Header);
+}
+
+/* DNS responder */
+
+DNSResponder::DNSResponder(std::string listen_address, std::string listen_service,
+                           int poll_timeout_ms, ns_rcode error_rcode)
+    : listen_address_(std::move(listen_address)),
+      listen_service_(std::move(listen_service)),
+      poll_timeout_ms_(poll_timeout_ms),
+      error_rcode_(error_rcode) {}
+
+DNSResponder::~DNSResponder() {
+    stopServer();
+}
+
+void DNSResponder::addMapping(const std::string& name, ns_type type, const std::string& addr) {
+    std::lock_guard lock(mappings_mutex_);
+    auto it = mappings_.find(QueryKey(name, type));
+    if (it != mappings_.end()) {
+        ALOGI("Overwriting mapping for (%s, %s), previous address %s, new "
+              "address %s",
+              name.c_str(), dnstype2str(type), it->second.c_str(), addr.c_str());
+        it->second = addr;
+        return;
+    }
+    mappings_.try_emplace({name, type}, addr);
+}
+
+void DNSResponder::removeMapping(const std::string& name, ns_type type) {
+    std::lock_guard lock(mappings_mutex_);
+    auto it = mappings_.find(QueryKey(name, type));
+    if (it != mappings_.end()) {
+        ALOGI("Cannot remove mapping mapping from (%s, %s), not present", name.c_str(),
+              dnstype2str(type));
+        return;
+    }
+    mappings_.erase(it);
+}
+
+void DNSResponder::setResponseProbability(double response_probability) {
+    response_probability_ = response_probability;
+}
+
+void DNSResponder::setEdns(Edns edns) {
+    edns_ = edns;
+}
+
+bool DNSResponder::running() const {
+    return socket_.get() != -1;
+}
+
+bool DNSResponder::startServer() {
+    if (running()) {
+        ALOGI("server already running");
+        return false;
+    }
+
+    // Set up UDP socket.
+    addrinfo ai_hints{
+        .ai_family = AF_UNSPEC,
+        .ai_socktype = SOCK_DGRAM,
+        .ai_flags = AI_PASSIVE
+    };
+    addrinfo* ai_res = nullptr;
+    int rv = getaddrinfo(listen_address_.c_str(), listen_service_.c_str(),
+                         &ai_hints, &ai_res);
+    ScopedAddrinfo ai_res_cleanup(ai_res);
+    if (rv) {
+        ALOGI("getaddrinfo(%s, %s) failed: %s", listen_address_.c_str(),
+            listen_service_.c_str(), gai_strerror(rv));
+        return false;
+    }
+    for (const addrinfo* ai = ai_res ; ai ; ai = ai->ai_next) {
+        socket_.reset(socket(ai->ai_family, ai->ai_socktype | SOCK_NONBLOCK, ai->ai_protocol));
+        if (socket_.get() < 0) {
+            APLOGI("ignore creating socket %d failed", socket_.get());
+            continue;
+        }
+        enableSockopt(socket_.get(), SOL_SOCKET, SO_REUSEPORT).ignoreError();
+        enableSockopt(socket_.get(), SOL_SOCKET, SO_REUSEADDR).ignoreError();
+        std::string host_str = addr2str(ai->ai_addr, ai->ai_addrlen);
+        if (bind(socket_.get(), ai->ai_addr, ai->ai_addrlen)) {
+            APLOGI("failed to bind UDP %s:%s", host_str.c_str(), listen_service_.c_str());
+            continue;
+        }
+        ALOGI("bound to UDP %s:%s", host_str.c_str(), listen_service_.c_str());
+        break;
+    }
+
+    // Set up eventfd socket.
+    event_fd_.reset(eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC));
+    if (event_fd_.get() == -1) {
+        APLOGI("failed to create eventfd %d", event_fd_.get());
+        return false;
+    }
+
+    // Set up epoll socket.
+    epoll_fd_.reset(epoll_create1(EPOLL_CLOEXEC));
+    if (epoll_fd_.get() < 0) {
+        APLOGI("epoll_create1() failed on fd %d", epoll_fd_.get());
+        return false;
+    }
+
+    ALOGI("adding socket %d to epoll", socket_.get());
+    if (!addFd(socket_.get(), EPOLLIN)) {
+        ALOGE("failed to add the socket %d to epoll", socket_.get());
+        return false;
+    }
+    ALOGI("adding eventfd %d to epoll", event_fd_.get());
+    if (!addFd(event_fd_.get(), EPOLLIN)) {
+        ALOGE("failed to add the eventfd %d to epoll", event_fd_.get());
+        return false;
+    }
+
+    {
+        std::lock_guard lock(update_mutex_);
+        handler_thread_ = std::thread(&DNSResponder::requestHandler, this);
+    }
+    ALOGI("server started successfully");
+    return true;
+}
+
+bool DNSResponder::stopServer() {
+    std::lock_guard lock(update_mutex_);
+    if (!running()) {
+        ALOGI("server not running");
+        return false;
+    }
+    ALOGI("stopping server");
+    if (!sendToEventFd()) {
+        return false;
+    }
+    handler_thread_.join();
+    epoll_fd_.reset();
+    socket_.reset();
+    ALOGI("server stopped successfully");
+    return true;
+}
+
+std::vector<std::pair<std::string, ns_type >> DNSResponder::queries() const {
+    std::lock_guard lock(queries_mutex_);
+    return queries_;
+}
+
+std::string DNSResponder::dumpQueries() const {
+    std::lock_guard lock(queries_mutex_);
+    std::string out;
+    for (const auto& q : queries_) {
+        out += "{\"" + q.first + "\", " + std::to_string(q.second) + "} ";
+    }
+    return out;
+}
+
+void DNSResponder::clearQueries() {
+    std::lock_guard lock(queries_mutex_);
+    queries_.clear();
+}
+
+void DNSResponder::requestHandler() {
+    epoll_event evs[EPOLL_MAX_EVENTS];
+    while (true) {
+        int n = epoll_wait(epoll_fd_.get(), evs, EPOLL_MAX_EVENTS, poll_timeout_ms_);
+        if (n == 0) continue;
+        if (n < 0) {
+            APLOGI("epoll_wait() failed, n=%d", n);
+            return;
+        }
+
+        for (int i = 0; i < n; i++) {
+            const int fd = evs[i].data.fd;
+            const uint32_t events = evs[i].events;
+            if (fd == event_fd_.get() && (events & (EPOLLIN | EPOLLERR))) {
+                handleEventFd();
+                return;
+            } else if (fd == socket_.get() && (events & (EPOLLIN | EPOLLERR))) {
+                handleQuery();
+            } else {
+                ALOGW("unexpected epoll events 0x%x on fd %d", events, fd);
+            }
+        }
+    }
+}
+
+bool DNSResponder::handleDNSRequest(const char* buffer, ssize_t len,
+                                    char* response, size_t* response_len)
+                                    const {
+    DBGLOG("request: '%s'", str2hex(buffer, len).c_str());
+    const char* buffer_end = buffer + len;
+    DNSHeader header;
+    const char* cur = header.read(buffer, buffer_end);
+    // TODO(imaipi): for now, unparsable messages are silently dropped, fix.
+    if (cur == nullptr) {
+        ALOGI("failed to parse query");
+        return false;
+    }
+    if (header.qr) {
+        ALOGI("response received instead of a query");
+        return false;
+    }
+    if (header.opcode != ns_opcode::ns_o_query) {
+        ALOGI("unsupported request opcode received");
+        return makeErrorResponse(&header, ns_rcode::ns_r_notimpl, response,
+                                 response_len);
+    }
+    if (header.questions.empty()) {
+        ALOGI("no questions present");
+        return makeErrorResponse(&header, ns_rcode::ns_r_formerr, response,
+                                 response_len);
+    }
+    if (!header.answers.empty()) {
+        ALOGI("already %zu answers present in query", header.answers.size());
+        return makeErrorResponse(&header, ns_rcode::ns_r_formerr, response,
+                                 response_len);
+    }
+
+    if (edns_ == Edns::FORMERR_UNCOND) {
+        ALOGI("force to return RCODE FORMERR");
+        return makeErrorResponse(&header, ns_rcode::ns_r_formerr, response, response_len);
+    }
+
+    if (!header.additionals.empty() && edns_ != Edns::ON) {
+        ALOGI("DNS request has an additional section (assumed EDNS). "
+              "Simulating an ancient (pre-EDNS) server, and returning %s",
+              edns_ == Edns::FORMERR_ON_EDNS ? "RCODE FORMERR." : "no response.");
+        if (edns_ == Edns::FORMERR_ON_EDNS) {
+            return makeErrorResponse(&header, ns_rcode::ns_r_formerr, response, response_len);
+        }
+        // No response.
+        return false;
+    }
+    {
+        std::lock_guard lock(queries_mutex_);
+        for (const DNSQuestion& question : header.questions) {
+            queries_.push_back(make_pair(question.qname.name,
+                                         ns_type(question.qtype)));
+        }
+    }
+
+    // Ignore requests with the preset probability.
+    auto constexpr bound = std::numeric_limits<unsigned>::max();
+    if (arc4random_uniform(bound) > bound * response_probability_) {
+        if (error_rcode_ < 0) {
+            ALOGI("Returning no response");
+            return false;
+        } else {
+            ALOGI("returning RCODE %d in accordance with probability distribution",
+                  static_cast<int>(error_rcode_));
+            return makeErrorResponse(&header, error_rcode_, response, response_len);
+        }
+    }
+
+    for (const DNSQuestion& question : header.questions) {
+        if (question.qclass != ns_class::ns_c_in &&
+            question.qclass != ns_class::ns_c_any) {
+            ALOGI("unsupported question class %u", question.qclass);
+            return makeErrorResponse(&header, ns_rcode::ns_r_notimpl, response,
+                                     response_len);
+        }
+
+        if (!addAnswerRecords(question, &header.answers)) {
+            return makeErrorResponse(&header, ns_rcode::ns_r_servfail, response, response_len);
+        }
+    }
+
+    header.qr = true;
+    char* response_cur = header.write(response, response + *response_len);
+    if (response_cur == nullptr) {
+        return false;
+    }
+    *response_len = response_cur - response;
+    return true;
+}
+
+bool DNSResponder::addAnswerRecords(const DNSQuestion& question,
+                                    std::vector<DNSRecord>* answers) const {
+    std::lock_guard guard(mappings_mutex_);
+    std::string rname = question.qname.name;
+    std::vector<int> rtypes;
+
+    if (question.qtype == ns_type::ns_t_a || question.qtype == ns_type::ns_t_aaaa)
+        rtypes.push_back(ns_type::ns_t_cname);
+    rtypes.push_back(question.qtype);
+    for (int rtype : rtypes) {
+        std::set<std::string> cnames_Loop;
+        std::unordered_map<QueryKey, std::string, QueryKeyHash>::const_iterator it;
+        while ((it = mappings_.find(QueryKey(rname, rtype))) != mappings_.end()) {
+            if (rtype == ns_type::ns_t_cname) {
+                // When detect CNAME infinite loops by cnames_Loop, it won't save the duplicate one.
+                // As following, the query will stop on loop3 by detecting the same cname.
+                // loop1.{"a.xxx.com", ns_type::ns_t_cname, "b.xxx.com"}(insert in answer record)
+                // loop2.{"b.xxx.com", ns_type::ns_t_cname, "a.xxx.com"}(insert in answer record)
+                // loop3.{"a.xxx.com", ns_type::ns_t_cname, "b.xxx.com"}(When the same cname record
+                //   is found in cnames_Loop already, break the query loop.)
+                if (cnames_Loop.find(it->first.name) != cnames_Loop.end()) break;
+                cnames_Loop.insert(it->first.name);
+            }
+            DNSRecord record{
+                    .name = {.name = it->first.name},
+                    .rtype = it->first.type,
+                    .rclass = ns_class::ns_c_in,
+                    .ttl = 5,  // seconds
+            };
+            fillAnswerRdata(it->second, record);
+            answers->push_back(std::move(record));
+            if (rtype != ns_type::ns_t_cname) break;
+            rname = it->second;
+        }
+    }
+
+    if (answers->size() == 0) {
+        // TODO(imaipi): handle correctly
+        ALOGI("no mapping found for %s %s, lazily refusing to add an answer",
+              question.qname.name.c_str(), dnstype2str(question.qtype));
+    }
+
+    return true;
+}
+
+bool DNSResponder::fillAnswerRdata(const std::string& rdatastr, DNSRecord& record) const {
+    if (record.rtype == ns_type::ns_t_a) {
+        record.rdata.resize(4);
+        if (inet_pton(AF_INET, rdatastr.c_str(), record.rdata.data()) != 1) {
+            ALOGI("inet_pton(AF_INET, %s) failed", rdatastr.c_str());
+            return false;
+        }
+    } else if (record.rtype == ns_type::ns_t_aaaa) {
+        record.rdata.resize(16);
+        if (inet_pton(AF_INET6, rdatastr.c_str(), record.rdata.data()) != 1) {
+            ALOGI("inet_pton(AF_INET6, %s) failed", rdatastr.c_str());
+            return false;
+        }
+    } else if ((record.rtype == ns_type::ns_t_ptr) || (record.rtype == ns_type::ns_t_cname)) {
+        constexpr char delimiter = '.';
+        std::string name = rdatastr;
+        std::vector<char> rdata;
+
+        // Generating PTRDNAME field(section 3.3.12) or CNAME field(section 3.3.1) in rfc1035.
+        // The "name" should be an absolute domain name which ends in a dot.
+        if (name.back() != delimiter) {
+            ALOGI("invalid absolute domain name");
+            return false;
+        }
+        name.pop_back();  // remove the dot in tail
+        for (const std::string& label : android::base::Split(name, {delimiter})) {
+            // The length of label is limited to 63 octets or less. See RFC 1035 section 3.1.
+            if (label.length() == 0 || label.length() > 63) {
+                ALOGI("invalid label length");
+                return false;
+            }
+
+            rdata.push_back(label.length());
+            rdata.insert(rdata.end(), label.begin(), label.end());
+        }
+        rdata.push_back(0);  // Length byte of zero terminates the label list
+
+        // The length of domain name is limited to 255 octets or less. See RFC 1035 section 3.1.
+        if (rdata.size() > 255) {
+            ALOGI("invalid name length");
+            return false;
+        }
+        record.rdata = move(rdata);
+    } else {
+        ALOGI("unhandled qtype %s", dnstype2str(record.rtype));
+        return false;
+    }
+    return true;
+}
+
+bool DNSResponder::makeErrorResponse(DNSHeader* header, ns_rcode rcode,
+                                     char* response, size_t* response_len)
+                                     const {
+    header->answers.clear();
+    header->authorities.clear();
+    header->additionals.clear();
+    header->rcode = rcode;
+    header->qr = true;
+    char* response_cur = header->write(response, response + *response_len);
+    if (response_cur == nullptr) return false;
+    *response_len = response_cur - response;
+    return true;
+}
+
+void DNSResponder::setDeferredResp(bool deferred_resp) {
+    std::lock_guard<std::mutex> guard(cv_mutex_for_deferred_resp_);
+    deferred_resp_ = deferred_resp;
+    if (!deferred_resp_) {
+        cv_for_deferred_resp_.notify_one();
+    }
+}
+
+bool DNSResponder::addFd(int fd, uint32_t events) {
+    epoll_event ev;
+    ev.events = events;
+    ev.data.fd = fd;
+    if (epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, fd, &ev) < 0) {
+        APLOGI("epoll_ctl() for socket %d failed", fd);
+        return false;
+    }
+    return true;
+}
+
+void DNSResponder::handleQuery() {
+    char buffer[4096];
+    sockaddr_storage sa;
+    socklen_t sa_len = sizeof(sa);
+    ssize_t len;
+    do {
+        len = recvfrom(socket_.get(), buffer, sizeof(buffer), 0, (sockaddr*)&sa, &sa_len);
+    } while (len < 0 && (errno == EAGAIN || errno == EINTR));
+    if (len <= 0) {
+        APLOGI("recvfrom() failed, len=%zu", len);
+        return;
+    }
+    DBGLOG("read %zd bytes", len);
+    std::lock_guard lock(cv_mutex_);
+    char response[4096];
+    size_t response_len = sizeof(response);
+    if (handleDNSRequest(buffer, len, response, &response_len) && response_len > 0) {
+        // place wait_for after handleDNSRequest() so we can check the number of queries in
+        // test case before it got responded.
+        std::unique_lock guard(cv_mutex_for_deferred_resp_);
+        cv_for_deferred_resp_.wait(
+                guard, [this]() REQUIRES(cv_mutex_for_deferred_resp_) { return !deferred_resp_; });
+
+        len = sendto(socket_.get(), response, response_len, 0,
+                     reinterpret_cast<const sockaddr*>(&sa), sa_len);
+        std::string host_str = addr2str(reinterpret_cast<const sockaddr*>(&sa), sa_len);
+        if (len > 0) {
+            DBGLOG("sent %zu bytes to %s", len, host_str.c_str());
+        } else {
+            APLOGI("sendto() failed for %s", host_str.c_str());
+        }
+        // Test that the response is actually a correct DNS message.
+        const char* response_end = response + len;
+        DNSHeader header;
+        const char* cur = header.read(response, response_end);
+        if (cur == nullptr) ALOGW("response is flawed");
+    } else {
+        ALOGW("not responding");
+    }
+    cv.notify_one();
+    return;
+}
+
+bool DNSResponder::sendToEventFd() {
+    const uint64_t data = 1;
+    if (const ssize_t rt = write(event_fd_.get(), &data, sizeof(data)); rt != sizeof(data)) {
+        APLOGI("failed to write eventfd, rt=%zd", rt);
+        return false;
+    }
+    return true;
+}
+
+void DNSResponder::handleEventFd() {
+    int64_t data;
+    if (const ssize_t rt = read(event_fd_.get(), &data, sizeof(data)); rt != sizeof(data)) {
+        APLOGI("ignore reading eventfd failed, rt=%zd", rt);
+    }
+}
+
+}  // namespace test
diff --git a/resolv/dns_responder/dns_responder.h b/resolv/dns_responder/dns_responder.h
new file mode 100644
index 0000000..99b601f
--- /dev/null
+++ b/resolv/dns_responder/dns_responder.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless requied by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef DNS_RESPONDER_H
+#define DNS_RESPONDER_H
+
+#include <arpa/nameser.h>
+
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+#include <unordered_map>
+#include <vector>
+
+#include <android-base/thread_annotations.h>
+#include "android-base/unique_fd.h"
+
+namespace test {
+
+struct DNSHeader;
+struct DNSQuestion;
+struct DNSRecord;
+
+inline const std::string kDefaultListenAddr = "127.0.0.3";
+inline const std::string kDefaultListenService = "53";
+inline const int kDefaultPollTimoutMillis = -1;
+
+/*
+ * Simple DNS responder, which replies to queries with the registered response
+ * for that type. Class is assumed to be IN. If no response is registered, the
+ * default error response code is returned.
+ */
+class DNSResponder {
+  public:
+    DNSResponder(std::string listen_address = kDefaultListenAddr,
+                 std::string listen_service = kDefaultListenService,
+                 int poll_timeout_ms = kDefaultPollTimoutMillis,
+                 ns_rcode error_rcode = ns_rcode::ns_r_servfail);
+    ~DNSResponder();
+
+    enum class Edns : uint8_t {
+        ON,
+        FORMERR_ON_EDNS, // DNS server not supporting EDNS will reply FORMERR.
+        FORMERR_UNCOND,  // DNS server reply FORMERR unconditionally
+        DROP             // DNS server not supporting EDNS will not do any response.
+    };
+
+    void addMapping(const std::string& name, ns_type type, const std::string& addr);
+    void removeMapping(const std::string& name, ns_type type);
+    void setResponseProbability(double response_probability);
+    void setEdns(Edns edns);
+    bool running() const;
+    bool startServer();
+    bool stopServer();
+    const std::string& listen_address() const {
+        return listen_address_;
+    }
+    const std::string& listen_service() const {
+        return listen_service_;
+    }
+    std::vector<std::pair<std::string, ns_type>> queries() const;
+    std::string dumpQueries() const;
+    void clearQueries();
+    std::condition_variable& getCv() { return cv; }
+    std::mutex& getCvMutex() { return cv_mutex_; }
+    void setDeferredResp(bool deferred_resp);
+
+  private:
+    // Key used for accessing mappings.
+    struct QueryKey {
+        std::string name;
+        unsigned type;
+
+        QueryKey(std::string n, unsigned t) : name(move(n)), type(t) {}
+        bool operator == (const QueryKey& o) const {
+            return name == o.name && type == o.type;
+        }
+        bool operator < (const QueryKey& o) const {
+            if (name < o.name) return true;
+            if (name > o.name) return false;
+            return type < o.type;
+        }
+    };
+
+    struct QueryKeyHash {
+        size_t operator() (const QueryKey& key) const {
+            return std::hash<std::string>()(key.name) +
+                   static_cast<size_t>(key.type);
+        }
+    };
+
+    void requestHandler();
+
+    // Parses and generates a response message for incoming DNS requests.
+    // Returns false to ignore the request, which might be due to either parsing error
+    // or unresponsiveness.
+    bool handleDNSRequest(const char* buffer, ssize_t buffer_len,
+                          char* response, size_t* response_len) const;
+
+    bool addAnswerRecords(const DNSQuestion& question, std::vector<DNSRecord>* answers) const;
+
+    bool fillAnswerRdata(const std::string& rdatastr, DNSRecord& record) const;
+
+    bool generateErrorResponse(DNSHeader* header, ns_rcode rcode,
+                               char* response, size_t* response_len) const;
+    bool makeErrorResponse(DNSHeader* header, ns_rcode rcode, char* response,
+                           size_t* response_len) const;
+
+    // Add a new file descriptor to be polled by the handler thread.
+    bool addFd(int fd, uint32_t events);
+
+    // Read the query sent from the client and send the answer back to the client. It
+    // makes sure the I/O communicated with the client is correct.
+    void handleQuery();
+
+    // Trigger the handler thread to terminate.
+    bool sendToEventFd();
+
+    // Used in the handler thread for the termination signal.
+    void handleEventFd();
+
+    // Address and service to listen on, currently limited to UDP.
+    const std::string listen_address_;
+    const std::string listen_service_;
+    // epoll_wait() timeout in ms.
+    const int poll_timeout_ms_;
+    // Error code to return for requests for an unknown name.
+    const ns_rcode error_rcode_;
+    // Probability that a valid response is being sent instead of being sent
+    // instead of returning error_rcode_.
+    std::atomic<double> response_probability_ = 1.0;
+    // Maximum number of fds for epoll.
+    const int EPOLL_MAX_EVENTS = 2;
+
+    // Control how the DNS server behaves when it receives the requests containing OPT RR.
+    // If it's set Edns::ON, the server can recognize and reply the response; if it's set
+    // Edns::FORMERR_ON_EDNS, the server behaves like an old DNS server that doesn't support EDNS0,
+    // and replying FORMERR; if it's Edns::DROP, the server doesn't support EDNS0 either, and
+    // ignoring the requests.
+    std::atomic<Edns> edns_ = Edns::ON;
+
+    // Mappings from (name, type) to registered response and the
+    // mutex protecting them.
+    std::unordered_map<QueryKey, std::string, QueryKeyHash> mappings_
+        GUARDED_BY(mappings_mutex_);
+    mutable std::mutex mappings_mutex_;
+    // Query names received so far and the corresponding mutex.
+    mutable std::vector<std::pair<std::string, ns_type>> queries_
+        GUARDED_BY(queries_mutex_);
+    mutable std::mutex queries_mutex_;
+    // Socket on which the server is listening.
+    android::base::unique_fd socket_;
+    // File descriptor for epoll.
+    android::base::unique_fd epoll_fd_;
+    // Eventfd used to signal for the handler thread termination.
+    android::base::unique_fd event_fd_;
+    // Thread for handling incoming threads.
+    std::thread handler_thread_ GUARDED_BY(update_mutex_);
+    std::mutex update_mutex_;
+    std::condition_variable cv;
+    std::mutex cv_mutex_;
+
+    std::condition_variable cv_for_deferred_resp_;
+    std::mutex cv_mutex_for_deferred_resp_;
+    bool deferred_resp_ GUARDED_BY(cv_mutex_for_deferred_resp_) = false;
+};
+
+}  // namespace test
+
+#endif  // DNS_RESPONDER_H
diff --git a/resolv/dns_responder/dns_responder_client.cpp b/resolv/dns_responder/dns_responder_client.cpp
new file mode 100644
index 0000000..3a87c21
--- /dev/null
+++ b/resolv/dns_responder/dns_responder_client.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "dns_responder_client"
+#include "dns_responder_client.h"
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <utils/Log.h>
+
+// TODO: make this dynamic and stop depending on implementation details.
+#define TEST_OEM_NETWORK "oem29"
+#define TEST_NETID 30
+
+// TODO: move this somewhere shared.
+static const char* ANDROID_DNS_MODE = "ANDROID_DNS_MODE";
+
+using android::base::StringPrintf;
+using android::net::INetd;
+using android::net::ResolverParamsParcel;
+
+void DnsResponderClient::SetupMappings(unsigned num_hosts, const std::vector<std::string>& domains,
+        std::vector<Mapping>* mappings) {
+    mappings->resize(num_hosts * domains.size());
+    auto mappings_it = mappings->begin();
+    for (unsigned i = 0 ; i < num_hosts ; ++i) {
+        for (const auto& domain : domains) {
+            mappings_it->host = StringPrintf("host%u", i);
+            mappings_it->entry = StringPrintf("%s.%s.", mappings_it->host.c_str(),
+                    domain.c_str());
+            mappings_it->ip4 = StringPrintf("192.0.2.%u", i%253 + 1);
+            mappings_it->ip6 = StringPrintf("2001:db8::%x", i%65534 + 1);
+            ++mappings_it;
+        }
+    }
+}
+
+// TODO: Use SetResolverConfiguration() with ResolverParamsParcel struct directly.
+// DEPRECATED: Use SetResolverConfiguration() in new code
+static ResolverParamsParcel makeResolverParamsParcel(
+        int netId, const std::vector<int>& params, const std::vector<std::string>& servers,
+        const std::vector<std::string>& domains, const std::string& tlsHostname,
+        const std::vector<std::string>& tlsServers,
+        const std::vector<std::string>& tlsFingerprints) {
+    using android::net::IDnsResolver;
+    ResolverParamsParcel paramsParcel;
+
+    paramsParcel.netId = netId;
+    paramsParcel.sampleValiditySeconds = params[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY];
+    paramsParcel.successThreshold = params[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD];
+    paramsParcel.minSamples = params[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES];
+    paramsParcel.maxSamples = params[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES];
+    if (params.size() > IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC) {
+        paramsParcel.baseTimeoutMsec = params[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC];
+    } else {
+        paramsParcel.baseTimeoutMsec = 0;
+    }
+    if (params.size() > IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT) {
+        paramsParcel.retryCount = params[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT];
+    } else {
+        paramsParcel.retryCount = 0;
+    }
+    paramsParcel.servers = servers;
+    paramsParcel.domains = domains;
+    paramsParcel.tlsName = tlsHostname;
+    paramsParcel.tlsServers = tlsServers;
+    paramsParcel.tlsFingerprints = tlsFingerprints;
+
+    return paramsParcel;
+}
+
+bool DnsResponderClient::SetResolversForNetwork(const std::vector<std::string>& servers,
+        const std::vector<std::string>& domains, const std::vector<int>& params) {
+    const auto& resolverParams =
+            makeResolverParamsParcel(TEST_NETID, params, servers, domains, "", {}, {});
+    const auto rv = mDnsResolvSrv->setResolverConfiguration(resolverParams);
+    return rv.isOk();
+}
+
+bool DnsResponderClient::SetResolversWithTls(const std::vector<std::string>& servers,
+        const std::vector<std::string>& domains, const std::vector<int>& params,
+        const std::vector<std::string>& tlsServers,
+        const std::string& name, const std::vector<std::string>& fingerprints) {
+    const auto& resolverParams = makeResolverParamsParcel(TEST_NETID, params, servers, domains,
+                                                          name, tlsServers, fingerprints);
+    const auto rv = mDnsResolvSrv->setResolverConfiguration(resolverParams);
+    if (!rv.isOk()) ALOGI("SetResolversWithTls() -> %s", rv.toString8().c_str());
+    return rv.isOk();
+}
+
+void DnsResponderClient::SetupDNSServers(unsigned num_servers, const std::vector<Mapping>& mappings,
+        std::vector<std::unique_ptr<test::DNSResponder>>* dns,
+        std::vector<std::string>* servers) {
+    const char* listen_srv = "53";
+    dns->resize(num_servers);
+    servers->resize(num_servers);
+    for (unsigned i = 0 ; i < num_servers ; ++i) {
+        auto& server = (*servers)[i];
+        auto& d = (*dns)[i];
+        server = StringPrintf("127.0.0.%u", i + 100);
+        d = std::make_unique<test::DNSResponder>(server, listen_srv, 250, ns_rcode::ns_r_servfail);
+        for (const auto& mapping : mappings) {
+            d->addMapping(mapping.entry.c_str(), ns_type::ns_t_a, mapping.ip4.c_str());
+            d->addMapping(mapping.entry.c_str(), ns_type::ns_t_aaaa, mapping.ip6.c_str());
+        }
+        d->startServer();
+    }
+}
+
+int DnsResponderClient::SetupOemNetwork() {
+    mNetdSrv->networkDestroy(TEST_NETID);
+    mDnsResolvSrv->destroyNetworkCache(TEST_NETID);
+    auto ret = mNetdSrv->networkCreatePhysical(TEST_NETID, INetd::PERMISSION_NONE);
+    if (!ret.isOk()) {
+        fprintf(stderr, "Creating physical network %d failed, %s\n", TEST_NETID,
+                ret.toString8().string());
+        return -1;
+    }
+    ret = mDnsResolvSrv->createNetworkCache(TEST_NETID);
+    if (!ret.isOk()) {
+        fprintf(stderr, "Creating network cache %d failed, %s\n", TEST_NETID,
+                ret.toString8().string());
+        return -1;
+    }
+    setNetworkForProcess(TEST_NETID);
+    if ((unsigned)TEST_NETID != getNetworkForProcess()) {
+        return -1;
+    }
+    return TEST_NETID;
+}
+
+void DnsResponderClient::TearDownOemNetwork(int oemNetId) {
+    if (oemNetId != -1) {
+        mNetdSrv->networkDestroy(oemNetId);
+        mDnsResolvSrv->destroyNetworkCache(oemNetId);
+    }
+}
+
+void DnsResponderClient::SetUp() {
+    // binder setup
+    auto binder = android::defaultServiceManager()->getService(android::String16("netd"));
+    mNetdSrv = android::interface_cast<android::net::INetd>(binder);
+    if (mNetdSrv == nullptr) {
+        LOG(FATAL) << "Can't connect to service 'netd'. Missing root privileges? uid=" << getuid();
+    }
+
+    auto resolvBinder =
+            android::defaultServiceManager()->getService(android::String16("dnsresolver"));
+    mDnsResolvSrv = android::interface_cast<android::net::IDnsResolver>(resolvBinder);
+
+    // Ensure resolutions go via proxy.
+    setenv(ANDROID_DNS_MODE, "", 1);
+    mOemNetId = SetupOemNetwork();
+}
+
+void DnsResponderClient::TearDown() {
+    TearDownOemNetwork(mOemNetId);
+}
diff --git a/resolv/dns_responder/dns_responder_client.h b/resolv/dns_responder/dns_responder_client.h
new file mode 100644
index 0000000..678be02
--- /dev/null
+++ b/resolv/dns_responder/dns_responder_client.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless requied by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef DNS_RESPONDER_CLIENT_H
+#define DNS_RESPONDER_CLIENT_H
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <cutils/sockets.h>
+
+#include <private/android_filesystem_config.h>
+#include <utils/StrongPointer.h>
+
+#include "NetdClient.h"
+#include "android/net/IDnsResolver.h"
+#include "android/net/INetd.h"
+#include "binder/IServiceManager.h"
+#include "dns_responder.h"
+
+#define SKIP_IF_RESOLVER_VERSION_NEWER_THAN(service, version) \
+    do {                                                      \
+        if ((service)->getInterfaceVersion() > (version)) {   \
+            return;                                           \
+        }                                                     \
+    } while (0)
+
+inline const std::vector<std::string> kDefaultServers = {"127.0.0.3"};
+inline const std::vector<std::string> kDefaultSearchDomains = {"example.com"};
+inline const std::vector<int> kDefaultParams = {
+        300,      // sample validity in seconds
+        25,       // success threshod in percent
+        8,    8,  // {MIN,MAX}_SAMPLES
+        1000,     // BASE_TIMEOUT_MSEC
+        2,        // retry count
+};
+
+class DnsResponderClient {
+public:
+    struct Mapping {
+        std::string host;
+        std::string entry;
+        std::string ip4;
+        std::string ip6;
+    };
+
+    virtual ~DnsResponderClient() = default;
+
+    static void SetupMappings(unsigned num_hosts, const std::vector<std::string>& domains,
+            std::vector<Mapping>* mappings);
+
+    bool SetResolversForNetwork(const std::vector<std::string>& servers = kDefaultServers,
+                                const std::vector<std::string>& domains = kDefaultSearchDomains,
+                                const std::vector<int>& params = kDefaultParams);
+
+    bool SetResolversForNetwork(const std::vector<std::string>& servers,
+            const std::vector<std::string>& searchDomains,
+            const std::string& params);
+
+    bool SetResolversWithTls(const std::vector<std::string>& servers,
+            const std::vector<std::string>& searchDomains,
+            const std::vector<int>& params,
+            const std::string& name,
+            const std::vector<std::string>& fingerprints) {
+        // Pass servers as both network-assigned and TLS servers.  Tests can
+        // determine on which server and by which protocol queries arrived.
+        return SetResolversWithTls(servers, searchDomains, params,
+                                   servers, name, fingerprints);
+    }
+
+    bool SetResolversWithTls(const std::vector<std::string>& servers,
+            const std::vector<std::string>& searchDomains,
+            const std::vector<int>& params,
+            const std::vector<std::string>& tlsServers,
+            const std::string& name,
+            const std::vector<std::string>& fingerprints);
+
+    static void SetupDNSServers(unsigned num_servers, const std::vector<Mapping>& mappings,
+            std::vector<std::unique_ptr<test::DNSResponder>>* dns,
+            std::vector<std::string>* servers);
+
+    int SetupOemNetwork();
+
+    void TearDownOemNetwork(int oemNetId);
+
+    virtual void SetUp();
+    virtual void TearDown();
+
+    android::net::IDnsResolver* resolvService() const { return mDnsResolvSrv.get(); }
+    android::net::INetd* netdService() const { return mNetdSrv.get(); }
+
+  private:
+    android::sp<android::net::INetd> mNetdSrv = nullptr;
+    android::sp<android::net::IDnsResolver> mDnsResolvSrv = nullptr;
+    int mOemNetId = -1;
+};
+
+#endif  // DNS_RESPONDER_CLIENT_H
diff --git a/resolv/dns_responder/dns_tls_frontend.cpp b/resolv/dns_responder/dns_tls_frontend.cpp
new file mode 100644
index 0000000..83e36ed
--- /dev/null
+++ b/resolv/dns_responder/dns_tls_frontend.cpp
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dns_tls_frontend.h"
+
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/ssl.h>
+#include <sys/eventfd.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define LOG_TAG "DnsTlsFrontend"
+#include <log/log.h>
+#include <netdutils/SocketOption.h>
+
+#include "NetdConstants.h"  // SHA256_SIZE
+
+using android::netdutils::enableSockopt;
+
+namespace {
+
+// Copied from DnsTlsTransport.
+bool getSPKIDigest(const X509* cert, std::vector<uint8_t>* out) {
+    int spki_len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), nullptr);
+    unsigned char spki[spki_len];
+    unsigned char* temp = spki;
+    if (spki_len != i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp)) {
+        ALOGE("SPKI length mismatch");
+        return false;
+    }
+    out->resize(SHA256_SIZE);
+    unsigned int digest_len = 0;
+    int ret = EVP_Digest(spki, spki_len, out->data(), &digest_len, EVP_sha256(), nullptr);
+    if (ret != 1) {
+        ALOGE("Server cert digest extraction failed");
+        return false;
+    }
+    if (digest_len != out->size()) {
+        ALOGE("Wrong digest length: %d", digest_len);
+        return false;
+    }
+    return true;
+}
+
+std::string errno2str() {
+    char error_msg[512] = { 0 };
+    return strerror_r(errno, error_msg, sizeof(error_msg));
+}
+
+#define APLOGI(fmt, ...) ALOGI(fmt ": [%d] %s", __VA_ARGS__, errno, errno2str().c_str())
+
+std::string addr2str(const sockaddr* sa, socklen_t sa_len) {
+    char host_str[NI_MAXHOST] = { 0 };
+    int rv = getnameinfo(sa, sa_len, host_str, sizeof(host_str), nullptr, 0,
+                         NI_NUMERICHOST);
+    if (rv == 0) return std::string(host_str);
+    return std::string();
+}
+
+bssl::UniquePtr<EVP_PKEY> make_private_key() {
+    bssl::UniquePtr<BIGNUM> e(BN_new());
+    if (!e) {
+        ALOGE("BN_new failed");
+        return nullptr;
+    }
+    if (!BN_set_word(e.get(), RSA_F4)) {
+        ALOGE("BN_set_word failed");
+        return nullptr;
+    }
+
+    bssl::UniquePtr<RSA> rsa(RSA_new());
+    if (!rsa) {
+        ALOGE("RSA_new failed");
+        return nullptr;
+    }
+    if (!RSA_generate_key_ex(rsa.get(), 2048, e.get(), nullptr)) {
+        ALOGE("RSA_generate_key_ex failed");
+        return nullptr;
+    }
+
+    bssl::UniquePtr<EVP_PKEY> privkey(EVP_PKEY_new());
+    if (!privkey) {
+        ALOGE("EVP_PKEY_new failed");
+        return nullptr;
+    }
+    if(!EVP_PKEY_assign_RSA(privkey.get(), rsa.get())) {
+        ALOGE("EVP_PKEY_assign_RSA failed");
+        return nullptr;
+    }
+
+    // |rsa| is now owned by |privkey|, so no need to free it.
+    rsa.release();
+    return privkey;
+}
+
+bssl::UniquePtr<X509> make_cert(EVP_PKEY* privkey, EVP_PKEY* parent_key) {
+    bssl::UniquePtr<X509> cert(X509_new());
+    if (!cert) {
+        ALOGE("X509_new failed");
+        return nullptr;
+    }
+
+    ASN1_INTEGER_set(X509_get_serialNumber(cert.get()), 1);
+
+    // Set one hour expiration.
+    X509_gmtime_adj(X509_get_notBefore(cert.get()), 0);
+    X509_gmtime_adj(X509_get_notAfter(cert.get()), 60 * 60);
+
+    X509_set_pubkey(cert.get(), privkey);
+
+    if (!X509_sign(cert.get(), parent_key, EVP_sha256())) {
+        ALOGE("X509_sign failed");
+        return nullptr;
+    }
+
+    return cert;
+}
+
+}
+
+namespace test {
+
+bool DnsTlsFrontend::startServer() {
+    SSL_load_error_strings();
+    OpenSSL_add_ssl_algorithms();
+
+    // reset queries_ to 0 every time startServer called
+    // which would help us easy to check queries_ via calling waitForQueries
+    queries_ = 0;
+
+    ctx_.reset(SSL_CTX_new(TLS_server_method()));
+    if (!ctx_) {
+        ALOGE("SSL context creation failed");
+        return false;
+    }
+
+    SSL_CTX_set_ecdh_auto(ctx_.get(), 1);
+
+    // Make certificate chain
+    std::vector<bssl::UniquePtr<EVP_PKEY>> keys(chain_length_);
+    for (int i = 0; i < chain_length_; ++i) {
+        keys[i] = make_private_key();
+    }
+    std::vector<bssl::UniquePtr<X509>> certs(chain_length_);
+    for (int i = 0; i < chain_length_; ++i) {
+        int next = std::min(i + 1, chain_length_ - 1);
+        certs[i] = make_cert(keys[i].get(), keys[next].get());
+    }
+
+    // Install certificate chain.
+    if (SSL_CTX_use_certificate(ctx_.get(), certs[0].get()) <= 0) {
+        ALOGE("SSL_CTX_use_certificate failed");
+        return false;
+    }
+    if (SSL_CTX_use_PrivateKey(ctx_.get(), keys[0].get()) <= 0 ) {
+        ALOGE("SSL_CTX_use_PrivateKey failed");
+        return false;
+    }
+    for (int i = 1; i < chain_length_; ++i) {
+        if (SSL_CTX_add1_chain_cert(ctx_.get(), certs[i].get()) != 1) {
+            ALOGE("SSL_CTX_add1_chain_cert failed");
+            return false;
+        }
+    }
+
+    // Report the fingerprint of the "middle" cert.  For N = 2, this is the root.
+    int fp_index = chain_length_ / 2;
+    if (!getSPKIDigest(certs[fp_index].get(), &fingerprint_)) {
+        ALOGE("getSPKIDigest failed");
+        return false;
+    }
+
+    // Set up TCP server socket for clients.
+    addrinfo frontend_ai_hints{
+        .ai_family = AF_UNSPEC,
+        .ai_socktype = SOCK_STREAM,
+        .ai_flags = AI_PASSIVE
+    };
+    addrinfo* frontend_ai_res = nullptr;
+    int rv = getaddrinfo(listen_address_.c_str(), listen_service_.c_str(),
+                         &frontend_ai_hints, &frontend_ai_res);
+    ScopedAddrinfo frontend_ai_res_cleanup(frontend_ai_res);
+    if (rv) {
+        ALOGE("frontend getaddrinfo(%s, %s) failed: %s", listen_address_.c_str(),
+            listen_service_.c_str(), gai_strerror(rv));
+        return false;
+    }
+
+    for (const addrinfo* ai = frontend_ai_res ; ai ; ai = ai->ai_next) {
+        android::base::unique_fd s(socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol));
+        if (s.get() < 0) {
+            APLOGI("ignore creating socket failed %d", s.get());
+            continue;
+        }
+        enableSockopt(s.get(), SOL_SOCKET, SO_REUSEPORT).ignoreError();
+        enableSockopt(s.get(), SOL_SOCKET, SO_REUSEADDR).ignoreError();
+        std::string host_str = addr2str(ai->ai_addr, ai->ai_addrlen);
+        if (bind(s.get(), ai->ai_addr, ai->ai_addrlen)) {
+            APLOGI("failed to bind TCP %s:%s", host_str.c_str(), listen_service_.c_str());
+            continue;
+        }
+        ALOGI("bound to TCP %s:%s", host_str.c_str(), listen_service_.c_str());
+        socket_ = std::move(s);
+        break;
+    }
+
+    if (listen(socket_.get(), 1) < 0) {
+        APLOGI("failed to listen socket %d", socket_.get());
+        return false;
+    }
+
+    // Set up UDP client socket to backend.
+    addrinfo backend_ai_hints{
+        .ai_family = AF_UNSPEC,
+        .ai_socktype = SOCK_DGRAM
+    };
+    addrinfo* backend_ai_res = nullptr;
+    rv = getaddrinfo(backend_address_.c_str(), backend_service_.c_str(),
+                         &backend_ai_hints, &backend_ai_res);
+    ScopedAddrinfo backend_ai_res_cleanup(backend_ai_res);
+    if (rv) {
+        ALOGE("backend getaddrinfo(%s, %s) failed: %s", listen_address_.c_str(),
+            listen_service_.c_str(), gai_strerror(rv));
+        return false;
+    }
+    backend_socket_.reset(socket(backend_ai_res->ai_family, backend_ai_res->ai_socktype,
+                                 backend_ai_res->ai_protocol));
+    if (backend_socket_.get() < 0) {
+        APLOGI("backend socket %d creation failed", backend_socket_.get());
+        return false;
+    }
+
+    // connect() always fails in the test DnsTlsSocketTest.SlowDestructor because of
+    // no backend server. Don't check it.
+    connect(backend_socket_.get(), backend_ai_res->ai_addr, backend_ai_res->ai_addrlen);
+
+    // Set up eventfd socket.
+    event_fd_.reset(eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC));
+    if (event_fd_.get() == -1) {
+        APLOGI("failed to create eventfd %d", event_fd_.get());
+        return false;
+    }
+
+    {
+        std::lock_guard lock(update_mutex_);
+        handler_thread_ = std::thread(&DnsTlsFrontend::requestHandler, this);
+    }
+    ALOGI("server started successfully");
+    return true;
+}
+
+void DnsTlsFrontend::requestHandler() {
+    ALOGD("Request handler started");
+    enum { EVENT_FD = 0, LISTEN_FD = 1 };
+    pollfd fds[2] = {{.fd = event_fd_.get(), .events = POLLIN},
+                     {.fd = socket_.get(), .events = POLLIN}};
+
+    while (true) {
+        int poll_code = poll(fds, std::size(fds), -1);
+        if (poll_code <= 0) {
+            APLOGI("Poll failed with error %d", poll_code);
+            break;
+        }
+
+        if (fds[EVENT_FD].revents & (POLLIN | POLLERR)) {
+            handleEventFd();
+            break;
+        }
+        if (fds[LISTEN_FD].revents & (POLLIN | POLLERR)) {
+            sockaddr_storage addr;
+            socklen_t len = sizeof(addr);
+
+            ALOGD("Trying to accept a client");
+            android::base::unique_fd client(
+                    accept4(socket_.get(), reinterpret_cast<sockaddr*>(&addr), &len, SOCK_CLOEXEC));
+            if (client.get() < 0) {
+                // Stop
+                APLOGI("failed to accept client socket %d", client.get());
+                break;
+            }
+
+            bssl::UniquePtr<SSL> ssl(SSL_new(ctx_.get()));
+            SSL_set_fd(ssl.get(), client.get());
+
+            ALOGD("Doing SSL handshake");
+            bool success = false;
+            if (SSL_accept(ssl.get()) <= 0) {
+                ALOGI("SSL negotiation failure");
+            } else {
+                ALOGD("SSL handshake complete");
+                success = handleOneRequest(ssl.get());
+            }
+
+            if (success) {
+                // Increment queries_ as late as possible, because it represents
+                // a query that is fully processed, and the response returned to the
+                // client, including cleanup actions.
+                ++queries_;
+            }
+        }
+    }
+    ALOGD("Ending loop");
+}
+
+bool DnsTlsFrontend::handleOneRequest(SSL* ssl) {
+    uint8_t queryHeader[2];
+    if (SSL_read(ssl, &queryHeader, 2) != 2) {
+        ALOGI("Not enough header bytes");
+        return false;
+    }
+    const uint16_t qlen = (queryHeader[0] << 8) | queryHeader[1];
+    uint8_t query[qlen];
+    size_t qbytes = 0;
+    while (qbytes < qlen) {
+        int ret = SSL_read(ssl, query + qbytes, qlen - qbytes);
+        if (ret <= 0) {
+            ALOGI("Error while reading query");
+            return false;
+        }
+        qbytes += ret;
+    }
+    int sent = send(backend_socket_.get(), query, qlen, 0);
+    if (sent != qlen) {
+        ALOGI("Failed to send query");
+        return false;
+    }
+    const int max_size = 4096;
+    uint8_t recv_buffer[max_size];
+    int rlen = recv(backend_socket_.get(), recv_buffer, max_size, 0);
+    if (rlen <= 0) {
+        ALOGI("Failed to receive response");
+        return false;
+    }
+    uint8_t responseHeader[2];
+    responseHeader[0] = rlen >> 8;
+    responseHeader[1] = rlen;
+    if (SSL_write(ssl, responseHeader, 2) != 2) {
+        ALOGI("Failed to write response header");
+        return false;
+    }
+    if (SSL_write(ssl, recv_buffer, rlen) != rlen) {
+        ALOGI("Failed to write response body");
+        return false;
+    }
+    return true;
+}
+
+bool DnsTlsFrontend::stopServer() {
+    std::lock_guard lock(update_mutex_);
+    if (!running()) {
+        ALOGI("server not running");
+        return false;
+    }
+
+    ALOGI("stopping frontend");
+    if (!sendToEventFd()) {
+        return false;
+    }
+    handler_thread_.join();
+    socket_.reset();
+    backend_socket_.reset();
+    event_fd_.reset();
+    ctx_.reset();
+    fingerprint_.clear();
+    ALOGI("frontend stopped successfully");
+    return true;
+}
+
+bool DnsTlsFrontend::waitForQueries(int number, int timeoutMs) const {
+    constexpr int intervalMs = 20;
+    int limit = timeoutMs / intervalMs;
+    for (int count = 0; count <= limit; ++count) {
+        bool done = queries_ >= number;
+        // Always sleep at least one more interval after we are done, to wait for
+        // any immediate post-query actions that the client may take (such as
+        // marking this server as reachable during validation).
+        usleep(intervalMs * 1000);
+        if (done) {
+            // For ensuring that calls have sufficient headroom for slow machines
+            ALOGD("Query arrived in %d/%d of allotted time", count, limit);
+            return true;
+        }
+    }
+    return false;
+}
+
+bool DnsTlsFrontend::sendToEventFd() {
+    const uint64_t data = 1;
+    if (const ssize_t rt = write(event_fd_.get(), &data, sizeof(data)); rt != sizeof(data)) {
+        APLOGI("failed to write eventfd, rt=%zd", rt);
+        return false;
+    }
+    return true;
+}
+
+void DnsTlsFrontend::handleEventFd() {
+    int64_t data;
+    if (const ssize_t rt = read(event_fd_.get(), &data, sizeof(data)); rt != sizeof(data)) {
+        APLOGI("ignore reading eventfd failed, rt=%zd", rt);
+    }
+}
+
+}  // namespace test
diff --git a/resolv/dns_responder/dns_tls_frontend.h b/resolv/dns_responder/dns_tls_frontend.h
new file mode 100644
index 0000000..32a2771
--- /dev/null
+++ b/resolv/dns_responder/dns_tls_frontend.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless requied by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef DNS_TLS_FRONTEND_H
+#define DNS_TLS_FRONTEND_H
+
+#include <arpa/nameser.h>
+
+#include <atomic>
+#include <mutex>
+#include <string>
+#include <thread>
+#include <unordered_map>
+#include <vector>
+
+#include <android-base/thread_annotations.h>
+#include <android-base/unique_fd.h>
+#include <openssl/ssl.h>
+
+namespace test {
+
+/*
+ * Simple DNS over TLS reverse proxy that forwards to a UDP backend.
+ * Only handles a single request at a time.
+ */
+class DnsTlsFrontend {
+  public:
+    DnsTlsFrontend(const std::string& listen_address, const std::string& listen_service,
+                   const std::string& backend_address, const std::string& backend_service)
+        : listen_address_(listen_address),
+          listen_service_(listen_service),
+          backend_address_(backend_address),
+          backend_service_(backend_service) {}
+    ~DnsTlsFrontend() {
+        stopServer();
+    }
+    const std::string& listen_address() const {
+        return listen_address_;
+    }
+    const std::string& listen_service() const {
+        return listen_service_;
+    }
+    bool running() const {
+        return socket_ != -1;
+    }
+    bool startServer();
+    bool stopServer();
+    int queries() const { return queries_; }
+    void clearQueries() { queries_ = 0; }
+    bool waitForQueries(int number, int timeoutMs) const;
+    void set_chain_length(int length) { chain_length_ = length; }
+    // Represents a fingerprint from the middle of the certificate chain.
+    const std::vector<uint8_t>& fingerprint() const { return fingerprint_; }
+
+  private:
+    void requestHandler();
+    bool handleOneRequest(SSL* ssl);
+
+    // Trigger the handler thread to terminate.
+    bool sendToEventFd();
+
+    // Used in the handler thread for the termination signal.
+    void handleEventFd();
+
+    std::string listen_address_;
+    std::string listen_service_;
+    std::string backend_address_;
+    std::string backend_service_;
+    bssl::UniquePtr<SSL_CTX> ctx_;
+    // Socket on which the server is listening for a TCP connection with a client.
+    android::base::unique_fd socket_;
+    // Socket used to communicate with the backend DNS server.
+    android::base::unique_fd backend_socket_;
+    // Eventfd used to signal for the handler thread termination.
+    android::base::unique_fd event_fd_;
+    std::atomic<int> queries_ = 0;
+    std::thread handler_thread_ GUARDED_BY(update_mutex_);
+    std::mutex update_mutex_;
+    int chain_length_ = 1;
+    std::vector<uint8_t> fingerprint_;
+};
+
+}  // namespace test
+
+#endif  // DNS_TLS_FRONTEND_H
diff --git a/resolv/dns_tls_test.cpp b/resolv/dns_tls_test.cpp
new file mode 100644
index 0000000..0bcad30
--- /dev/null
+++ b/resolv/dns_tls_test.cpp
@@ -0,0 +1,963 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "dns_tls_test"
+#define LOG_NDEBUG 1  // Set to 0 to enable verbose debug logging
+
+#include <gtest/gtest.h>
+
+#include "DnsTlsDispatcher.h"
+#include "DnsTlsQueryMap.h"
+#include "DnsTlsServer.h"
+#include "DnsTlsSessionCache.h"
+#include "DnsTlsSocket.h"
+#include "DnsTlsTransport.h"
+#include "IDnsTlsSocket.h"
+#include "IDnsTlsSocketFactory.h"
+#include "IDnsTlsSocketObserver.h"
+
+#include "dns_responder/dns_tls_frontend.h"
+
+#include <chrono>
+#include <arpa/inet.h>
+#include <android-base/macros.h>
+#include <netdutils/Slice.h>
+
+#include "log/log.h"
+
+namespace android {
+namespace net {
+
+using netdutils::Slice;
+using netdutils::makeSlice;
+
+typedef std::vector<uint8_t> bytevec;
+
+static void parseServer(const char* server, in_port_t port, sockaddr_storage* parsed) {
+    sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(parsed);
+    if (inet_pton(AF_INET, server, &(sin->sin_addr)) == 1) {
+        // IPv4 parse succeeded, so it's IPv4
+        sin->sin_family = AF_INET;
+        sin->sin_port = htons(port);
+        return;
+    }
+    sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(parsed);
+    if (inet_pton(AF_INET6, server, &(sin6->sin6_addr)) == 1){
+        // IPv6 parse succeeded, so it's IPv6.
+        sin6->sin6_family = AF_INET6;
+        sin6->sin6_port = htons(port);
+        return;
+    }
+    ALOGE("Failed to parse server address: %s", server);
+}
+
+bytevec FINGERPRINT1 = { 1 };
+bytevec FINGERPRINT2 = { 2 };
+
+std::string SERVERNAME1 = "dns.example.com";
+std::string SERVERNAME2 = "dns.example.org";
+
+// BaseTest just provides constants that are useful for the tests.
+class BaseTest : public ::testing::Test {
+  protected:
+    BaseTest() {
+        parseServer("192.0.2.1", 853, &V4ADDR1);
+        parseServer("192.0.2.2", 853, &V4ADDR2);
+        parseServer("2001:db8::1", 853, &V6ADDR1);
+        parseServer("2001:db8::2", 853, &V6ADDR2);
+
+        SERVER1 = DnsTlsServer(V4ADDR1);
+        SERVER1.fingerprints.insert(FINGERPRINT1);
+        SERVER1.name = SERVERNAME1;
+    }
+
+    sockaddr_storage V4ADDR1;
+    sockaddr_storage V4ADDR2;
+    sockaddr_storage V6ADDR1;
+    sockaddr_storage V6ADDR2;
+
+    DnsTlsServer SERVER1;
+};
+
+bytevec make_query(uint16_t id, size_t size) {
+    bytevec vec(size);
+    vec[0] = id >> 8;
+    vec[1] = id;
+    // Arbitrarily fill the query body with unique data.
+    for (size_t i = 2; i < size; ++i) {
+        vec[i] = id + i;
+    }
+    return vec;
+}
+
+// Query constants
+const unsigned MARK = 123;
+const uint16_t ID = 52;
+const uint16_t SIZE = 22;
+const bytevec QUERY = make_query(ID, SIZE);
+
+template <class T>
+class FakeSocketFactory : public IDnsTlsSocketFactory {
+  public:
+    FakeSocketFactory() {}
+    std::unique_ptr<IDnsTlsSocket> createDnsTlsSocket(
+            const DnsTlsServer& server ATTRIBUTE_UNUSED,
+            unsigned mark ATTRIBUTE_UNUSED,
+            IDnsTlsSocketObserver* observer,
+            DnsTlsSessionCache* cache ATTRIBUTE_UNUSED) override {
+        return std::make_unique<T>(observer);
+    }
+};
+
+bytevec make_echo(uint16_t id, const Slice query) {
+    bytevec response(query.size() + 2);
+    response[0] = id >> 8;
+    response[1] = id;
+    // Echo the query as the fake response.
+    memcpy(response.data() + 2, query.base(), query.size());
+    return response;
+}
+
+// Simplest possible fake server.  This just echoes the query as the response.
+class FakeSocketEcho : public IDnsTlsSocket {
+  public:
+    explicit FakeSocketEcho(IDnsTlsSocketObserver* observer) : mObserver(observer) {}
+    bool query(uint16_t id, const Slice query) override {
+        // Return the response immediately (asynchronously).
+        std::thread(&IDnsTlsSocketObserver::onResponse, mObserver, make_echo(id, query)).detach();
+        return true;
+    }
+
+  private:
+    IDnsTlsSocketObserver* const mObserver;
+};
+
+class TransportTest : public BaseTest {};
+
+TEST_F(TransportTest, Query) {
+    FakeSocketFactory<FakeSocketEcho> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    auto r = transport.query(makeSlice(QUERY)).get();
+
+    EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
+    EXPECT_EQ(QUERY, r.response);
+}
+
+// Fake Socket that echoes the observed query ID as the response body.
+class FakeSocketId : public IDnsTlsSocket {
+  public:
+    explicit FakeSocketId(IDnsTlsSocketObserver* observer) : mObserver(observer) {}
+    bool query(uint16_t id, const Slice query ATTRIBUTE_UNUSED) override {
+        // Return the response immediately (asynchronously).
+        bytevec response(4);
+        // Echo the ID in the header to match the response to the query.
+        // This will be overwritten by DnsTlsQueryMap.
+        response[0] = id >> 8;
+        response[1] = id;
+        // Echo the ID in the body, so that the test can verify which ID was used by
+        // DnsTlsQueryMap.
+        response[2] = id >> 8;
+        response[3] = id;
+        std::thread(&IDnsTlsSocketObserver::onResponse, mObserver, response).detach();
+        return true;
+    }
+
+  private:
+    IDnsTlsSocketObserver* const mObserver;
+};
+
+// Test that IDs are properly reused
+TEST_F(TransportTest, IdReuse) {
+    FakeSocketFactory<FakeSocketId> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    for (int i = 0; i < 100; ++i) {
+        // Send a query.
+        std::future<DnsTlsServer::Result> f = transport.query(makeSlice(QUERY));
+        // Wait for the response.
+        DnsTlsServer::Result r = f.get();
+        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
+
+        // All queries should have an observed ID of zero, because it is returned to the ID pool
+        // after each use.
+        EXPECT_EQ(0, (r.response[2] << 8) | r.response[3]);
+    }
+}
+
+// These queries might be handled in serial or parallel as they race the
+// responses.
+TEST_F(TransportTest, RacingQueries_10000) {
+    FakeSocketFactory<FakeSocketEcho> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    std::vector<std::future<DnsTlsTransport::Result>> results;
+    // Fewer than 65536 queries to avoid ID exhaustion.
+    const int num_queries = 10000;
+    results.reserve(num_queries);
+    for (int i = 0; i < num_queries; ++i) {
+        results.push_back(transport.query(makeSlice(QUERY)));
+    }
+    for (auto& result : results) {
+        auto r = result.get();
+        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
+        EXPECT_EQ(QUERY, r.response);
+    }
+}
+
+// A server that waits until sDelay queries are queued before responding.
+class FakeSocketDelay : public IDnsTlsSocket {
+  public:
+    explicit FakeSocketDelay(IDnsTlsSocketObserver* observer) : mObserver(observer) {}
+    ~FakeSocketDelay() { std::lock_guard guard(mLock); }
+    static size_t sDelay;
+    static bool sReverse;
+
+    bool query(uint16_t id, const Slice query) override {
+        ALOGV("FakeSocketDelay got query with ID %d", int(id));
+        std::lock_guard guard(mLock);
+        // Check for duplicate IDs.
+        EXPECT_EQ(0U, mIds.count(id));
+        mIds.insert(id);
+
+        // Store response.
+        mResponses.push_back(make_echo(id, query));
+
+        ALOGV("Up to %zu out of %zu queries", mResponses.size(), sDelay);
+        if (mResponses.size() == sDelay) {
+            std::thread(&FakeSocketDelay::sendResponses, this).detach();
+        }
+        return true;
+    }
+
+  private:
+    void sendResponses() {
+        std::lock_guard guard(mLock);
+        if (sReverse) {
+            std::reverse(std::begin(mResponses), std::end(mResponses));
+        }
+        for (auto& response : mResponses) {
+            mObserver->onResponse(response);
+        }
+        mIds.clear();
+        mResponses.clear();
+    }
+
+    std::mutex mLock;
+    IDnsTlsSocketObserver* const mObserver;
+    std::set<uint16_t> mIds GUARDED_BY(mLock);
+    std::vector<bytevec> mResponses GUARDED_BY(mLock);
+};
+
+size_t FakeSocketDelay::sDelay;
+bool FakeSocketDelay::sReverse;
+
+TEST_F(TransportTest, ParallelColliding) {
+    FakeSocketDelay::sDelay = 10;
+    FakeSocketDelay::sReverse = false;
+    FakeSocketFactory<FakeSocketDelay> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    std::vector<std::future<DnsTlsTransport::Result>> results;
+    // Fewer than 65536 queries to avoid ID exhaustion.
+    results.reserve(FakeSocketDelay::sDelay);
+    for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
+        results.push_back(transport.query(makeSlice(QUERY)));
+    }
+    for (auto& result : results) {
+        auto r = result.get();
+        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
+        EXPECT_EQ(QUERY, r.response);
+    }
+}
+
+TEST_F(TransportTest, ParallelColliding_Max) {
+    FakeSocketDelay::sDelay = 65536;
+    FakeSocketDelay::sReverse = false;
+    FakeSocketFactory<FakeSocketDelay> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    std::vector<std::future<DnsTlsTransport::Result>> results;
+    // Exactly 65536 queries should still be possible in parallel,
+    // even if they all have the same original ID.
+    results.reserve(FakeSocketDelay::sDelay);
+    for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
+        results.push_back(transport.query(makeSlice(QUERY)));
+    }
+    for (auto& result : results) {
+        auto r = result.get();
+        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
+        EXPECT_EQ(QUERY, r.response);
+    }
+}
+
+TEST_F(TransportTest, ParallelUnique) {
+    FakeSocketDelay::sDelay = 10;
+    FakeSocketDelay::sReverse = false;
+    FakeSocketFactory<FakeSocketDelay> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    std::vector<bytevec> queries(FakeSocketDelay::sDelay);
+    std::vector<std::future<DnsTlsTransport::Result>> results;
+    results.reserve(FakeSocketDelay::sDelay);
+    for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
+        queries[i] = make_query(i, SIZE);
+        results.push_back(transport.query(makeSlice(queries[i])));
+    }
+    for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
+        auto r = results[i].get();
+        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
+        EXPECT_EQ(queries[i], r.response);
+    }
+}
+
+TEST_F(TransportTest, ParallelUnique_Max) {
+    FakeSocketDelay::sDelay = 65536;
+    FakeSocketDelay::sReverse = false;
+    FakeSocketFactory<FakeSocketDelay> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    std::vector<bytevec> queries(FakeSocketDelay::sDelay);
+    std::vector<std::future<DnsTlsTransport::Result>> results;
+    // Exactly 65536 queries should still be possible in parallel,
+    // and they should all be mapped correctly back to the original ID.
+    results.reserve(FakeSocketDelay::sDelay);
+    for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
+        queries[i] = make_query(i, SIZE);
+        results.push_back(transport.query(makeSlice(queries[i])));
+    }
+    for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
+        auto r = results[i].get();
+        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
+        EXPECT_EQ(queries[i], r.response);
+    }
+}
+
+TEST_F(TransportTest, IdExhaustion) {
+    const int num_queries = 65536;
+    // A delay of 65537 is unreachable, because the maximum number
+    // of outstanding queries is 65536.
+    FakeSocketDelay::sDelay = num_queries + 1;
+    FakeSocketDelay::sReverse = false;
+    FakeSocketFactory<FakeSocketDelay> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    std::vector<std::future<DnsTlsTransport::Result>> results;
+    // Issue the maximum number of queries.
+    results.reserve(num_queries);
+    for (int i = 0; i < num_queries; ++i) {
+        results.push_back(transport.query(makeSlice(QUERY)));
+    }
+
+    // The ID space is now full, so subsequent queries should fail immediately.
+    auto r = transport.query(makeSlice(QUERY)).get();
+    EXPECT_EQ(DnsTlsTransport::Response::internal_error, r.code);
+    EXPECT_TRUE(r.response.empty());
+
+    for (auto& result : results) {
+        // All other queries should remain outstanding.
+        EXPECT_EQ(std::future_status::timeout,
+                result.wait_for(std::chrono::duration<int>::zero()));
+    }
+}
+
+// Responses can come back from the server in any order.  This should have no
+// effect on Transport's observed behavior.
+TEST_F(TransportTest, ReverseOrder) {
+    FakeSocketDelay::sDelay = 10;
+    FakeSocketDelay::sReverse = true;
+    FakeSocketFactory<FakeSocketDelay> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    std::vector<bytevec> queries(FakeSocketDelay::sDelay);
+    std::vector<std::future<DnsTlsTransport::Result>> results;
+    results.reserve(FakeSocketDelay::sDelay);
+    for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
+        queries[i] = make_query(i, SIZE);
+        results.push_back(transport.query(makeSlice(queries[i])));
+    }
+    for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
+        auto r = results[i].get();
+        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
+        EXPECT_EQ(queries[i], r.response);
+    }
+}
+
+TEST_F(TransportTest, ReverseOrder_Max) {
+    FakeSocketDelay::sDelay = 65536;
+    FakeSocketDelay::sReverse = true;
+    FakeSocketFactory<FakeSocketDelay> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    std::vector<bytevec> queries(FakeSocketDelay::sDelay);
+    std::vector<std::future<DnsTlsTransport::Result>> results;
+    results.reserve(FakeSocketDelay::sDelay);
+    for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
+        queries[i] = make_query(i, SIZE);
+        results.push_back(transport.query(makeSlice(queries[i])));
+    }
+    for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
+        auto r = results[i].get();
+        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
+        EXPECT_EQ(queries[i], r.response);
+    }
+}
+
+// Returning null from the factory indicates a connection failure.
+class NullSocketFactory : public IDnsTlsSocketFactory {
+  public:
+    NullSocketFactory() {}
+    std::unique_ptr<IDnsTlsSocket> createDnsTlsSocket(
+            const DnsTlsServer& server ATTRIBUTE_UNUSED,
+            unsigned mark ATTRIBUTE_UNUSED,
+            IDnsTlsSocketObserver* observer ATTRIBUTE_UNUSED,
+            DnsTlsSessionCache* cache ATTRIBUTE_UNUSED) override {
+        return nullptr;
+    }
+};
+
+TEST_F(TransportTest, ConnectFail) {
+    NullSocketFactory factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    auto r = transport.query(makeSlice(QUERY)).get();
+
+    EXPECT_EQ(DnsTlsTransport::Response::network_error, r.code);
+    EXPECT_TRUE(r.response.empty());
+}
+
+// Simulate a socket that connects but then immediately receives a server
+// close notification.
+class FakeSocketClose : public IDnsTlsSocket {
+  public:
+    explicit FakeSocketClose(IDnsTlsSocketObserver* observer)
+        : mCloser(&IDnsTlsSocketObserver::onClosed, observer) {}
+    ~FakeSocketClose() { mCloser.join(); }
+    bool query(uint16_t id ATTRIBUTE_UNUSED,
+               const Slice query ATTRIBUTE_UNUSED) override {
+        return true;
+    }
+
+  private:
+    std::thread mCloser;
+};
+
+TEST_F(TransportTest, CloseRetryFail) {
+    FakeSocketFactory<FakeSocketClose> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    auto r = transport.query(makeSlice(QUERY)).get();
+
+    EXPECT_EQ(DnsTlsTransport::Response::network_error, r.code);
+    EXPECT_TRUE(r.response.empty());
+}
+
+// Simulate a server that occasionally closes the connection and silently
+// drops some queries.
+class FakeSocketLimited : public IDnsTlsSocket {
+  public:
+    static int sLimit;  // Number of queries to answer per socket.
+    static size_t sMaxSize;  // Silently discard queries greater than this size.
+    explicit FakeSocketLimited(IDnsTlsSocketObserver* observer)
+        : mObserver(observer), mQueries(0) {}
+    ~FakeSocketLimited() {
+        {
+            ALOGV("~FakeSocketLimited acquiring mLock");
+            std::lock_guard guard(mLock);
+            ALOGV("~FakeSocketLimited acquired mLock");
+            for (auto& thread : mThreads) {
+                ALOGV("~FakeSocketLimited joining response thread");
+                thread.join();
+                ALOGV("~FakeSocketLimited joined response thread");
+            }
+            mThreads.clear();
+        }
+
+        if (mCloser) {
+            ALOGV("~FakeSocketLimited joining closer thread");
+            mCloser->join();
+            ALOGV("~FakeSocketLimited joined closer thread");
+        }
+    }
+    bool query(uint16_t id, const Slice query) override {
+        ALOGV("FakeSocketLimited::query acquiring mLock");
+        std::lock_guard guard(mLock);
+        ALOGV("FakeSocketLimited::query acquired mLock");
+        ++mQueries;
+
+        if (mQueries <= sLimit) {
+            ALOGV("size %zu vs. limit of %zu", query.size(), sMaxSize);
+            if (query.size() <= sMaxSize) {
+                // Return the response immediately (asynchronously).
+                mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, make_echo(id, query));
+            }
+        }
+        if (mQueries == sLimit) {
+            mCloser = std::make_unique<std::thread>(&FakeSocketLimited::sendClose, this);
+        }
+        return mQueries <= sLimit;
+    }
+
+  private:
+    void sendClose() {
+        {
+            ALOGV("FakeSocketLimited::sendClose acquiring mLock");
+            std::lock_guard guard(mLock);
+            ALOGV("FakeSocketLimited::sendClose acquired mLock");
+            for (auto& thread : mThreads) {
+                ALOGV("FakeSocketLimited::sendClose joining response thread");
+                thread.join();
+                ALOGV("FakeSocketLimited::sendClose joined response thread");
+            }
+            mThreads.clear();
+        }
+        mObserver->onClosed();
+    }
+    std::mutex mLock;
+    IDnsTlsSocketObserver* const mObserver;
+    int mQueries GUARDED_BY(mLock);
+    std::vector<std::thread> mThreads GUARDED_BY(mLock);
+    std::unique_ptr<std::thread> mCloser GUARDED_BY(mLock);
+};
+
+int FakeSocketLimited::sLimit;
+size_t FakeSocketLimited::sMaxSize;
+
+TEST_F(TransportTest, SilentDrop) {
+    FakeSocketLimited::sLimit = 10;  // Close the socket after 10 queries.
+    FakeSocketLimited::sMaxSize = 0;  // Silently drop all queries
+    FakeSocketFactory<FakeSocketLimited> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+
+    // Queue up 10 queries.  They will all be ignored, and after the 10th,
+    // the socket will close.  Transport will retry them all, until they
+    // all hit the retry limit and expire.
+    std::vector<std::future<DnsTlsTransport::Result>> results;
+    results.reserve(FakeSocketLimited::sLimit);
+    for (int i = 0; i < FakeSocketLimited::sLimit; ++i) {
+        results.push_back(transport.query(makeSlice(QUERY)));
+    }
+    for (auto& result : results) {
+        auto r = result.get();
+        EXPECT_EQ(DnsTlsTransport::Response::network_error, r.code);
+        EXPECT_TRUE(r.response.empty());
+    }
+}
+
+TEST_F(TransportTest, PartialDrop) {
+    FakeSocketLimited::sLimit = 10;  // Close the socket after 10 queries.
+    FakeSocketLimited::sMaxSize = SIZE - 2;  // Silently drop "long" queries
+    FakeSocketFactory<FakeSocketLimited> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+
+    // Queue up 100 queries, alternating "short" which will be served and "long"
+    // which will be dropped.
+    const int num_queries = 10 * FakeSocketLimited::sLimit;
+    std::vector<bytevec> queries(num_queries);
+    std::vector<std::future<DnsTlsTransport::Result>> results;
+    results.reserve(num_queries);
+    for (int i = 0; i < num_queries; ++i) {
+        queries[i] = make_query(i, SIZE + (i % 2));
+        results.push_back(transport.query(makeSlice(queries[i])));
+    }
+    // Just check the short queries, which are at the even indices.
+    for (int i = 0; i < num_queries; i += 2) {
+        auto r = results[i].get();
+        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
+        EXPECT_EQ(queries[i], r.response);
+    }
+}
+
+// Simulate a malfunctioning server that injects extra miscellaneous
+// responses to queries that were not asked.  This will cause wrong answers but
+// must not crash the Transport.
+class FakeSocketGarbage : public IDnsTlsSocket {
+  public:
+    explicit FakeSocketGarbage(IDnsTlsSocketObserver* observer) : mObserver(observer) {
+        // Inject a garbage event.
+        mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, make_query(ID + 1, SIZE));
+    }
+    ~FakeSocketGarbage() {
+        std::lock_guard guard(mLock);
+        for (auto& thread : mThreads) {
+            thread.join();
+        }
+    }
+    bool query(uint16_t id, const Slice query) override {
+        std::lock_guard guard(mLock);
+        // Return the response twice.
+        auto echo = make_echo(id, query);
+        mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, echo);
+        mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, echo);
+        // Also return some other garbage
+        mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, make_query(id + 1, query.size() + 2));
+        return true;
+    }
+
+  private:
+    std::mutex mLock;
+    std::vector<std::thread> mThreads GUARDED_BY(mLock);
+    IDnsTlsSocketObserver* const mObserver;
+};
+
+TEST_F(TransportTest, IgnoringGarbage) {
+    FakeSocketFactory<FakeSocketGarbage> factory;
+    DnsTlsTransport transport(SERVER1, MARK, &factory);
+    for (int i = 0; i < 10; ++i) {
+        auto r = transport.query(makeSlice(QUERY)).get();
+
+        EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
+        // Don't check the response because this server is malfunctioning.
+    }
+}
+
+// Dispatcher tests
+class DispatcherTest : public BaseTest {};
+
+TEST_F(DispatcherTest, Query) {
+    bytevec ans(4096);
+    int resplen = 0;
+
+    auto factory = std::make_unique<FakeSocketFactory<FakeSocketEcho>>();
+    DnsTlsDispatcher dispatcher(std::move(factory));
+    auto r = dispatcher.query(SERVER1, MARK, makeSlice(QUERY),
+                              makeSlice(ans), &resplen);
+
+    EXPECT_EQ(DnsTlsTransport::Response::success, r);
+    EXPECT_EQ(int(QUERY.size()), resplen);
+    ans.resize(resplen);
+    EXPECT_EQ(QUERY, ans);
+}
+
+TEST_F(DispatcherTest, AnswerTooLarge) {
+    bytevec ans(SIZE - 1);  // Too small to hold the answer
+    int resplen = 0;
+
+    auto factory = std::make_unique<FakeSocketFactory<FakeSocketEcho>>();
+    DnsTlsDispatcher dispatcher(std::move(factory));
+    auto r = dispatcher.query(SERVER1, MARK, makeSlice(QUERY),
+                              makeSlice(ans), &resplen);
+
+    EXPECT_EQ(DnsTlsTransport::Response::limit_error, r);
+}
+
+template<class T>
+class TrackingFakeSocketFactory : public IDnsTlsSocketFactory {
+  public:
+    TrackingFakeSocketFactory() {}
+    std::unique_ptr<IDnsTlsSocket> createDnsTlsSocket(
+            const DnsTlsServer& server,
+            unsigned mark,
+            IDnsTlsSocketObserver* observer,
+            DnsTlsSessionCache* cache ATTRIBUTE_UNUSED) override {
+        std::lock_guard guard(mLock);
+        keys.emplace(mark, server);
+        return std::make_unique<T>(observer);
+    }
+    std::multiset<std::pair<unsigned, DnsTlsServer>> keys;
+
+  private:
+    std::mutex mLock;
+};
+
+TEST_F(DispatcherTest, Dispatching) {
+    FakeSocketDelay::sDelay = 5;
+    FakeSocketDelay::sReverse = true;
+    auto factory = std::make_unique<TrackingFakeSocketFactory<FakeSocketDelay>>();
+    auto* weak_factory = factory.get();  // Valid as long as dispatcher is in scope.
+    DnsTlsDispatcher dispatcher(std::move(factory));
+
+    // Populate a vector of two servers and two socket marks, four combinations
+    // in total.
+    std::vector<std::pair<unsigned, DnsTlsServer>> keys;
+    keys.emplace_back(MARK, SERVER1);
+    keys.emplace_back(MARK + 1, SERVER1);
+    keys.emplace_back(MARK, V4ADDR2);
+    keys.emplace_back(MARK + 1, V4ADDR2);
+
+    // Do several queries on each server.  They should all succeed.
+    std::vector<std::thread> threads;
+    for (size_t i = 0; i < FakeSocketDelay::sDelay * keys.size(); ++i) {
+        auto key = keys[i % keys.size()];
+        threads.emplace_back([key, i] (DnsTlsDispatcher* dispatcher) {
+            auto q = make_query(i, SIZE);
+            bytevec ans(4096);
+            int resplen = 0;
+            unsigned mark = key.first;
+            const DnsTlsServer& server = key.second;
+            auto r = dispatcher->query(server, mark, makeSlice(q),
+                                       makeSlice(ans), &resplen);
+            EXPECT_EQ(DnsTlsTransport::Response::success, r);
+            EXPECT_EQ(int(q.size()), resplen);
+            ans.resize(resplen);
+            EXPECT_EQ(q, ans);
+        }, &dispatcher);
+    }
+    for (auto& thread : threads) {
+        thread.join();
+    }
+    // We expect that the factory created one socket for each key.
+    EXPECT_EQ(keys.size(), weak_factory->keys.size());
+    for (auto& key : keys) {
+        EXPECT_EQ(1U, weak_factory->keys.count(key));
+    }
+}
+
+// Check DnsTlsServer's comparison logic.
+AddressComparator ADDRESS_COMPARATOR;
+bool isAddressEqual(const DnsTlsServer& s1, const DnsTlsServer& s2) {
+    bool cmp1 = ADDRESS_COMPARATOR(s1, s2);
+    bool cmp2 = ADDRESS_COMPARATOR(s2, s1);
+    EXPECT_FALSE(cmp1 && cmp2);
+    return !cmp1 && !cmp2;
+}
+
+void checkUnequal(const DnsTlsServer& s1, const DnsTlsServer& s2) {
+    EXPECT_TRUE(s1 == s1);
+    EXPECT_TRUE(s2 == s2);
+    EXPECT_TRUE(isAddressEqual(s1, s1));
+    EXPECT_TRUE(isAddressEqual(s2, s2));
+
+    EXPECT_TRUE(s1 < s2 ^ s2 < s1);
+    EXPECT_FALSE(s1 == s2);
+    EXPECT_FALSE(s2 == s1);
+}
+
+class ServerTest : public BaseTest {};
+
+TEST_F(ServerTest, IPv4) {
+    checkUnequal(V4ADDR1, V4ADDR2);
+    EXPECT_FALSE(isAddressEqual(V4ADDR1, V4ADDR2));
+}
+
+TEST_F(ServerTest, IPv6) {
+    checkUnequal(V6ADDR1, V6ADDR2);
+    EXPECT_FALSE(isAddressEqual(V6ADDR1, V6ADDR2));
+}
+
+TEST_F(ServerTest, MixedAddressFamily) {
+    checkUnequal(V6ADDR1, V4ADDR1);
+    EXPECT_FALSE(isAddressEqual(V6ADDR1, V4ADDR1));
+}
+
+TEST_F(ServerTest, IPv6ScopeId) {
+    DnsTlsServer s1(V6ADDR1), s2(V6ADDR1);
+    sockaddr_in6* addr1 = reinterpret_cast<sockaddr_in6*>(&s1.ss);
+    addr1->sin6_scope_id = 1;
+    sockaddr_in6* addr2 = reinterpret_cast<sockaddr_in6*>(&s2.ss);
+    addr2->sin6_scope_id = 2;
+    checkUnequal(s1, s2);
+    EXPECT_FALSE(isAddressEqual(s1, s2));
+
+    EXPECT_FALSE(s1.wasExplicitlyConfigured());
+    EXPECT_FALSE(s2.wasExplicitlyConfigured());
+}
+
+TEST_F(ServerTest, IPv6FlowInfo) {
+    DnsTlsServer s1(V6ADDR1), s2(V6ADDR1);
+    sockaddr_in6* addr1 = reinterpret_cast<sockaddr_in6*>(&s1.ss);
+    addr1->sin6_flowinfo = 1;
+    sockaddr_in6* addr2 = reinterpret_cast<sockaddr_in6*>(&s2.ss);
+    addr2->sin6_flowinfo = 2;
+    // All comparisons ignore flowinfo.
+    EXPECT_EQ(s1, s2);
+    EXPECT_TRUE(isAddressEqual(s1, s2));
+
+    EXPECT_FALSE(s1.wasExplicitlyConfigured());
+    EXPECT_FALSE(s2.wasExplicitlyConfigured());
+}
+
+TEST_F(ServerTest, Port) {
+    DnsTlsServer s1, s2;
+    parseServer("192.0.2.1", 853, &s1.ss);
+    parseServer("192.0.2.1", 854, &s2.ss);
+    checkUnequal(s1, s2);
+    EXPECT_TRUE(isAddressEqual(s1, s2));
+
+    DnsTlsServer s3, s4;
+    parseServer("2001:db8::1", 853, &s3.ss);
+    parseServer("2001:db8::1", 852, &s4.ss);
+    checkUnequal(s3, s4);
+    EXPECT_TRUE(isAddressEqual(s3, s4));
+
+    EXPECT_FALSE(s1.wasExplicitlyConfigured());
+    EXPECT_FALSE(s2.wasExplicitlyConfigured());
+}
+
+TEST_F(ServerTest, Name) {
+    DnsTlsServer s1(V4ADDR1), s2(V4ADDR1);
+    s1.name = SERVERNAME1;
+    checkUnequal(s1, s2);
+    s2.name = SERVERNAME2;
+    checkUnequal(s1, s2);
+    EXPECT_TRUE(isAddressEqual(s1, s2));
+
+    EXPECT_TRUE(s1.wasExplicitlyConfigured());
+    EXPECT_TRUE(s2.wasExplicitlyConfigured());
+}
+
+TEST_F(ServerTest, Fingerprint) {
+    DnsTlsServer s1(V4ADDR1), s2(V4ADDR1);
+
+    s1.fingerprints.insert(FINGERPRINT1);
+    checkUnequal(s1, s2);
+    EXPECT_TRUE(isAddressEqual(s1, s2));
+
+    s2.fingerprints.insert(FINGERPRINT2);
+    checkUnequal(s1, s2);
+    EXPECT_TRUE(isAddressEqual(s1, s2));
+
+    s2.fingerprints.insert(FINGERPRINT1);
+    checkUnequal(s1, s2);
+    EXPECT_TRUE(isAddressEqual(s1, s2));
+
+    s1.fingerprints.insert(FINGERPRINT2);
+    EXPECT_EQ(s1, s2);
+    EXPECT_TRUE(isAddressEqual(s1, s2));
+
+    EXPECT_TRUE(s1.wasExplicitlyConfigured());
+    EXPECT_TRUE(s2.wasExplicitlyConfigured());
+}
+
+TEST(QueryMapTest, Basic) {
+    DnsTlsQueryMap map;
+
+    EXPECT_TRUE(map.empty());
+
+    bytevec q0 = make_query(999, SIZE);
+    bytevec q1 = make_query(888, SIZE);
+    bytevec q2 = make_query(777, SIZE);
+
+    auto f0 = map.recordQuery(makeSlice(q0));
+    auto f1 = map.recordQuery(makeSlice(q1));
+    auto f2 = map.recordQuery(makeSlice(q2));
+
+    // Check return values of recordQuery
+    EXPECT_EQ(0, f0->query.newId);
+    EXPECT_EQ(1, f1->query.newId);
+    EXPECT_EQ(2, f2->query.newId);
+
+    // Check side effects of recordQuery
+    EXPECT_FALSE(map.empty());
+
+    auto all = map.getAll();
+    EXPECT_EQ(3U, all.size());
+
+    EXPECT_EQ(0, all[0].newId);
+    EXPECT_EQ(1, all[1].newId);
+    EXPECT_EQ(2, all[2].newId);
+
+    EXPECT_EQ(makeSlice(q0), all[0].query);
+    EXPECT_EQ(makeSlice(q1), all[1].query);
+    EXPECT_EQ(makeSlice(q2), all[2].query);
+
+    bytevec a0 = make_query(0, SIZE);
+    bytevec a1 = make_query(1, SIZE);
+    bytevec a2 = make_query(2, SIZE);
+
+    // Return responses out of order
+    map.onResponse(a2);
+    map.onResponse(a0);
+    map.onResponse(a1);
+
+    EXPECT_TRUE(map.empty());
+
+    auto r0 = f0->result.get();
+    auto r1 = f1->result.get();
+    auto r2 = f2->result.get();
+
+    EXPECT_EQ(DnsTlsQueryMap::Response::success, r0.code);
+    EXPECT_EQ(DnsTlsQueryMap::Response::success, r1.code);
+    EXPECT_EQ(DnsTlsQueryMap::Response::success, r2.code);
+
+    const bytevec& d0 = r0.response;
+    const bytevec& d1 = r1.response;
+    const bytevec& d2 = r2.response;
+
+    // The ID should match the query
+    EXPECT_EQ(999, d0[0] << 8 | d0[1]);
+    EXPECT_EQ(888, d1[0] << 8 | d1[1]);
+    EXPECT_EQ(777, d2[0] << 8 | d2[1]);
+    // The body should match the answer
+    EXPECT_EQ(bytevec(a0.begin() + 2, a0.end()), bytevec(d0.begin() + 2, d0.end()));
+    EXPECT_EQ(bytevec(a1.begin() + 2, a1.end()), bytevec(d1.begin() + 2, d1.end()));
+    EXPECT_EQ(bytevec(a2.begin() + 2, a2.end()), bytevec(d2.begin() + 2, d2.end()));
+}
+
+TEST(QueryMapTest, FillHole) {
+    DnsTlsQueryMap map;
+    std::vector<std::unique_ptr<DnsTlsQueryMap::QueryFuture>> futures(UINT16_MAX + 1);
+    for (uint32_t i = 0; i <= UINT16_MAX; ++i) {
+        futures[i] = map.recordQuery(makeSlice(QUERY));
+        ASSERT_TRUE(futures[i]);  // answers[i] should be nonnull.
+        EXPECT_EQ(i, futures[i]->query.newId);
+    }
+
+    // The map should now be full.
+    EXPECT_EQ(size_t(UINT16_MAX + 1), map.getAll().size());
+
+    // Trying to add another query should fail because the map is full.
+    EXPECT_FALSE(map.recordQuery(makeSlice(QUERY)));
+
+    // Send an answer to query 40000
+    auto answer = make_query(40000, SIZE);
+    map.onResponse(answer);
+    auto result = futures[40000]->result.get();
+    EXPECT_EQ(DnsTlsQueryMap::Response::success, result.code);
+    EXPECT_EQ(ID, result.response[0] << 8 | result.response[1]);
+    EXPECT_EQ(bytevec(answer.begin() + 2, answer.end()),
+              bytevec(result.response.begin() + 2, result.response.end()));
+
+    // There should now be room in the map.
+    EXPECT_EQ(size_t(UINT16_MAX), map.getAll().size());
+    auto f = map.recordQuery(makeSlice(QUERY));
+    ASSERT_TRUE(f);
+    EXPECT_EQ(40000, f->query.newId);
+
+    // The map should now be full again.
+    EXPECT_EQ(size_t(UINT16_MAX + 1), map.getAll().size());
+    EXPECT_FALSE(map.recordQuery(makeSlice(QUERY)));
+}
+
+class StubObserver : public IDnsTlsSocketObserver {
+  public:
+    bool closed = false;
+    void onResponse(std::vector<uint8_t>) override {}
+
+    void onClosed() override { closed = true; }
+};
+
+TEST(DnsTlsSocketTest, SlowDestructor) {
+    constexpr char tls_addr[] = "127.0.0.3";
+    constexpr char tls_port[] = "8530";  // High-numbered port so root isn't required.
+    // This test doesn't perform any queries, so the backend address can be invalid.
+    constexpr char backend_addr[] = "192.0.2.1";
+    constexpr char backend_port[] = "1";
+
+    test::DnsTlsFrontend tls(tls_addr, tls_port, backend_addr, backend_port);
+    ASSERT_TRUE(tls.startServer());
+
+    DnsTlsServer server;
+    parseServer(tls_addr, 8530, &server.ss);
+
+    StubObserver observer;
+    ASSERT_FALSE(observer.closed);
+    DnsTlsSessionCache cache;
+    auto socket = std::make_unique<DnsTlsSocket>(server, MARK, &observer, &cache);
+    ASSERT_TRUE(socket->initialize());
+
+    // Test: Time the socket destructor.  This should be fast.
+    auto before = std::chrono::steady_clock::now();
+    socket.reset();
+    auto after = std::chrono::steady_clock::now();
+    auto delay = after - before;
+    ALOGV("Shutdown took %lld ns", delay / std::chrono::nanoseconds{1});
+    EXPECT_TRUE(observer.closed);
+    // Shutdown should complete in milliseconds, but if the shutdown signal is lost
+    // it will wait for the timeout, which is expected to take 20seconds.
+    EXPECT_LT(delay, std::chrono::seconds{5});
+}
+
+} // end of namespace net
+} // end of namespace android
diff --git a/resolv/dnsresolver_binder_test.cpp b/resolv/dnsresolver_binder_test.cpp
new file mode 100644
index 0000000..97dea53
--- /dev/null
+++ b/resolv/dnsresolver_binder_test.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * binder_test.cpp - unit tests for netd binder RPCs.
+ */
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+
+#include <vector>
+
+#include <openssl/base64.h>
+
+#include <android-base/strings.h>
+#include <android/net/IDnsResolver.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <gmock/gmock-matchers.h>
+#include <gtest/gtest.h>
+#include <netdb.h>
+#include <netdutils/Stopwatch.h>
+#include "tests/BaseTestMetricsListener.h"
+#include "tests/TestMetrics.h"
+
+#include "NetdConstants.h"  // SHA256_SIZE
+#include "ResolverStats.h"
+#include "dns_responder.h"
+#include "dns_responder_client.h"
+
+namespace binder = android::binder;
+
+using android::IBinder;
+using android::IServiceManager;
+using android::ProcessState;
+using android::sp;
+using android::String16;
+using android::String8;
+using android::net::IDnsResolver;
+using android::net::ResolverParamsParcel;
+using android::net::ResolverStats;
+using android::net::metrics::INetdEventListener;
+using android::net::metrics::TestOnDnsEvent;
+using android::netdutils::Stopwatch;
+
+// TODO: make this dynamic and stop depending on implementation details.
+// Sync from TEST_NETID in dns_responder_client.cpp as resolver_test.cpp does.
+constexpr int TEST_NETID = 30;
+
+class DnsResolverBinderTest : public ::testing::Test {
+  public:
+    DnsResolverBinderTest() {
+        sp<IServiceManager> sm = android::defaultServiceManager();
+        sp<IBinder> binder = sm->getService(String16("dnsresolver"));
+        if (binder != nullptr) {
+            mDnsResolver = android::interface_cast<IDnsResolver>(binder);
+        }
+        // This could happen when the test isn't running as root, or if netd isn't running.
+        assert(nullptr != mDnsResolver.get());
+        // Create cache for test
+        mDnsResolver->createNetworkCache(TEST_NETID);
+    }
+
+    ~DnsResolverBinderTest() {
+        // Destroy cache for test
+        mDnsResolver->destroyNetworkCache(TEST_NETID);
+    }
+
+  protected:
+    sp<IDnsResolver> mDnsResolver;
+};
+
+class TimedOperation : public Stopwatch {
+  public:
+    explicit TimedOperation(const std::string& name) : mName(name) {}
+    virtual ~TimedOperation() { fprintf(stderr, "    %s: %6.1f ms\n", mName.c_str(), timeTaken()); }
+
+  private:
+    std::string mName;
+};
+
+namespace {
+
+std::string base64Encode(const std::vector<uint8_t>& input) {
+    size_t out_len;
+    EXPECT_EQ(1, EVP_EncodedLength(&out_len, input.size()));
+    // out_len includes the trailing NULL.
+    uint8_t output_bytes[out_len];
+    EXPECT_EQ(out_len - 1, EVP_EncodeBlock(output_bytes, input.data(), input.size()));
+    return std::string(reinterpret_cast<char*>(output_bytes));
+}
+
+// TODO: Convert tests to ResolverParamsParcel and delete this stub.
+ResolverParamsParcel makeResolverParamsParcel(int netId, const std::vector<int>& params,
+                                              const std::vector<std::string>& servers,
+                                              const std::vector<std::string>& domains,
+                                              const std::string& tlsHostname,
+                                              const std::vector<std::string>& tlsServers,
+                                              const std::vector<std::string>& tlsFingerprints) {
+    using android::net::IDnsResolver;
+    ResolverParamsParcel paramsParcel;
+
+    paramsParcel.netId = netId;
+    paramsParcel.sampleValiditySeconds = params[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY];
+    paramsParcel.successThreshold = params[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD];
+    paramsParcel.minSamples = params[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES];
+    paramsParcel.maxSamples = params[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES];
+    if (params.size() > IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC) {
+        paramsParcel.baseTimeoutMsec = params[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC];
+    } else {
+        paramsParcel.baseTimeoutMsec = 0;
+    }
+    if (params.size() > IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT) {
+        paramsParcel.retryCount = params[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT];
+    } else {
+        paramsParcel.retryCount = 0;
+    }
+    paramsParcel.servers = servers;
+    paramsParcel.domains = domains;
+    paramsParcel.tlsName = tlsHostname;
+    paramsParcel.tlsServers = tlsServers;
+    paramsParcel.tlsFingerprints = tlsFingerprints;
+
+    return paramsParcel;
+}
+
+}  // namespace
+
+TEST_F(DnsResolverBinderTest, IsAlive) {
+    TimedOperation t("isAlive RPC");
+    bool isAlive = false;
+    mDnsResolver->isAlive(&isAlive);
+    ASSERT_TRUE(isAlive);
+}
+
+// TODO: Move this test to resolver_test.cpp
+TEST_F(DnsResolverBinderTest, EventListener_onDnsEvent) {
+    // The test configs are used to trigger expected events. The expected results are defined in
+    // expectedResults.
+    static const struct TestConfig {
+        std::string hostname;
+        int returnCode;
+    } testConfigs[] = {
+            {"hi", 0 /*success*/},
+            {"nonexistent", EAI_NODATA},
+    };
+
+    // The expected results define expected event content for test verification.
+    static const std::vector<TestOnDnsEvent::TestResult> expectedResults = {
+            {TEST_NETID, INetdEventListener::EVENT_GETADDRINFO, 0 /*success*/, 1, "hi", "1.2.3.4"},
+            {TEST_NETID, INetdEventListener::EVENT_GETADDRINFO, EAI_NODATA, 0, "nonexistent", ""},
+    };
+
+    // Start the Binder thread pool.
+    // TODO: Consider doing this once if there has another event listener unit test.
+    android::ProcessState::self()->startThreadPool();
+
+    // Setup network.
+    // TODO: Setup device configuration and DNS responser server as resolver test does.
+    // Currently, leave DNS related configuration in this test because only it needs DNS
+    // client-server testing environment.
+    DnsResponderClient dnsClient;
+    dnsClient.SetUp();
+
+    // Setup DNS responder server.
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_srv[] = "53";
+    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
+    dns.addMapping("hi.example.com.", ns_type::ns_t_a, "1.2.3.4");
+    ASSERT_TRUE(dns.startServer());
+
+    // Setup DNS configuration.
+    const std::vector<std::string> test_servers = {listen_addr};
+    std::vector<std::string> test_domains = {"example.com"};
+    std::vector<int> test_params = {300 /*sample_validity*/, 25 /*success_threshold*/,
+                                    8 /*min_samples*/, 8 /*max_samples*/};
+
+    ASSERT_TRUE(dnsClient.SetResolversForNetwork(test_servers, test_domains, test_params));
+    dns.clearQueries();
+
+    // Register event listener.
+    android::sp<TestOnDnsEvent> testOnDnsEvent = new TestOnDnsEvent(expectedResults);
+    android::binder::Status status = mDnsResolver->registerEventListener(
+            android::interface_cast<INetdEventListener>(testOnDnsEvent));
+    ASSERT_TRUE(status.isOk()) << status.exceptionMessage();
+
+    // DNS queries.
+    // Once all expected events of expectedResults are received by the listener, the unit test will
+    // be notified. Otherwise, notified with a timeout expired failure.
+    auto& cv = testOnDnsEvent->getCv();
+    auto& cvMutex = testOnDnsEvent->getCvMutex();
+    {
+        std::unique_lock lock(cvMutex);
+
+        for (const auto& config : testConfigs) {
+            SCOPED_TRACE(config.hostname);
+
+            addrinfo* result = nullptr;
+            addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
+            int status = getaddrinfo(config.hostname.c_str(), nullptr, &hints, &result);
+            EXPECT_EQ(config.returnCode, status);
+
+            if (result) freeaddrinfo(result);
+        }
+
+        // Wait for receiving expected events.
+        EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lock, std::chrono::seconds(2)));
+    }
+
+    // Verify that all testcases are passed.
+    EXPECT_TRUE(testOnDnsEvent->isVerified());
+
+    dnsClient.TearDown();
+}
+
+TEST_F(DnsResolverBinderTest, SetResolverConfiguration_Tls) {
+    // Certificate fingerprints are no longer supported by the module.
+    SKIP_IF_RESOLVER_VERSION_NEWER_THAN(mDnsResolver, 2);
+
+    const std::vector<std::string> LOCALLY_ASSIGNED_DNS{"8.8.8.8", "2001:4860:4860::8888"};
+    std::vector<uint8_t> fp(SHA256_SIZE);
+    std::vector<uint8_t> short_fp(1);
+    std::vector<uint8_t> long_fp(SHA256_SIZE + 1);
+    std::vector<std::string> test_domains;
+    std::vector<int> test_params = {300, 25, 8, 8};
+    static const struct TestData {
+        const std::vector<std::string> servers;
+        const std::string tlsName;
+        const std::vector<std::vector<uint8_t>> tlsFingerprints;
+        const int expectedReturnCode;
+    } kTlsTestData[] = {
+            {{"192.0.2.1"}, "", {}, 0},
+            {{"2001:db8::2"}, "host.name", {}, 0},
+            {{"192.0.2.3"}, "@@@@", {fp}, 0},
+            {{"2001:db8::4"}, "", {fp}, 0},
+            {{}, "", {}, 0},
+            {{""}, "", {}, EINVAL},
+            {{"192.0.*.5"}, "", {}, EINVAL},
+            {{"2001:dg8::6"}, "", {}, EINVAL},
+            {{"2001:db8::c"}, "", {short_fp}, EINVAL},
+            {{"192.0.2.12"}, "", {long_fp}, EINVAL},
+            {{"2001:db8::e"}, "", {fp, fp, fp}, 0},
+            {{"192.0.2.14"}, "", {fp, short_fp}, EINVAL},
+    };
+
+    for (size_t i = 0; i < std::size(kTlsTestData); i++) {
+        const auto& td = kTlsTestData[i];
+
+        std::vector<std::string> fingerprints;
+        for (const auto& fingerprint : td.tlsFingerprints) {
+            fingerprints.push_back(base64Encode(fingerprint));
+        }
+        const auto resolverParams =
+                makeResolverParamsParcel(TEST_NETID, test_params, LOCALLY_ASSIGNED_DNS,
+                                         test_domains, td.tlsName, td.servers, fingerprints);
+        binder::Status status = mDnsResolver->setResolverConfiguration(resolverParams);
+
+        if (td.expectedReturnCode == 0) {
+            SCOPED_TRACE(String8::format("test case %zu should have passed", i));
+            SCOPED_TRACE(status.toString8());
+            EXPECT_EQ(0, status.exceptionCode());
+        } else {
+            SCOPED_TRACE(String8::format("test case %zu should have failed", i));
+            EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
+            EXPECT_EQ(td.expectedReturnCode, status.serviceSpecificErrorCode());
+        }
+    }
+}
+
+TEST_F(DnsResolverBinderTest, GetResolverInfo) {
+    std::vector<std::string> servers = {"127.0.0.1", "127.0.0.2"};
+    std::vector<std::string> domains = {"example.com"};
+    std::vector<int> testParams = {
+            300,     // sample validity in seconds
+            25,      // success threshod in percent
+            8,   8,  // {MIN,MAX}_SAMPLES
+            100,     // BASE_TIMEOUT_MSEC
+            2,       // retry count
+    };
+    const auto resolverParams =
+            makeResolverParamsParcel(TEST_NETID, testParams, servers, domains, "", {}, {});
+    binder::Status status = mDnsResolver->setResolverConfiguration(resolverParams);
+    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+
+    std::vector<std::string> res_servers;
+    std::vector<std::string> res_domains;
+    std::vector<std::string> res_tls_servers;
+    std::vector<int32_t> params32;
+    std::vector<int32_t> stats32;
+    std::vector<int32_t> wait_for_pending_req_timeout_count32{0};
+    status = mDnsResolver->getResolverInfo(TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
+                                           &params32, &stats32,
+                                           &wait_for_pending_req_timeout_count32);
+
+    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+    EXPECT_EQ(servers.size(), res_servers.size());
+    EXPECT_EQ(domains.size(), res_domains.size());
+    EXPECT_EQ(0U, res_tls_servers.size());
+    ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), testParams.size());
+    EXPECT_EQ(testParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
+              params32[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY]);
+    EXPECT_EQ(testParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
+              params32[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD]);
+    EXPECT_EQ(testParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES],
+              params32[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES]);
+    EXPECT_EQ(testParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES],
+              params32[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES]);
+    EXPECT_EQ(testParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
+              params32[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC]);
+
+    std::vector<ResolverStats> stats;
+    ResolverStats::decodeAll(stats32, &stats);
+
+    EXPECT_EQ(servers.size(), stats.size());
+
+    EXPECT_THAT(res_servers, testing::UnorderedElementsAreArray(servers));
+    EXPECT_THAT(res_domains, testing::UnorderedElementsAreArray(domains));
+}
+
+TEST_F(DnsResolverBinderTest, CreateDestroyNetworkCache) {
+    // Must not be the same as TEST_NETID
+    const int ANOTHER_TEST_NETID = TEST_NETID + 1;
+
+    // Create a new network cache.
+    EXPECT_TRUE(mDnsResolver->createNetworkCache(ANOTHER_TEST_NETID).isOk());
+
+    // create it again, expect a EEXIST.
+    EXPECT_EQ(EEXIST,
+              mDnsResolver->createNetworkCache(ANOTHER_TEST_NETID).serviceSpecificErrorCode());
+
+    // destroy it.
+    EXPECT_TRUE(mDnsResolver->destroyNetworkCache(ANOTHER_TEST_NETID).isOk());
+
+    // re-create it
+    EXPECT_TRUE(mDnsResolver->createNetworkCache(ANOTHER_TEST_NETID).isOk());
+
+    // destroy it.
+    EXPECT_TRUE(mDnsResolver->destroyNetworkCache(ANOTHER_TEST_NETID).isOk());
+
+    // re-destroy it
+    EXPECT_TRUE(mDnsResolver->destroyNetworkCache(ANOTHER_TEST_NETID).isOk());
+}
+
+TEST_F(DnsResolverBinderTest, setLogSeverity) {
+    // Expect fail
+    EXPECT_EQ(EINVAL, mDnsResolver->setLogSeverity(-1).serviceSpecificErrorCode());
+
+    // Test set different log level
+    EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_VERBOSE).isOk());
+
+    EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_DEBUG).isOk());
+
+    EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_INFO).isOk());
+
+    EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_WARNING).isOk());
+
+    EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_ERROR).isOk());
+
+    // Set back to default
+    EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_WARNING).isOk());
+}
diff --git a/resolv/getaddrinfo.cpp b/resolv/getaddrinfo.cpp
new file mode 100644
index 0000000..bb9ef07
--- /dev/null
+++ b/resolv/getaddrinfo.cpp
@@ -0,0 +1,1832 @@
+/*	$NetBSD: getaddrinfo.c,v 1.82 2006/03/25 12:09:40 rpaulo Exp $	*/
+/*	$KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define LOG_TAG "getaddrinfo"
+
+#include "getaddrinfo.h"
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+
+#include "netd_resolv/resolv.h"
+#include "resolv_cache.h"
+#include "resolv_private.h"
+
+#define ANY 0
+
+using android::net::NetworkDnsEventReported;
+
+const char in_addrany[] = {0, 0, 0, 0};
+const char in_loopback[] = {127, 0, 0, 1};
+const char in6_addrany[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const char in6_loopback[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+
+const struct afd {
+    int a_af;
+    int a_addrlen;
+    int a_socklen;
+    int a_off;
+    const char* a_addrany;
+    const char* a_loopback;
+    int a_scoped;
+} afdl[] = {
+        {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
+         offsetof(struct sockaddr_in6, sin6_addr), in6_addrany, in6_loopback, 1},
+        {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
+         offsetof(struct sockaddr_in, sin_addr), in_addrany, in_loopback, 0},
+        {0, 0, 0, 0, NULL, NULL, 0},
+};
+
+struct Explore {
+    int e_af;
+    int e_socktype;
+    int e_protocol;
+    int e_wild;
+#define WILD_AF(ex) ((ex).e_wild & 0x01)
+#define WILD_SOCKTYPE(ex) ((ex).e_wild & 0x02)
+#define WILD_PROTOCOL(ex) ((ex).e_wild & 0x04)
+};
+
+const Explore explore_options[] = {
+        {PF_INET6, SOCK_DGRAM, IPPROTO_UDP, 0x07},
+        {PF_INET6, SOCK_STREAM, IPPROTO_TCP, 0x07},
+        {PF_INET6, SOCK_RAW, ANY, 0x05},
+        {PF_INET, SOCK_DGRAM, IPPROTO_UDP, 0x07},
+        {PF_INET, SOCK_STREAM, IPPROTO_TCP, 0x07},
+        {PF_INET, SOCK_RAW, ANY, 0x05},
+        {PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, 0x07},
+        {PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0x07},
+        {PF_UNSPEC, SOCK_RAW, ANY, 0x05},
+};
+
+#define PTON_MAX 16
+#define MAXPACKET (8 * 1024)
+
+typedef union {
+    HEADER hdr;
+    u_char buf[MAXPACKET];
+} querybuf;
+
+struct res_target {
+    struct res_target* next;
+    const char* name;  /* domain name */
+    int qclass, qtype; /* class and type of query */
+    u_char* answer;    /* buffer to put answer */
+    int anslen;        /* size of answer buffer */
+    int n;             /* result length */
+};
+
+static int str2number(const char*);
+static int explore_fqdn(const struct addrinfo*, const char*, const char*, struct addrinfo**,
+                        const struct android_net_context*, NetworkDnsEventReported* event);
+static int explore_null(const struct addrinfo*, const char*, struct addrinfo**);
+static int explore_numeric(const struct addrinfo*, const char*, const char*, struct addrinfo**,
+                           const char*);
+static int explore_numeric_scope(const struct addrinfo*, const char*, const char*,
+                                 struct addrinfo**);
+static int get_canonname(const struct addrinfo*, struct addrinfo*, const char*);
+static struct addrinfo* get_ai(const struct addrinfo*, const struct afd*, const char*);
+static int get_portmatch(const struct addrinfo*, const char*);
+static int get_port(const struct addrinfo*, const char*, int);
+static const struct afd* find_afd(int);
+static int ip6_str2scopeid(const char*, struct sockaddr_in6*, u_int32_t*);
+
+static struct addrinfo* getanswer(const querybuf*, int, const char*, int, const struct addrinfo*,
+                                  int* herrno);
+static int dns_getaddrinfo(const char* name, const addrinfo* pai,
+                           const android_net_context* netcontext, addrinfo** rv,
+                           NetworkDnsEventReported* event);
+static void _sethtent(FILE**);
+static void _endhtent(FILE**);
+static struct addrinfo* _gethtent(FILE**, const char*, const struct addrinfo*);
+static bool files_getaddrinfo(const char* name, const addrinfo* pai, addrinfo** res);
+static int _find_src_addr(const struct sockaddr*, struct sockaddr*, unsigned, uid_t);
+
+static int res_queryN(const char* name, res_target* target, res_state res, int* herrno);
+static int res_searchN(const char* name, res_target* target, res_state res, int* herrno);
+static int res_querydomainN(const char* name, const char* domain, res_target* target, res_state res,
+                            int* herrno);
+
+const char* const ai_errlist[] = {
+        "Success",
+        "Address family for hostname not supported",    /* EAI_ADDRFAMILY */
+        "Temporary failure in name resolution",         /* EAI_AGAIN      */
+        "Invalid value for ai_flags",                   /* EAI_BADFLAGS   */
+        "Non-recoverable failure in name resolution",   /* EAI_FAIL       */
+        "ai_family not supported",                      /* EAI_FAMILY     */
+        "Memory allocation failure",                    /* EAI_MEMORY     */
+        "No address associated with hostname",          /* EAI_NODATA     */
+        "hostname nor servname provided, or not known", /* EAI_NONAME     */
+        "servname not supported for ai_socktype",       /* EAI_SERVICE    */
+        "ai_socktype not supported",                    /* EAI_SOCKTYPE   */
+        "System error returned in errno",               /* EAI_SYSTEM     */
+        "Invalid value for hints",                      /* EAI_BADHINTS	  */
+        "Resolved protocol is unknown",                 /* EAI_PROTOCOL   */
+        "Argument buffer overflow",                     /* EAI_OVERFLOW   */
+        "Unknown error",                                /* EAI_MAX        */
+};
+
+/* XXX macros that make external reference is BAD. */
+
+#define GET_AI(ai, afd, addr)                                \
+    do {                                                     \
+        /* external reference: pai, error, and label free */ \
+        (ai) = get_ai(pai, (afd), (addr));                   \
+        if ((ai) == NULL) {                                  \
+            error = EAI_MEMORY;                              \
+            goto free;                                       \
+        }                                                    \
+    } while (0)
+
+#define GET_PORT(ai, serv)                             \
+    do {                                               \
+        /* external reference: error and label free */ \
+        error = get_port((ai), (serv), 0);             \
+        if (error != 0) goto free;                     \
+    } while (0)
+
+#define MATCH_FAMILY(x, y, w) \
+    ((x) == (y) || ((w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
+#define MATCH(x, y, w) ((x) == (y) || ((w) && ((x) == ANY || (y) == ANY)))
+
+const char* gai_strerror(int ecode) {
+    if (ecode < 0 || ecode > EAI_MAX) ecode = EAI_MAX;
+    return ai_errlist[ecode];
+}
+
+void freeaddrinfo(struct addrinfo* ai) {
+    while (ai) {
+        struct addrinfo* next = ai->ai_next;
+        if (ai->ai_canonname) free(ai->ai_canonname);
+        // Also frees ai->ai_addr which points to extra space beyond addrinfo
+        free(ai);
+        ai = next;
+    }
+}
+
+static int str2number(const char* p) {
+    char* ep;
+    unsigned long v;
+
+    assert(p != NULL);
+
+    if (*p == '\0') return -1;
+    ep = NULL;
+    errno = 0;
+    v = strtoul(p, &ep, 10);
+    if (errno == 0 && ep && *ep == '\0' && v <= UINT_MAX)
+        return v;
+    else
+        return -1;
+}
+
+/*
+ * The following functions determine whether IPv4 or IPv6 connectivity is
+ * available in order to implement AI_ADDRCONFIG.
+ *
+ * Strictly speaking, AI_ADDRCONFIG should not look at whether connectivity is
+ * available, but whether addresses of the specified family are "configured
+ * on the local system". However, bionic doesn't currently support getifaddrs,
+ * so checking for connectivity is the next best thing.
+ */
+static int have_ipv6(unsigned mark, uid_t uid) {
+    static const struct sockaddr_in6 sin6_test = {
+            .sin6_family = AF_INET6,
+            .sin6_addr.s6_addr = {// 2000::
+                                  0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    sockaddr_union addr = {.sin6 = sin6_test};
+    return _find_src_addr(&addr.sa, NULL, mark, uid) == 1;
+}
+
+static int have_ipv4(unsigned mark, uid_t uid) {
+    static const struct sockaddr_in sin_test = {
+            .sin_family = AF_INET,
+            .sin_addr.s_addr = __constant_htonl(0x08080808L)  // 8.8.8.8
+    };
+    sockaddr_union addr = {.sin = sin_test};
+    return _find_src_addr(&addr.sa, NULL, mark, uid) == 1;
+}
+
+// Internal version of getaddrinfo(), but limited to AI_NUMERICHOST.
+// NOTE: also called by resolv_set_nameservers_for_net().
+int getaddrinfo_numeric(const char* hostname, const char* servname, addrinfo hints,
+                        addrinfo** result) {
+    hints.ai_flags = AI_NUMERICHOST;
+    const android_net_context netcontext = {
+            .app_netid = NETID_UNSET,
+            .app_mark = MARK_UNSET,
+            .dns_netid = NETID_UNSET,
+            .dns_mark = MARK_UNSET,
+            .uid = NET_CONTEXT_INVALID_UID,
+    };
+    NetworkDnsEventReported event;
+    return android_getaddrinfofornetcontext(hostname, servname, &hints, &netcontext, result,
+                                            &event);
+}
+
+int android_getaddrinfofornetcontext(const char* hostname, const char* servname,
+                                     const struct addrinfo* hints,
+                                     const struct android_net_context* netcontext,
+                                     struct addrinfo** res, NetworkDnsEventReported* event) {
+    struct addrinfo sentinel = {};
+    struct addrinfo* cur = &sentinel;
+    int error = 0;
+
+    // hostname is allowed to be nullptr
+    // servname is allowed to be nullptr
+    // hints is allowed to be nullptr
+    assert(res != nullptr);
+    assert(netcontext != nullptr);
+    assert(event != nullptr);
+
+    struct addrinfo ai = {
+            .ai_flags = 0,
+            .ai_family = PF_UNSPEC,
+            .ai_socktype = ANY,
+            .ai_protocol = ANY,
+            .ai_addrlen = 0,
+            .ai_canonname = nullptr,
+            .ai_addr = nullptr,
+            .ai_next = nullptr,
+    };
+
+    do {
+        if (hostname == NULL && servname == NULL) {
+            error = EAI_NONAME;
+            break;
+        }
+        if (hints) {
+            /* error check for hints */
+            if (hints->ai_addrlen || hints->ai_canonname || hints->ai_addr || hints->ai_next) {
+                error = EAI_BADHINTS;
+                break;
+            }
+            if (hints->ai_flags & ~AI_MASK) {
+                error = EAI_BADFLAGS;
+                break;
+            }
+
+            if (!(hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET ||
+                  hints->ai_family == PF_INET6)) {
+                error = EAI_FAMILY;
+                break;
+            }
+
+            ai = *hints;
+
+            /*
+             * if both socktype/protocol are specified, check if they
+             * are meaningful combination.
+             */
+            if (ai.ai_socktype != ANY && ai.ai_protocol != ANY) {
+                for (const Explore& ex : explore_options) {
+                    if (ai.ai_family != ex.e_af) continue;
+                    if (ex.e_socktype == ANY) continue;
+                    if (ex.e_protocol == ANY) continue;
+                    if (ai.ai_socktype == ex.e_socktype && ai.ai_protocol != ex.e_protocol) {
+                        error = EAI_BADHINTS;
+                        break;
+                    }
+                }
+                if (error) break;
+            }
+        }
+
+        /*
+         * Check for special cases:
+         * (1) numeric servname is disallowed if socktype/protocol are left unspecified.
+         * (2) servname is disallowed for raw and other inet{,6} sockets.
+         */
+        if (MATCH_FAMILY(ai.ai_family, PF_INET, 1) || MATCH_FAMILY(ai.ai_family, PF_INET6, 1)) {
+            struct addrinfo tmp = ai;
+            if (tmp.ai_family == PF_UNSPEC) {
+                tmp.ai_family = PF_INET6;
+            }
+            error = get_portmatch(&tmp, servname);
+            if (error) break;
+        }
+
+        // NULL hostname, or numeric hostname
+        for (const Explore& ex : explore_options) {
+            /* PF_UNSPEC entries are prepared for DNS queries only */
+            if (ex.e_af == PF_UNSPEC) continue;
+
+            if (!MATCH_FAMILY(ai.ai_family, ex.e_af, WILD_AF(ex))) continue;
+            if (!MATCH(ai.ai_socktype, ex.e_socktype, WILD_SOCKTYPE(ex))) continue;
+            if (!MATCH(ai.ai_protocol, ex.e_protocol, WILD_PROTOCOL(ex))) continue;
+
+            struct addrinfo tmp = ai;
+            if (tmp.ai_family == PF_UNSPEC) tmp.ai_family = ex.e_af;
+            if (tmp.ai_socktype == ANY && ex.e_socktype != ANY) tmp.ai_socktype = ex.e_socktype;
+            if (tmp.ai_protocol == ANY && ex.e_protocol != ANY) tmp.ai_protocol = ex.e_protocol;
+
+            LOG(DEBUG) << __func__ << ": explore_numeric: ai_family=" << tmp.ai_family
+                       << " ai_socktype=" << tmp.ai_socktype << " ai_protocol=" << tmp.ai_protocol;
+            if (hostname == nullptr)
+                error = explore_null(&tmp, servname, &cur->ai_next);
+            else
+                error = explore_numeric_scope(&tmp, hostname, servname, &cur->ai_next);
+
+            if (error) break;
+
+            while (cur->ai_next) cur = cur->ai_next;
+        }
+        if (error) break;
+
+        /*
+         * XXX
+         * If numeric representation of AF1 can be interpreted as FQDN
+         * representation of AF2, we need to think again about the code below.
+         */
+        if (sentinel.ai_next) break;
+
+        if (hostname == nullptr) {
+            error = EAI_NODATA;
+            break;
+        }
+        if (ai.ai_flags & AI_NUMERICHOST) {
+            error = EAI_NONAME;
+            break;
+        }
+
+        /*
+         * hostname as alphabetical name.
+         * We would like to prefer AF_INET6 over AF_INET, so we'll make a outer loop by AFs.
+         */
+        for (const Explore& ex : explore_options) {
+            // Require exact match for family field
+            if (ai.ai_family != ex.e_af) continue;
+
+            if (!MATCH(ai.ai_socktype, ex.e_socktype, WILD_SOCKTYPE(ex))) {
+                continue;
+            }
+            if (!MATCH(ai.ai_protocol, ex.e_protocol, WILD_PROTOCOL(ex))) {
+                continue;
+            }
+
+            struct addrinfo tmp = ai;
+            if (tmp.ai_socktype == ANY && ex.e_socktype != ANY) tmp.ai_socktype = ex.e_socktype;
+            if (tmp.ai_protocol == ANY && ex.e_protocol != ANY) tmp.ai_protocol = ex.e_protocol;
+
+            LOG(DEBUG) << __func__ << ": explore_fqdn(): ai_family=" << tmp.ai_family
+                       << " ai_socktype=" << tmp.ai_socktype << " ai_protocol=" << tmp.ai_protocol;
+            error = explore_fqdn(&tmp, hostname, servname, &cur->ai_next, netcontext, event);
+
+            while (cur->ai_next) cur = cur->ai_next;
+        }
+
+        if (sentinel.ai_next) {
+            error = 0;
+        } else if (error == 0) {
+            error = EAI_FAIL;
+        }
+    } while (0);
+
+    if (error) {
+        freeaddrinfo(sentinel.ai_next);
+        *res = nullptr;
+    } else {
+        *res = sentinel.ai_next;
+    }
+    return error;
+}
+
+// FQDN hostname, DNS lookup
+static int explore_fqdn(const struct addrinfo* pai, const char* hostname, const char* servname,
+                        struct addrinfo** res, const struct android_net_context* netcontext,
+                        NetworkDnsEventReported* event) {
+    struct addrinfo* result;
+    int error = 0;
+
+    assert(pai != NULL);
+    /* hostname may be NULL */
+    /* servname may be NULL */
+    assert(res != NULL);
+
+    result = NULL;
+
+    // If the servname does not match socktype/protocol, ignore it.
+    if (get_portmatch(pai, servname) != 0) return 0;
+
+    if (!files_getaddrinfo(hostname, pai, &result)) {
+        error = dns_getaddrinfo(hostname, pai, netcontext, &result, event);
+    }
+    if (!error) {
+        struct addrinfo* cur;
+        for (cur = result; cur; cur = cur->ai_next) {
+            GET_PORT(cur, servname);
+            /* canonname should be filled already */
+        }
+        *res = result;
+        return 0;
+    }
+
+free:
+    freeaddrinfo(result);
+    return error;
+}
+
+/*
+ * hostname == NULL.
+ * passive socket -> anyaddr (0.0.0.0 or ::)
+ * non-passive socket -> localhost (127.0.0.1 or ::1)
+ */
+static int explore_null(const struct addrinfo* pai, const char* servname, struct addrinfo** res) {
+    int s;
+    const struct afd* afd;
+    struct addrinfo* cur;
+    struct addrinfo sentinel;
+    int error;
+
+    LOG(DEBUG) << __func__;
+
+    assert(pai != NULL);
+    /* servname may be NULL */
+    assert(res != NULL);
+
+    *res = NULL;
+    sentinel.ai_next = NULL;
+    cur = &sentinel;
+
+    /*
+     * filter out AFs that are not supported by the kernel
+     * XXX errno?
+     */
+    s = socket(pai->ai_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    if (s < 0) {
+        if (errno != EMFILE) return 0;
+    } else
+        close(s);
+
+    /*
+     * if the servname does not match socktype/protocol, ignore it.
+     */
+    if (get_portmatch(pai, servname) != 0) return 0;
+
+    afd = find_afd(pai->ai_family);
+    if (afd == NULL) return 0;
+
+    if (pai->ai_flags & AI_PASSIVE) {
+        GET_AI(cur->ai_next, afd, afd->a_addrany);
+        GET_PORT(cur->ai_next, servname);
+    } else {
+        GET_AI(cur->ai_next, afd, afd->a_loopback);
+        GET_PORT(cur->ai_next, servname);
+    }
+    cur = cur->ai_next;
+
+    *res = sentinel.ai_next;
+    return 0;
+
+free:
+    freeaddrinfo(sentinel.ai_next);
+    return error;
+}
+
+/*
+ * numeric hostname
+ */
+static int explore_numeric(const struct addrinfo* pai, const char* hostname, const char* servname,
+                           struct addrinfo** res, const char* canonname) {
+    const struct afd* afd;
+    struct addrinfo* cur;
+    struct addrinfo sentinel;
+    int error;
+    char pton[PTON_MAX];
+
+    assert(pai != NULL);
+    /* hostname may be NULL */
+    /* servname may be NULL */
+    assert(res != NULL);
+
+    *res = NULL;
+    sentinel.ai_next = NULL;
+    cur = &sentinel;
+
+    /*
+     * if the servname does not match socktype/protocol, ignore it.
+     */
+    if (get_portmatch(pai, servname) != 0) return 0;
+
+    afd = find_afd(pai->ai_family);
+    if (afd == NULL) return 0;
+
+    if (inet_pton(afd->a_af, hostname, pton) == 1) {
+        if (pai->ai_family == afd->a_af || pai->ai_family == PF_UNSPEC /*?*/) {
+            GET_AI(cur->ai_next, afd, pton);
+            GET_PORT(cur->ai_next, servname);
+            if ((pai->ai_flags & AI_CANONNAME)) {
+                /*
+                 * Set the numeric address itself as
+                 * the canonical name, based on a
+                 * clarification in rfc2553bis-03.
+                 */
+                error = get_canonname(pai, cur->ai_next, canonname);
+                if (error != 0) {
+                    freeaddrinfo(sentinel.ai_next);
+                    return error;
+                }
+            }
+            while (cur->ai_next) cur = cur->ai_next;
+        } else
+            return EAI_FAMILY;
+    }
+
+    *res = sentinel.ai_next;
+    return 0;
+
+free:
+    freeaddrinfo(sentinel.ai_next);
+    return error;
+}
+
+/*
+ * numeric hostname with scope
+ */
+static int explore_numeric_scope(const struct addrinfo* pai, const char* hostname,
+                                 const char* servname, struct addrinfo** res) {
+    const struct afd* afd;
+    struct addrinfo* cur;
+    int error;
+    const char *cp, *scope, *addr;
+    struct sockaddr_in6* sin6;
+
+    LOG(DEBUG) << __func__;
+
+    assert(pai != NULL);
+    /* hostname may be NULL */
+    /* servname may be NULL */
+    assert(res != NULL);
+
+    /*
+     * if the servname does not match socktype/protocol, ignore it.
+     */
+    if (get_portmatch(pai, servname) != 0) return 0;
+
+    afd = find_afd(pai->ai_family);
+    if (afd == NULL) return 0;
+
+    if (!afd->a_scoped) return explore_numeric(pai, hostname, servname, res, hostname);
+
+    cp = strchr(hostname, SCOPE_DELIMITER);
+    if (cp == NULL) return explore_numeric(pai, hostname, servname, res, hostname);
+
+    /*
+     * Handle special case of <scoped_address><delimiter><scope id>
+     */
+    char* hostname2 = strdup(hostname);
+    if (hostname2 == NULL) return EAI_MEMORY;
+    /* terminate at the delimiter */
+    hostname2[cp - hostname] = '\0';
+    addr = hostname2;
+    scope = cp + 1;
+
+    error = explore_numeric(pai, addr, servname, res, hostname);
+    if (error == 0) {
+        u_int32_t scopeid;
+
+        for (cur = *res; cur; cur = cur->ai_next) {
+            if (cur->ai_family != AF_INET6) continue;
+            sin6 = (struct sockaddr_in6*) (void*) cur->ai_addr;
+            if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {
+                free(hostname2);
+                return (EAI_NODATA); /* XXX: is return OK? */
+            }
+            sin6->sin6_scope_id = scopeid;
+        }
+    }
+
+    free(hostname2);
+
+    return error;
+}
+
+static int get_canonname(const struct addrinfo* pai, struct addrinfo* ai, const char* str) {
+    assert(pai != NULL);
+    assert(ai != NULL);
+    assert(str != NULL);
+
+    if ((pai->ai_flags & AI_CANONNAME) != 0) {
+        ai->ai_canonname = strdup(str);
+        if (ai->ai_canonname == NULL) return EAI_MEMORY;
+    }
+    return 0;
+}
+
+static struct addrinfo* get_ai(const struct addrinfo* pai, const struct afd* afd,
+                               const char* addr) {
+    char* p;
+    struct addrinfo* ai;
+
+    assert(pai != NULL);
+    assert(afd != NULL);
+    assert(addr != NULL);
+
+    ai = (struct addrinfo*) malloc(sizeof(struct addrinfo) + sizeof(sockaddr_union));
+    if (ai == NULL) return NULL;
+
+    memcpy(ai, pai, sizeof(struct addrinfo));
+    ai->ai_addr = (struct sockaddr*) (void*) (ai + 1);
+    memset(ai->ai_addr, 0, sizeof(sockaddr_union));
+
+    ai->ai_addrlen = afd->a_socklen;
+    ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
+    p = (char*) (void*) (ai->ai_addr);
+    memcpy(p + afd->a_off, addr, (size_t) afd->a_addrlen);
+    return ai;
+}
+
+static int get_portmatch(const struct addrinfo* ai, const char* servname) {
+    assert(ai != NULL);
+    /* servname may be NULL */
+
+    return get_port(ai, servname, 1);
+}
+
+static int get_port(const struct addrinfo* ai, const char* servname, int matchonly) {
+    const char* proto;
+    struct servent* sp;
+    int port;
+    int allownumeric;
+
+    assert(ai != NULL);
+    /* servname may be NULL */
+
+    if (servname == NULL) return 0;
+    switch (ai->ai_family) {
+        case AF_INET:
+        case AF_INET6:
+            break;
+        default:
+            return 0;
+    }
+
+    switch (ai->ai_socktype) {
+        case SOCK_RAW:
+            return EAI_SERVICE;
+        case SOCK_DGRAM:
+        case SOCK_STREAM:
+            allownumeric = 1;
+            break;
+        case ANY:
+            allownumeric = 1;
+            break;
+        default:
+            return EAI_SOCKTYPE;
+    }
+
+    port = str2number(servname);
+    if (port >= 0) {
+        if (!allownumeric) return EAI_SERVICE;
+        if (port < 0 || port > 65535) return EAI_SERVICE;
+        port = htons(port);
+    } else {
+        if (ai->ai_flags & AI_NUMERICSERV) return EAI_NONAME;
+
+        switch (ai->ai_socktype) {
+            case SOCK_DGRAM:
+                proto = "udp";
+                break;
+            case SOCK_STREAM:
+                proto = "tcp";
+                break;
+            default:
+                proto = NULL;
+                break;
+        }
+
+        if ((sp = getservbyname(servname, proto)) == NULL) return EAI_SERVICE;
+        port = sp->s_port;
+    }
+
+    if (!matchonly) {
+        switch (ai->ai_family) {
+            case AF_INET:
+                ((struct sockaddr_in*) (void*) ai->ai_addr)->sin_port = port;
+                break;
+            case AF_INET6:
+                ((struct sockaddr_in6*) (void*) ai->ai_addr)->sin6_port = port;
+                break;
+        }
+    }
+
+    return 0;
+}
+
+static const struct afd* find_afd(int af) {
+    const struct afd* afd;
+
+    if (af == PF_UNSPEC) return NULL;
+    for (afd = afdl; afd->a_af; afd++) {
+        if (afd->a_af == af) return afd;
+    }
+    return NULL;
+}
+
+// Convert a string to a scope identifier.
+static int ip6_str2scopeid(const char* scope, struct sockaddr_in6* sin6, u_int32_t* scopeid) {
+    u_long lscopeid;
+    struct in6_addr* a6;
+    char* ep;
+
+    assert(scope != NULL);
+    assert(sin6 != NULL);
+    assert(scopeid != NULL);
+
+    a6 = &sin6->sin6_addr;
+
+    /* empty scopeid portion is invalid */
+    if (*scope == '\0') return -1;
+
+    if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) {
+        /*
+         * We currently assume a one-to-one mapping between links
+         * and interfaces, so we simply use interface indices for
+         * like-local scopes.
+         */
+        *scopeid = if_nametoindex(scope);
+        if (*scopeid == 0) goto trynumeric;
+        return 0;
+    }
+
+    /* still unclear about literal, allow numeric only - placeholder */
+    if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6)) goto trynumeric;
+    if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
+        goto trynumeric;
+    else
+        goto trynumeric; /* global */
+
+    /* try to convert to a numeric id as a last resort */
+trynumeric:
+    errno = 0;
+    lscopeid = strtoul(scope, &ep, 10);
+    *scopeid = (u_int32_t)(lscopeid & 0xffffffffUL);
+    if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid)
+        return 0;
+    else
+        return -1;
+}
+
+/* code duplicate with gethnamaddr.c */
+
+#define BOUNDED_INCR(x)      \
+    do {                     \
+        BOUNDS_CHECK(cp, x); \
+        cp += (x);           \
+    } while (0)
+
+#define BOUNDS_CHECK(ptr, count)     \
+    do {                             \
+        if (eom - (ptr) < (count)) { \
+            *herrno = NO_RECOVERY;   \
+            return NULL;             \
+        }                            \
+    } while (0)
+
+static struct addrinfo* getanswer(const querybuf* answer, int anslen, const char* qname, int qtype,
+                                  const struct addrinfo* pai, int* herrno) {
+    struct addrinfo sentinel = {};
+    struct addrinfo *cur;
+    struct addrinfo ai;
+    const struct afd* afd;
+    char* canonname;
+    const HEADER* hp;
+    const u_char* cp;
+    int n;
+    const u_char* eom;
+    char *bp, *ep;
+    int type, ancount, qdcount;
+    int haveanswer, had_error;
+    char tbuf[MAXDNAME];
+    int (*name_ok)(const char*);
+    char hostbuf[8 * 1024];
+
+    assert(answer != NULL);
+    assert(qname != NULL);
+    assert(pai != NULL);
+
+    cur = &sentinel;
+
+    canonname = NULL;
+    eom = answer->buf + anslen;
+    switch (qtype) {
+        case T_A:
+        case T_AAAA:
+        case T_ANY: /*use T_ANY only for T_A/T_AAAA lookup*/
+            name_ok = res_hnok;
+            break;
+        default:
+            return NULL; /* XXX should be abort(); */
+    }
+    /*
+     * find first satisfactory answer
+     */
+    hp = &answer->hdr;
+    ancount = ntohs(hp->ancount);
+    qdcount = ntohs(hp->qdcount);
+    bp = hostbuf;
+    ep = hostbuf + sizeof hostbuf;
+    cp = answer->buf;
+    BOUNDED_INCR(HFIXEDSZ);
+    if (qdcount != 1) {
+        *herrno = NO_RECOVERY;
+        return (NULL);
+    }
+    n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
+    if ((n < 0) || !(*name_ok)(bp)) {
+        *herrno = NO_RECOVERY;
+        return (NULL);
+    }
+    BOUNDED_INCR(n + QFIXEDSZ);
+    if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
+        /* res_send() has already verified that the query name is the
+         * same as the one we sent; this just gets the expanded name
+         * (i.e., with the succeeding search-domain tacked on).
+         */
+        n = strlen(bp) + 1; /* for the \0 */
+        if (n >= MAXHOSTNAMELEN) {
+            *herrno = NO_RECOVERY;
+            return (NULL);
+        }
+        canonname = bp;
+        bp += n;
+        /* The qname can be abbreviated, but h_name is now absolute. */
+        qname = canonname;
+    }
+    haveanswer = 0;
+    had_error = 0;
+    while (ancount-- > 0 && cp < eom && !had_error) {
+        n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
+        if ((n < 0) || !(*name_ok)(bp)) {
+            had_error++;
+            continue;
+        }
+        cp += n; /* name */
+        BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
+        type = ntohs(*reinterpret_cast<const uint16_t*>(cp));
+        cp += INT16SZ; /* type */
+        int cl = ntohs(*reinterpret_cast<const uint16_t*>(cp));
+        cp += INT16SZ + INT32SZ; /* class, TTL */
+        n = ntohs(*reinterpret_cast<const uint16_t*>(cp));
+        cp += INT16SZ; /* len */
+        BOUNDS_CHECK(cp, n);
+        if (cl != C_IN) {
+            /* XXX - debug? syslog? */
+            cp += n;
+            continue; /* XXX - had_error++ ? */
+        }
+        if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) && type == T_CNAME) {
+            n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
+            if ((n < 0) || !(*name_ok)(tbuf)) {
+                had_error++;
+                continue;
+            }
+            cp += n;
+            /* Get canonical name. */
+            n = strlen(tbuf) + 1; /* for the \0 */
+            if (n > ep - bp || n >= MAXHOSTNAMELEN) {
+                had_error++;
+                continue;
+            }
+            strlcpy(bp, tbuf, (size_t)(ep - bp));
+            canonname = bp;
+            bp += n;
+            continue;
+        }
+        if (qtype == T_ANY) {
+            if (!(type == T_A || type == T_AAAA)) {
+                cp += n;
+                continue;
+            }
+        } else if (type != qtype) {
+            if (type != T_KEY && type != T_SIG)
+                LOG(DEBUG) << __func__ << ": asked for \"" << qname << " " << p_class(C_IN) << " "
+                           << p_type(qtype) << "\", got type \"" << p_type(type) << "\"";
+            cp += n;
+            continue; /* XXX - had_error++ ? */
+        }
+        switch (type) {
+            case T_A:
+            case T_AAAA:
+                if (strcasecmp(canonname, bp) != 0) {
+                    LOG(DEBUG) << __func__ << ": asked for \"" << canonname << "\", got \"" << bp
+                               << "\"";
+                    cp += n;
+                    continue; /* XXX - had_error++ ? */
+                }
+                if (type == T_A && n != INADDRSZ) {
+                    cp += n;
+                    continue;
+                }
+                if (type == T_AAAA && n != IN6ADDRSZ) {
+                    cp += n;
+                    continue;
+                }
+                if (type == T_AAAA) {
+                    struct in6_addr in6;
+                    memcpy(&in6, cp, IN6ADDRSZ);
+                    if (IN6_IS_ADDR_V4MAPPED(&in6)) {
+                        cp += n;
+                        continue;
+                    }
+                }
+                if (!haveanswer) {
+                    int nn;
+
+                    canonname = bp;
+                    nn = strlen(bp) + 1; /* for the \0 */
+                    bp += nn;
+                }
+
+                /* don't overwrite pai */
+                ai = *pai;
+                ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
+                afd = find_afd(ai.ai_family);
+                if (afd == NULL) {
+                    cp += n;
+                    continue;
+                }
+                cur->ai_next = get_ai(&ai, afd, (const char*) cp);
+                if (cur->ai_next == NULL) had_error++;
+                while (cur && cur->ai_next) cur = cur->ai_next;
+                cp += n;
+                break;
+            default:
+                abort();
+        }
+        if (!had_error) haveanswer++;
+    }
+    if (haveanswer) {
+        if (!canonname)
+            (void) get_canonname(pai, sentinel.ai_next, qname);
+        else
+            (void) get_canonname(pai, sentinel.ai_next, canonname);
+        *herrno = NETDB_SUCCESS;
+        return sentinel.ai_next;
+    }
+
+    *herrno = NO_RECOVERY;
+    return NULL;
+}
+
+struct addrinfo_sort_elem {
+    struct addrinfo* ai;
+    int has_src_addr;
+    sockaddr_union src_addr;
+    int original_order;
+};
+
+static int _get_scope(const struct sockaddr* addr) {
+    if (addr->sa_family == AF_INET6) {
+        const struct sockaddr_in6* addr6 = (const struct sockaddr_in6*) addr;
+        if (IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr)) {
+            return IPV6_ADDR_MC_SCOPE(&addr6->sin6_addr);
+        } else if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr) ||
+                   IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)) {
+            /*
+             * RFC 4291 section 2.5.3 says loopback is to be treated as having
+             * link-local scope.
+             */
+            return IPV6_ADDR_SCOPE_LINKLOCAL;
+        } else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
+            return IPV6_ADDR_SCOPE_SITELOCAL;
+        } else {
+            return IPV6_ADDR_SCOPE_GLOBAL;
+        }
+    } else if (addr->sa_family == AF_INET) {
+        const struct sockaddr_in* addr4 = (const struct sockaddr_in*) addr;
+        unsigned long int na = ntohl(addr4->sin_addr.s_addr);
+
+        if (IN_LOOPBACK(na) ||                 /* 127.0.0.0/8 */
+            (na & 0xffff0000) == 0xa9fe0000) { /* 169.254.0.0/16 */
+            return IPV6_ADDR_SCOPE_LINKLOCAL;
+        } else {
+            /*
+             * RFC 6724 section 3.2. Other IPv4 addresses, including private addresses
+             * and shared addresses (100.64.0.0/10), are assigned global scope.
+             */
+            return IPV6_ADDR_SCOPE_GLOBAL;
+        }
+    } else {
+        /*
+         * This should never happen.
+         * Return a scope with low priority as a last resort.
+         */
+        return IPV6_ADDR_SCOPE_NODELOCAL;
+    }
+}
+
+/* These macros are modelled after the ones in <netinet/in6.h>. */
+
+/* RFC 4380, section 2.6 */
+#define IN6_IS_ADDR_TEREDO(a) \
+    ((*(const uint32_t*) (const void*) (&(a)->s6_addr[0]) == ntohl(0x20010000)))
+
+/* RFC 3056, section 2. */
+#define IN6_IS_ADDR_6TO4(a) (((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02))
+
+/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */
+#define IN6_IS_ADDR_6BONE(a) (((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe))
+
+/*
+ * Get the label for a given IPv4/IPv6 address.
+ * RFC 6724, section 2.1.
+ */
+
+static int _get_label(const struct sockaddr* addr) {
+    if (addr->sa_family == AF_INET) {
+        return 4;
+    } else if (addr->sa_family == AF_INET6) {
+        const struct sockaddr_in6* addr6 = (const struct sockaddr_in6*) addr;
+        if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
+            return 0;
+        } else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
+            return 4;
+        } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
+            return 2;
+        } else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
+            return 5;
+        } else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
+            return 13;
+        } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
+            return 3;
+        } else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
+            return 11;
+        } else if (IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
+            return 12;
+        } else {
+            /* All other IPv6 addresses, including global unicast addresses. */
+            return 1;
+        }
+    } else {
+        /*
+         * This should never happen.
+         * Return a semi-random label as a last resort.
+         */
+        return 1;
+    }
+}
+
+/*
+ * Get the precedence for a given IPv4/IPv6 address.
+ * RFC 6724, section 2.1.
+ */
+
+static int _get_precedence(const struct sockaddr* addr) {
+    if (addr->sa_family == AF_INET) {
+        return 35;
+    } else if (addr->sa_family == AF_INET6) {
+        const struct sockaddr_in6* addr6 = (const struct sockaddr_in6*) addr;
+        if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
+            return 50;
+        } else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
+            return 35;
+        } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
+            return 30;
+        } else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
+            return 5;
+        } else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
+            return 3;
+        } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
+                   IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
+                   IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
+            return 1;
+        } else {
+            /* All other IPv6 addresses, including global unicast addresses. */
+            return 40;
+        }
+    } else {
+        return 1;
+    }
+}
+
+/*
+ * Find number of matching initial bits between the two addresses a1 and a2.
+ */
+
+static int _common_prefix_len(const struct in6_addr* a1, const struct in6_addr* a2) {
+    const char* p1 = (const char*) a1;
+    const char* p2 = (const char*) a2;
+    unsigned i;
+
+    for (i = 0; i < sizeof(*a1); ++i) {
+        int x, j;
+
+        if (p1[i] == p2[i]) {
+            continue;
+        }
+        x = p1[i] ^ p2[i];
+        for (j = 0; j < CHAR_BIT; ++j) {
+            if (x & (1 << (CHAR_BIT - 1))) {
+                return i * CHAR_BIT + j;
+            }
+            x <<= 1;
+        }
+    }
+    return sizeof(*a1) * CHAR_BIT;
+}
+
+/*
+ * Compare two source/destination address pairs.
+ * RFC 6724, section 6.
+ */
+
+static int _rfc6724_compare(const void* ptr1, const void* ptr2) {
+    const struct addrinfo_sort_elem* a1 = (const struct addrinfo_sort_elem*) ptr1;
+    const struct addrinfo_sort_elem* a2 = (const struct addrinfo_sort_elem*) ptr2;
+    int scope_src1, scope_dst1, scope_match1;
+    int scope_src2, scope_dst2, scope_match2;
+    int label_src1, label_dst1, label_match1;
+    int label_src2, label_dst2, label_match2;
+    int precedence1, precedence2;
+    int prefixlen1, prefixlen2;
+
+    /* Rule 1: Avoid unusable destinations. */
+    if (a1->has_src_addr != a2->has_src_addr) {
+        return a2->has_src_addr - a1->has_src_addr;
+    }
+
+    /* Rule 2: Prefer matching scope. */
+    scope_src1 = _get_scope(&a1->src_addr.sa);
+    scope_dst1 = _get_scope(a1->ai->ai_addr);
+    scope_match1 = (scope_src1 == scope_dst1);
+
+    scope_src2 = _get_scope(&a2->src_addr.sa);
+    scope_dst2 = _get_scope(a2->ai->ai_addr);
+    scope_match2 = (scope_src2 == scope_dst2);
+
+    if (scope_match1 != scope_match2) {
+        return scope_match2 - scope_match1;
+    }
+
+    /*
+     * Rule 3: Avoid deprecated addresses.
+     * TODO(sesse): We don't currently have a good way of finding this.
+     */
+
+    /*
+     * Rule 4: Prefer home addresses.
+     * TODO(sesse): We don't currently have a good way of finding this.
+     */
+
+    /* Rule 5: Prefer matching label. */
+    label_src1 = _get_label(&a1->src_addr.sa);
+    label_dst1 = _get_label(a1->ai->ai_addr);
+    label_match1 = (label_src1 == label_dst1);
+
+    label_src2 = _get_label(&a2->src_addr.sa);
+    label_dst2 = _get_label(a2->ai->ai_addr);
+    label_match2 = (label_src2 == label_dst2);
+
+    if (label_match1 != label_match2) {
+        return label_match2 - label_match1;
+    }
+
+    /* Rule 6: Prefer higher precedence. */
+    precedence1 = _get_precedence(a1->ai->ai_addr);
+    precedence2 = _get_precedence(a2->ai->ai_addr);
+    if (precedence1 != precedence2) {
+        return precedence2 - precedence1;
+    }
+
+    /*
+     * Rule 7: Prefer native transport.
+     * TODO(sesse): We don't currently have a good way of finding this.
+     */
+
+    /* Rule 8: Prefer smaller scope. */
+    if (scope_dst1 != scope_dst2) {
+        return scope_dst1 - scope_dst2;
+    }
+
+    /*
+     * Rule 9: Use longest matching prefix.
+     * We implement this for IPv6 only, as the rules in RFC 6724 don't seem
+     * to work very well directly applied to IPv4. (glibc uses information from
+     * the routing table for a custom IPv4 implementation here.)
+     */
+    if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 && a2->has_src_addr &&
+        a2->ai->ai_addr->sa_family == AF_INET6) {
+        const struct sockaddr_in6* a1_src = &a1->src_addr.sin6;
+        const struct sockaddr_in6* a1_dst = (const struct sockaddr_in6*) a1->ai->ai_addr;
+        const struct sockaddr_in6* a2_src = &a2->src_addr.sin6;
+        const struct sockaddr_in6* a2_dst = (const struct sockaddr_in6*) a2->ai->ai_addr;
+        prefixlen1 = _common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr);
+        prefixlen2 = _common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr);
+        if (prefixlen1 != prefixlen2) {
+            return prefixlen2 - prefixlen1;
+        }
+    }
+
+    /*
+     * Rule 10: Leave the order unchanged.
+     * We need this since qsort() is not necessarily stable.
+     */
+    return a1->original_order - a2->original_order;
+}
+
+/*
+ * Find the source address that will be used if trying to connect to the given
+ * address. src_addr must be large enough to hold a struct sockaddr_in6.
+ *
+ * Returns 1 if a source address was found, 0 if the address is unreachable,
+ * and -1 if a fatal error occurred. If 0 or -1, the contents of src_addr are
+ * undefined.
+ */
+
+static int _find_src_addr(const struct sockaddr* addr, struct sockaddr* src_addr, unsigned mark,
+                          uid_t uid) {
+    int sock;
+    int ret;
+    socklen_t len;
+
+    switch (addr->sa_family) {
+        case AF_INET:
+            len = sizeof(struct sockaddr_in);
+            break;
+        case AF_INET6:
+            len = sizeof(struct sockaddr_in6);
+            break;
+        default:
+            /* No known usable source address for non-INET families. */
+            return 0;
+    }
+
+    sock = socket(addr->sa_family, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
+    if (sock == -1) {
+        if (errno == EAFNOSUPPORT) {
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+    if (mark != MARK_UNSET && setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
+        close(sock);
+        return 0;
+    }
+    if (uid > 0 && uid != NET_CONTEXT_INVALID_UID && fchown(sock, uid, (gid_t) -1) < 0) {
+        close(sock);
+        return 0;
+    }
+    do {
+        ret = connect(sock, addr, len);
+    } while (ret == -1 && errno == EINTR);
+
+    if (ret == -1) {
+        close(sock);
+        return 0;
+    }
+
+    if (src_addr && getsockname(sock, src_addr, &len) == -1) {
+        close(sock);
+        return -1;
+    }
+    close(sock);
+    return 1;
+}
+
+/*
+ * Sort the linked list starting at sentinel->ai_next in RFC6724 order.
+ * Will leave the list unchanged if an error occurs.
+ */
+
+static void _rfc6724_sort(struct addrinfo* list_sentinel, unsigned mark, uid_t uid) {
+    struct addrinfo* cur;
+    int nelem = 0, i;
+    struct addrinfo_sort_elem* elems;
+
+    cur = list_sentinel->ai_next;
+    while (cur) {
+        ++nelem;
+        cur = cur->ai_next;
+    }
+
+    elems = (struct addrinfo_sort_elem*) malloc(nelem * sizeof(struct addrinfo_sort_elem));
+    if (elems == NULL) {
+        goto error;
+    }
+
+    /*
+     * Convert the linked list to an array that also contains the candidate
+     * source address for each destination address.
+     */
+    for (i = 0, cur = list_sentinel->ai_next; i < nelem; ++i, cur = cur->ai_next) {
+        int has_src_addr;
+        assert(cur != NULL);
+        elems[i].ai = cur;
+        elems[i].original_order = i;
+
+        has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.sa, mark, uid);
+        if (has_src_addr == -1) {
+            goto error;
+        }
+        elems[i].has_src_addr = has_src_addr;
+    }
+
+    /* Sort the addresses, and rearrange the linked list so it matches the sorted order. */
+    qsort((void*) elems, nelem, sizeof(struct addrinfo_sort_elem), _rfc6724_compare);
+
+    list_sentinel->ai_next = elems[0].ai;
+    for (i = 0; i < nelem - 1; ++i) {
+        elems[i].ai->ai_next = elems[i + 1].ai;
+    }
+    elems[nelem - 1].ai->ai_next = NULL;
+
+error:
+    free(elems);
+}
+
+static int dns_getaddrinfo(const char* name, const addrinfo* pai,
+                           const android_net_context* netcontext, addrinfo** rv,
+                           NetworkDnsEventReported* event) {
+    res_target q = {};
+    res_target q2 = {};
+
+    auto buf = std::make_unique<querybuf>();
+    auto buf2 = std::make_unique<querybuf>();
+
+    switch (pai->ai_family) {
+        case AF_UNSPEC: {
+            /* prefer IPv6 */
+            q.name = name;
+            q.qclass = C_IN;
+            q.answer = buf->buf;
+            q.anslen = sizeof(buf->buf);
+            int query_ipv6 = 1, query_ipv4 = 1;
+            if (pai->ai_flags & AI_ADDRCONFIG) {
+                query_ipv6 = have_ipv6(netcontext->app_mark, netcontext->uid);
+                query_ipv4 = have_ipv4(netcontext->app_mark, netcontext->uid);
+            }
+            if (query_ipv6) {
+                q.qtype = T_AAAA;
+                if (query_ipv4) {
+                    q.next = &q2;
+                    q2.name = name;
+                    q2.qclass = C_IN;
+                    q2.qtype = T_A;
+                    q2.answer = buf2->buf;
+                    q2.anslen = sizeof(buf2->buf);
+                }
+            } else if (query_ipv4) {
+                q.qtype = T_A;
+            } else {
+                return EAI_NODATA;
+            }
+            break;
+        }
+        case AF_INET:
+            q.name = name;
+            q.qclass = C_IN;
+            q.qtype = T_A;
+            q.answer = buf->buf;
+            q.anslen = sizeof(buf->buf);
+            break;
+        case AF_INET6:
+            q.name = name;
+            q.qclass = C_IN;
+            q.qtype = T_AAAA;
+            q.answer = buf->buf;
+            q.anslen = sizeof(buf->buf);
+            break;
+        default:
+            return EAI_FAMILY;
+    }
+
+    res_state res = res_get_state();
+    if (!res) return EAI_MEMORY;
+
+    /* this just sets our netid val in the thread private data so we don't have to
+     * modify the api's all the way down to res_send.c's res_nsend.  We could
+     * fully populate the thread private data here, but if we get down there
+     * and have a cache hit that would be wasted, so we do the rest there on miss
+     */
+    res_setnetcontext(res, netcontext, event);
+
+    int he;
+    if (res_searchN(name, &q, res, &he) < 0) {
+        // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA.
+        // Note that res_searchN() doesn't set the pair NETDB_INTERNAL and errno.
+        // See also herrnoToAiErrno().
+        return herrnoToAiErrno(he);
+    }
+
+    addrinfo sentinel = {};
+    addrinfo* cur = &sentinel;
+    addrinfo* ai = getanswer(buf.get(), q.n, q.name, q.qtype, pai, &he);
+    if (ai) {
+        cur->ai_next = ai;
+        while (cur && cur->ai_next) cur = cur->ai_next;
+    }
+    if (q.next) {
+        ai = getanswer(buf2.get(), q2.n, q2.name, q2.qtype, pai, &he);
+        if (ai) cur->ai_next = ai;
+    }
+    if (sentinel.ai_next == NULL) {
+        // Note that getanswer() doesn't set the pair NETDB_INTERNAL and errno.
+        // See also herrnoToAiErrno().
+        return herrnoToAiErrno(he);
+    }
+
+    _rfc6724_sort(&sentinel, netcontext->app_mark, netcontext->uid);
+
+    *rv = sentinel.ai_next;
+    return 0;
+}
+
+static void _sethtent(FILE** hostf) {
+    if (!*hostf)
+        *hostf = fopen(_PATH_HOSTS, "re");
+    else
+        rewind(*hostf);
+}
+
+static void _endhtent(FILE** hostf) {
+    if (*hostf) {
+        (void) fclose(*hostf);
+        *hostf = NULL;
+    }
+}
+
+static struct addrinfo* _gethtent(FILE** hostf, const char* name, const struct addrinfo* pai) {
+    char* p;
+    char *cp, *tname, *cname;
+    struct addrinfo *res0, *res;
+    int error;
+    const char* addr;
+    char hostbuf[8 * 1024];
+
+    assert(name != NULL);
+    assert(pai != NULL);
+
+    if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "re"))) return (NULL);
+again:
+    if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf))) return (NULL);
+    if (*p == '#') goto again;
+    if (!(cp = strpbrk(p, "#\n"))) goto again;
+    *cp = '\0';
+    if (!(cp = strpbrk(p, " \t"))) goto again;
+    *cp++ = '\0';
+    addr = p;
+    /* if this is not something we're looking for, skip it. */
+    cname = NULL;
+    while (cp && *cp) {
+        if (*cp == ' ' || *cp == '\t') {
+            cp++;
+            continue;
+        }
+        if (!cname) cname = cp;
+        tname = cp;
+        if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0';
+        if (strcasecmp(name, tname) == 0) goto found;
+    }
+    goto again;
+
+found:
+    error = getaddrinfo_numeric(addr, nullptr, *pai, &res0);
+    if (error) goto again;
+    for (res = res0; res; res = res->ai_next) {
+        /* cover it up */
+        res->ai_flags = pai->ai_flags;
+
+        if (pai->ai_flags & AI_CANONNAME) {
+            if (get_canonname(pai, res, cname) != 0) {
+                freeaddrinfo(res0);
+                goto again;
+            }
+        }
+    }
+    return res0;
+}
+
+static bool files_getaddrinfo(const char* name, const addrinfo* pai, addrinfo** res) {
+    struct addrinfo sentinel = {};
+    struct addrinfo *p, *cur;
+    FILE* hostf = NULL;
+
+    cur = &sentinel;
+
+    _sethtent(&hostf);
+    while ((p = _gethtent(&hostf, name, pai)) != NULL) {
+        cur->ai_next = p;
+        while (cur && cur->ai_next) cur = cur->ai_next;
+    }
+    _endhtent(&hostf);
+
+    *res = sentinel.ai_next;
+    return sentinel.ai_next != NULL;
+}
+
+/* resolver logic */
+
+/*
+ * Formulate a normal query, send, and await answer.
+ * Returned answer is placed in supplied buffer "answer".
+ * Perform preliminary check of answer, returning success only
+ * if no error is indicated and the answer count is nonzero.
+ * Return the size of the response on success, -1 on error.
+ * Error number is left in *herrno.
+ *
+ * Caller must parse answer and determine whether it answers the question.
+ */
+static int res_queryN(const char* name, res_target* target, res_state res, int* herrno) {
+    u_char buf[MAXPACKET];
+    HEADER* hp;
+    int n;
+    struct res_target* t;
+    int rcode;
+    int ancount;
+
+    assert(name != NULL);
+    /* XXX: target may be NULL??? */
+
+    rcode = NOERROR;
+    ancount = 0;
+
+    for (t = target; t; t = t->next) {
+        u_char* answer;
+        int anslen;
+
+        hp = (HEADER*) (void*) t->answer;
+        bool retried = false;
+    again:
+        hp->rcode = NOERROR; /* default */
+
+        /* make it easier... */
+        int cl = t->qclass;
+        int type = t->qtype;
+        answer = t->answer;
+        anslen = t->anslen;
+
+        LOG(DEBUG) << __func__ << ": (" << cl << ", " << type << ")";
+
+        n = res_nmkquery(res, QUERY, name, cl, type, NULL, 0, NULL, buf, sizeof(buf));
+        if (n > 0 && (res->options & (RES_USE_EDNS0 | RES_USE_DNSSEC)) != 0 && !retried)
+            n = res_nopt(res, n, buf, sizeof(buf), anslen);
+        if (n <= 0) {
+            LOG(ERROR) << __func__ << ": res_nmkquery failed";
+            *herrno = NO_RECOVERY;
+            return n;
+        }
+
+        n = res_nsend(res, buf, n, answer, anslen, &rcode, 0);
+        if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
+            // Record rcode from DNS response header only if no timeout.
+            // Keep rcode timeout for reporting later if any.
+            if (rcode != RCODE_TIMEOUT) rcode = hp->rcode; /* record most recent error */
+            /* if the query choked with EDNS0, retry without EDNS0 */
+            if ((res->options & (RES_USE_EDNS0 | RES_USE_DNSSEC)) != 0 &&
+                (res->_flags & RES_F_EDNS0ERR) && !retried) {
+                LOG(DEBUG) << __func__ << ": retry without EDNS0";
+                retried = true;
+                goto again;
+            }
+            LOG(DEBUG) << __func__ << ": rcode=" << hp->rcode << ", ancount=" << ntohs(hp->ancount);
+            continue;
+        }
+
+        ancount += ntohs(hp->ancount);
+
+        t->n = n;
+    }
+
+    if (ancount == 0) {
+        switch (rcode) {
+            // Not defined in RFC.
+            case RCODE_TIMEOUT:
+                // DNS metrics monitors DNS query timeout.
+                *herrno = NETD_RESOLV_H_ERRNO_EXT_TIMEOUT;  // extended h_errno.
+                break;
+            // Defined in RFC 1035 section 4.1.1.
+            case NXDOMAIN:
+                *herrno = HOST_NOT_FOUND;
+                break;
+            case SERVFAIL:
+                *herrno = TRY_AGAIN;
+                break;
+            case NOERROR:
+                *herrno = NO_DATA;
+                break;
+            case FORMERR:
+            case NOTIMP:
+            case REFUSED:
+            default:
+                *herrno = NO_RECOVERY;
+                break;
+        }
+        return -1;
+    }
+    return ancount;
+}
+
+/*
+ * Formulate a normal query, send, and retrieve answer in supplied buffer.
+ * Return the size of the response on success, -1 on error.
+ * If enabled, implement search rules until answer or unrecoverable failure
+ * is detected.  Error code, if any, is left in *herrno.
+ */
+static int res_searchN(const char* name, res_target* target, res_state res, int* herrno) {
+    const char *cp, *const *domain;
+    HEADER* hp;
+    u_int dots;
+    int trailing_dot, ret, saved_herrno;
+    int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
+
+    assert(name != NULL);
+    assert(target != NULL);
+
+    hp = (HEADER*) (void*) target->answer; /*XXX*/
+
+    errno = 0;
+    *herrno = HOST_NOT_FOUND; /* default, if we never query */
+    dots = 0;
+    for (cp = name; *cp; cp++) dots += (*cp == '.');
+    trailing_dot = 0;
+    if (cp > name && *--cp == '.') trailing_dot++;
+
+    /*
+     * If there are dots in the name already, let's just give it a try
+     * 'as is'.  The threshold can be set with the "ndots" option.
+     */
+    saved_herrno = -1;
+    if (dots >= res->ndots) {
+        ret = res_querydomainN(name, NULL, target, res, herrno);
+        if (ret > 0) return (ret);
+        saved_herrno = *herrno;
+        tried_as_is++;
+    }
+
+    /*
+     * We do at least one level of search if
+     *	- there is no dot and RES_DEFNAME is set, or
+     *	- there is at least one dot, there is no trailing dot,
+     *	  and RES_DNSRCH is set.
+     */
+    if ((!dots && (res->options & RES_DEFNAMES)) ||
+        (dots && !trailing_dot && (res->options & RES_DNSRCH))) {
+        int done = 0;
+
+        /* Unfortunately we need to set stuff up before
+         * the domain stuff is tried.  Will have a better
+         * fix after thread pools are used.
+         */
+        _resolv_populate_res_for_net(res);
+
+        for (domain = (const char* const*) res->dnsrch; *domain && !done; domain++) {
+            ret = res_querydomainN(name, *domain, target, res, herrno);
+            if (ret > 0) return ret;
+
+            /*
+             * If no server present, give up.
+             * If name isn't found in this domain,
+             * keep trying higher domains in the search list
+             * (if that's enabled).
+             * On a NO_DATA error, keep trying, otherwise
+             * a wildcard entry of another type could keep us
+             * from finding this entry higher in the domain.
+             * If we get some other error (negative answer or
+             * server failure), then stop searching up,
+             * but try the input name below in case it's
+             * fully-qualified.
+             */
+            if (errno == ECONNREFUSED) {
+                *herrno = TRY_AGAIN;
+                return -1;
+            }
+
+            switch (*herrno) {
+                case NO_DATA:
+                    got_nodata++;
+                    [[fallthrough]];
+                case HOST_NOT_FOUND:
+                    /* keep trying */
+                    break;
+                case TRY_AGAIN:
+                    if (hp->rcode == SERVFAIL) {
+                        /* try next search element, if any */
+                        got_servfail++;
+                        break;
+                    }
+                    [[fallthrough]];
+                default:
+                    /* anything else implies that we're done */
+                    done++;
+            }
+            /*
+             * if we got here for some reason other than DNSRCH,
+             * we only wanted one iteration of the loop, so stop.
+             */
+            if (!(res->options & RES_DNSRCH)) done++;
+        }
+    }
+
+    /*
+     * if we have not already tried the name "as is", do that now.
+     * note that we do this regardless of how many dots were in the
+     * name or whether it ends with a dot.
+     */
+    if (!tried_as_is) {
+        ret = res_querydomainN(name, NULL, target, res, herrno);
+        if (ret > 0) return ret;
+    }
+
+    /*
+     * if we got here, we didn't satisfy the search.
+     * if we did an initial full query, return that query's h_errno
+     * (note that we wouldn't be here if that query had succeeded).
+     * else if we ever got a nodata, send that back as the reason.
+     * else send back meaningless h_errno, that being the one from
+     * the last DNSRCH we did.
+     */
+    if (saved_herrno != -1)
+        *herrno = saved_herrno;
+    else if (got_nodata)
+        *herrno = NO_DATA;
+    else if (got_servfail)
+        *herrno = TRY_AGAIN;
+    return -1;
+}
+
+/*
+ * Perform a call on res_query on the concatenation of name and domain,
+ * removing a trailing dot from name if domain is NULL.
+ */
+static int res_querydomainN(const char* name, const char* domain, res_target* target, res_state res,
+                            int* herrno) {
+    char nbuf[MAXDNAME];
+    const char* longname = nbuf;
+    size_t n, d;
+
+    assert(name != NULL);
+
+    if (domain == NULL) {
+        // Check for trailing '.'; copy without '.' if present.
+        n = strlen(name);
+        if (n + 1 > sizeof(nbuf)) {
+            *herrno = NO_RECOVERY;
+            return -1;
+        }
+        if (n > 0 && name[--n] == '.') {
+            strncpy(nbuf, name, n);
+            nbuf[n] = '\0';
+        } else
+            longname = name;
+    } else {
+        n = strlen(name);
+        d = strlen(domain);
+        if (n + 1 + d + 1 > sizeof(nbuf)) {
+            *herrno = NO_RECOVERY;
+            return -1;
+        }
+        snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
+    }
+    return res_queryN(longname, target, res, herrno);
+}
diff --git a/resolv/getaddrinfo.h b/resolv/getaddrinfo.h
new file mode 100644
index 0000000..e8ba5dc
--- /dev/null
+++ b/resolv/getaddrinfo.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "netd_resolv/resolv.h"  // struct android_net_context
+#include "stats.pb.h"
+
+struct addrinfo;
+
+// This is the DNS proxy entry point for getaddrinfo().
+int android_getaddrinfofornetcontext(const char*, const char*, const addrinfo*,
+                                     const android_net_context*, addrinfo**,
+                                     android::net::NetworkDnsEventReported*);
diff --git a/resolv/gethnamaddr.cpp b/resolv/gethnamaddr.cpp
new file mode 100644
index 0000000..a40a7b7
--- /dev/null
+++ b/resolv/gethnamaddr.cpp
@@ -0,0 +1,960 @@
+/*	$NetBSD: gethnamaddr.c,v 1.91 2014/06/19 15:08:18 christos Exp $	*/
+
+/*
+ * ++Copyright++ 1985, 1988, 1993
+ * -
+ * Copyright (c) 1985, 1988, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#include "gethnamaddr.h"
+
+#include <android-base/logging.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <functional>
+#include <vector>
+
+#include "hostent.h"
+#include "netd_resolv/resolv.h"
+#include "resolv_cache.h"
+#include "resolv_private.h"
+#include "stats.pb.h"
+
+using android::net::NetworkDnsEventReported;
+
+// NetBSD uses _DIAGASSERT to null-check arguments and the like,
+// but it's clear from the number of mistakes in their assertions
+// that they don't actually test or ship with this.
+#define _DIAGASSERT(e) /* nothing */
+
+// TODO: unify macro ALIGNBYTES and ALIGN for all possible data type alignment of hostent
+// buffer.
+#define ALIGNBYTES (sizeof(uintptr_t) - 1)
+#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) & ~ALIGNBYTES)
+
+#define maybe_ok(res, nm, ok) (((res)->options & RES_NOCHECKNAME) != 0U || (ok)(nm) != 0)
+#define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok)
+#define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok)
+
+#define MAXPACKET (8 * 1024)
+
+typedef union {
+    HEADER hdr;
+    u_char buf[MAXPACKET];
+} querybuf;
+
+typedef union {
+    int32_t al;
+    char ac;
+} align;
+
+static struct hostent* getanswer(const querybuf*, int, const char*, int, res_state, struct hostent*,
+                                 char*, size_t, int*);
+static void convert_v4v6_hostent(struct hostent* hp, char** bpp, char* ep,
+                                 std::function<void(struct hostent* hp)> mapping_param,
+                                 std::function<void(char* src, char* dst)> mapping_addr);
+static void map_v4v6_address(const char*, char*);
+static void map_v4v6_hostent(struct hostent*, char**, char*);
+static void pad_v4v6_hostent(struct hostent* hp, char** bpp, char* ep);
+static void addrsort(char**, int, res_state);
+
+static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
+                           const android_net_context* netcontext, getnamaddr* info,
+                           NetworkDnsEventReported* event);
+static int dns_gethtbyname(const char* name, int af, getnamaddr* info);
+
+static int gethostbyname_internal(const char* name, int af, res_state res, hostent* hp, char* hbuf,
+                                  size_t hbuflen, const android_net_context* netcontext,
+                                  NetworkDnsEventReported* event);
+static int gethostbyname_internal_real(const char* name, int af, res_state res, hostent* hp,
+                                       char* buf, size_t buflen);
+static int android_gethostbyaddrfornetcontext_proxy_internal(const void*, socklen_t, int,
+                                                             struct hostent*, char*, size_t,
+                                                             const struct android_net_context*,
+                                                             NetworkDnsEventReported* event);
+static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
+                                                    const struct android_net_context* netcontext,
+                                                    hostent** hp, NetworkDnsEventReported* event);
+
+#define BOUNDED_INCR(x)      \
+    do {                     \
+        BOUNDS_CHECK(cp, x); \
+        cp += (x);           \
+    } while (0)
+
+#define BOUNDS_CHECK(ptr, count)                     \
+    do {                                             \
+        if (eom - (ptr) < (count)) goto no_recovery; \
+    } while (0)
+
+static struct hostent* getanswer(const querybuf* answer, int anslen, const char* qname, int qtype,
+                                 res_state res, struct hostent* hent, char* buf, size_t buflen,
+                                 int* he) {
+    const HEADER* hp;
+    const u_char* cp;
+    int n;
+    size_t qlen;
+    const u_char *eom, *erdata;
+    char *bp, **hap, *ep;
+    int ancount, qdcount;
+    int haveanswer, had_error;
+    int toobig = 0;
+    char tbuf[MAXDNAME];
+    char* addr_ptrs[MAXADDRS];
+    const char* tname;
+    int (*name_ok)(const char*);
+    std::vector<char*> aliases;
+
+    _DIAGASSERT(answer != NULL);
+    _DIAGASSERT(qname != NULL);
+
+    tname = qname;
+    hent->h_name = NULL;
+    eom = answer->buf + anslen;
+    switch (qtype) {
+        case T_A:
+        case T_AAAA:
+            name_ok = res_hnok;
+            break;
+        case T_PTR:
+            name_ok = res_dnok;
+            break;
+        default:
+            *he = NO_RECOVERY;
+            return NULL; /* XXX should be abort(); */
+    }
+
+    /*
+     * find first satisfactory answer
+     */
+    hp = &answer->hdr;
+    ancount = ntohs(hp->ancount);
+    qdcount = ntohs(hp->qdcount);
+    bp = buf;
+    ep = buf + buflen;
+    cp = answer->buf;
+    BOUNDED_INCR(HFIXEDSZ);
+    if (qdcount != 1) goto no_recovery;
+
+    n = dn_expand(answer->buf, eom, cp, bp, (int) (ep - bp));
+    if ((n < 0) || !maybe_ok(res, bp, name_ok)) goto no_recovery;
+
+    BOUNDED_INCR(n + QFIXEDSZ);
+    if (qtype == T_A || qtype == T_AAAA) {
+        /* res_send() has already verified that the query name is the
+         * same as the one we sent; this just gets the expanded name
+         * (i.e., with the succeeding search-domain tacked on).
+         */
+        n = (int) strlen(bp) + 1; /* for the \0 */
+        if (n >= MAXHOSTNAMELEN) goto no_recovery;
+        hent->h_name = bp;
+        bp += n;
+        /* The qname can be abbreviated, but h_name is now absolute. */
+        qname = hent->h_name;
+    }
+    hent->h_addr_list = hap = addr_ptrs;
+    *hap = NULL;
+    haveanswer = 0;
+    had_error = 0;
+    while (ancount-- > 0 && cp < eom && !had_error) {
+        n = dn_expand(answer->buf, eom, cp, bp, (int) (ep - bp));
+        if ((n < 0) || !maybe_ok(res, bp, name_ok)) {
+            had_error++;
+            continue;
+        }
+        cp += n; /* name */
+        BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
+        int type = ntohs(*reinterpret_cast<const uint16_t*>(cp));
+        cp += INT16SZ; /* type */
+        int cl = ntohs(*reinterpret_cast<const uint16_t*>(cp));
+        cp += INT16SZ + INT32SZ; /* class, TTL */
+        n = ntohs(*reinterpret_cast<const uint16_t*>(cp));
+        cp += INT16SZ; /* len */
+        BOUNDS_CHECK(cp, n);
+        erdata = cp + n;
+        if (cl != C_IN) {
+            /* XXX - debug? syslog? */
+            cp += n;
+            continue; /* XXX - had_error++ ? */
+        }
+        if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
+            n = dn_expand(answer->buf, eom, cp, tbuf, (int) sizeof tbuf);
+            if ((n < 0) || !maybe_ok(res, tbuf, name_ok)) {
+                had_error++;
+                continue;
+            }
+            cp += n;
+            if (cp != erdata) goto no_recovery;
+            /* Store alias. */
+            aliases.push_back(bp);
+            n = (int) strlen(bp) + 1; /* for the \0 */
+            if (n >= MAXHOSTNAMELEN) {
+                had_error++;
+                continue;
+            }
+            bp += n;
+            /* Get canonical name. */
+            n = (int) strlen(tbuf) + 1; /* for the \0 */
+            if (n > ep - bp || n >= MAXHOSTNAMELEN) {
+                had_error++;
+                continue;
+            }
+            strlcpy(bp, tbuf, (size_t)(ep - bp));
+            hent->h_name = bp;
+            bp += n;
+            continue;
+        }
+        if (qtype == T_PTR && type == T_CNAME) {
+            n = dn_expand(answer->buf, eom, cp, tbuf, (int) sizeof tbuf);
+            if (n < 0 || !maybe_dnok(res, tbuf)) {
+                had_error++;
+                continue;
+            }
+            cp += n;
+            if (cp != erdata) goto no_recovery;
+            /* Get canonical name. */
+            n = (int) strlen(tbuf) + 1; /* for the \0 */
+            if (n > ep - bp || n >= MAXHOSTNAMELEN) {
+                had_error++;
+                continue;
+            }
+            strlcpy(bp, tbuf, (size_t)(ep - bp));
+            tname = bp;
+            bp += n;
+            continue;
+        }
+        if (type != qtype) {
+            if (type != T_KEY && type != T_SIG)
+                LOG(DEBUG) << __func__ << ": asked for \"" << qname << " " << p_class(C_IN) << " "
+                           << p_type(qtype) << "\", got type \"" << p_type(type) << "\"";
+            cp += n;
+            continue; /* XXX - had_error++ ? */
+        }
+        switch (type) {
+            case T_PTR:
+                if (strcasecmp(tname, bp) != 0) {
+                    LOG(DEBUG) << __func__ << ": asked for \"" << qname << "\", got \"" << bp
+                               << "\"";
+                    cp += n;
+                    continue; /* XXX - had_error++ ? */
+                }
+                n = dn_expand(answer->buf, eom, cp, bp, (int) (ep - bp));
+                if ((n < 0) || !maybe_hnok(res, bp)) {
+                    had_error++;
+                    break;
+                }
+                cp += n;
+                if (cp != erdata) goto no_recovery;
+                if (!haveanswer)
+                    hent->h_name = bp;
+                else
+                    aliases.push_back(bp);
+                if (n != -1) {
+                    n = (int) strlen(bp) + 1; /* for the \0 */
+                    if (n >= MAXHOSTNAMELEN) {
+                        had_error++;
+                        break;
+                    }
+                    bp += n;
+                }
+                break;
+            case T_A:
+            case T_AAAA:
+                if (strcasecmp(hent->h_name, bp) != 0) {
+                    LOG(DEBUG) << __func__ << ": asked for \"" << hent->h_name << "\", got \"" << bp
+                               << "\"";
+                    cp += n;
+                    continue; /* XXX - had_error++ ? */
+                }
+                if (n != hent->h_length) {
+                    cp += n;
+                    continue;
+                }
+                if (type == T_AAAA) {
+                    struct in6_addr in6;
+                    memcpy(&in6, cp, NS_IN6ADDRSZ);
+                    if (IN6_IS_ADDR_V4MAPPED(&in6)) {
+                        cp += n;
+                        continue;
+                    }
+                }
+                if (!haveanswer) {
+                    int nn;
+
+                    hent->h_name = bp;
+                    nn = (int) strlen(bp) + 1; /* for the \0 */
+                    bp += nn;
+                }
+
+                bp += sizeof(align) - (size_t)((u_long) bp % sizeof(align));
+
+                if (bp + n >= ep) {
+                    LOG(DEBUG) << __func__ << ": size (" << n << ") too big";
+                    had_error++;
+                    continue;
+                }
+                if (hap >= &addr_ptrs[MAXADDRS - 1]) {
+                    if (!toobig++) {
+                        LOG(DEBUG) << __func__ << ": Too many addresses (" << MAXADDRS << ")";
+                    }
+                    cp += n;
+                    continue;
+                }
+                (void) memcpy(*hap++ = bp, cp, (size_t) n);
+                bp += n;
+                cp += n;
+                if (cp != erdata) goto no_recovery;
+                break;
+            default:
+                abort();
+        }
+        if (!had_error) haveanswer++;
+    }
+    if (haveanswer) {
+        *hap = NULL;
+        /*
+         * Note: we sort even if host can take only one address
+         * in its return structures - should give it the "best"
+         * address in that case, not some random one
+         */
+        if (res->nsort && haveanswer > 1 && qtype == T_A) addrsort(addr_ptrs, haveanswer, res);
+        if (!hent->h_name) {
+            n = (int) strlen(qname) + 1; /* for the \0 */
+            if (n > ep - bp || n >= MAXHOSTNAMELEN) goto no_recovery;
+            strlcpy(bp, qname, (size_t)(ep - bp));
+            hent->h_name = bp;
+            bp += n;
+        }
+        if (res->options & RES_USE_INET6) map_v4v6_hostent(hent, &bp, ep);
+        if (hent->h_addrtype == AF_INET) pad_v4v6_hostent(hent, &bp, ep);
+        goto success;
+    }
+no_recovery:
+    *he = NO_RECOVERY;
+    return NULL;
+success:
+    bp = (char*) ALIGN(bp);
+    aliases.push_back(nullptr);
+    qlen = aliases.size() * sizeof(*hent->h_aliases);
+    if ((size_t)(ep - bp) < qlen) goto nospc;
+    hent->h_aliases = (char**) bp;
+    memcpy(bp, aliases.data(), qlen);
+
+    bp += qlen;
+    n = (int) (hap - addr_ptrs);
+    qlen = (n + 1) * sizeof(*hent->h_addr_list);
+    if ((size_t)(ep - bp) < qlen) goto nospc;
+    hent->h_addr_list = (char**) bp;
+    memcpy(bp, addr_ptrs, qlen);
+    *he = NETDB_SUCCESS;
+    return hent;
+nospc:
+    errno = ENOSPC;
+    *he = NETDB_INTERNAL;
+    return NULL;
+}
+
+static int gethostbyname_internal_real(const char* name, int af, res_state res, hostent* hp,
+                                       char* buf, size_t buflen) {
+    getnamaddr info;
+    size_t size;
+
+    _DIAGASSERT(name != NULL);
+
+    switch (af) {
+        case AF_INET:
+            size = NS_INADDRSZ;
+            break;
+        case AF_INET6:
+            size = NS_IN6ADDRSZ;
+            break;
+        default:
+            return EAI_FAMILY;
+    }
+    if (buflen < size) goto nospc;
+
+    hp->h_addrtype = af;
+    hp->h_length = (int) size;
+
+    /*
+     * disallow names consisting only of digits/dots, unless
+     * they end in a dot.
+     */
+    if (isdigit((u_char) name[0])) {
+        for (const char* cp = name;; ++cp) {
+            if (!*cp) {
+                if (*--cp == '.') break;
+                /*
+                 * All-numeric, no dot at the end.
+                 * Fake up a hostent as if we'd actually
+                 * done a lookup.
+                 */
+                goto fake;
+            }
+            if (!isdigit((u_char) *cp) && *cp != '.') break;
+        }
+    }
+    if ((isxdigit((u_char) name[0]) && strchr(name, ':') != NULL) || name[0] == ':') {
+        for (const char* cp = name;; ++cp) {
+            if (!*cp) {
+                if (*--cp == '.') break;
+                /*
+                 * All-IPv6-legal, no dot at the end.
+                 * Fake up a hostent as if we'd actually
+                 * done a lookup.
+                 */
+                goto fake;
+            }
+            if (!isxdigit((u_char) *cp) && *cp != ':' && *cp != '.') break;
+        }
+    }
+
+    info.hp = hp;
+    info.buf = buf;
+    info.buflen = buflen;
+    if (_hf_gethtbyname2(name, af, &info)) {
+        int error = dns_gethtbyname(name, af, &info);
+        if (error != 0) return error;
+    }
+    return 0;
+nospc:
+    return EAI_MEMORY;
+fake:
+    HENT_ARRAY(hp->h_addr_list, 1, buf, buflen);
+    HENT_ARRAY(hp->h_aliases, 0, buf, buflen);
+
+    hp->h_aliases[0] = NULL;
+    if (size > buflen) goto nospc;
+
+    if (inet_pton(af, name, buf) <= 0) {
+        return EAI_NODATA;
+    }
+    hp->h_addr_list[0] = buf;
+    hp->h_addr_list[1] = NULL;
+    buf += size;
+    buflen -= size;
+    HENT_SCOPY(hp->h_name, name, buf, buflen);
+    if (res->options & RES_USE_INET6) map_v4v6_hostent(hp, &buf, buf + buflen);
+    return 0;
+}
+
+// very similar in proxy-ness to android_getaddrinfo_proxy
+static int gethostbyname_internal(const char* name, int af, res_state res, hostent* hp, char* hbuf,
+                                  size_t hbuflen, const android_net_context* netcontext,
+                                  NetworkDnsEventReported* event) {
+    res_setnetcontext(res, netcontext, event);
+    return gethostbyname_internal_real(name, af, res, hp, hbuf, hbuflen);
+}
+
+static int android_gethostbyaddrfornetcontext_real(const void* addr, socklen_t len, int af,
+                                                   struct hostent* hp, char* buf, size_t buflen,
+                                                   const struct android_net_context* netcontext,
+                                                   NetworkDnsEventReported* event) {
+    const u_char* uaddr = (const u_char*) addr;
+    socklen_t size;
+    struct getnamaddr info;
+
+    _DIAGASSERT(addr != NULL);
+
+    if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
+        (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr*) addr) ||
+         IN6_IS_ADDR_SITELOCAL((const struct in6_addr*) addr))) {
+        return EAI_NODATA;
+    }
+    if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
+        (IN6_IS_ADDR_V4MAPPED((const struct in6_addr*) addr) ||
+         IN6_IS_ADDR_V4COMPAT((const struct in6_addr*) addr))) {
+        /* Unmap. */
+        uaddr += NS_IN6ADDRSZ - NS_INADDRSZ;
+        addr = uaddr;
+        af = AF_INET;
+        len = NS_INADDRSZ;
+    }
+    switch (af) {
+        case AF_INET:
+            size = NS_INADDRSZ;
+            break;
+        case AF_INET6:
+            size = NS_IN6ADDRSZ;
+            break;
+        default:
+            return EAI_FAMILY;
+    }
+    if (size != len) {
+        // TODO: Consider converting to a private extended EAI_* error code.
+        // Currently, the EAI_* value has no corresponding error code for invalid argument socket
+        // length. In order to not rely on errno, convert the original error code pair, EAI_SYSTEM
+        // and EINVAL, to EAI_FAIL.
+        return EAI_FAIL;
+    }
+    info.hp = hp;
+    info.buf = buf;
+    info.buflen = buflen;
+    if (_hf_gethtbyaddr(uaddr, len, af, &info)) {
+        int error = dns_gethtbyaddr(uaddr, len, af, netcontext, &info, event);
+        if (error != 0) return error;
+    }
+    return 0;
+}
+
+static int android_gethostbyaddrfornetcontext_proxy_internal(
+        const void* addr, socklen_t len, int af, struct hostent* hp, char* hbuf, size_t hbuflen,
+        const struct android_net_context* netcontext, NetworkDnsEventReported* event) {
+    return android_gethostbyaddrfornetcontext_real(addr, len, af, hp, hbuf, hbuflen, netcontext,
+                                                   event);
+}
+
+// TODO: Consider leaving function without returning error code as _gethtent() does because
+// the error code of the caller does not currently return to netd.
+struct hostent* netbsd_gethostent_r(FILE* hf, struct hostent* hent, char* buf, size_t buflen,
+                                    int* he) {
+    const size_t line_buf_size = sizeof(res_get_static()->hostbuf);
+    char *name;
+    char* cp;
+    int af, len;
+    size_t anum;
+    struct in6_addr host_addr;
+    std::vector<char*> aliases;
+
+    if (hf == NULL) {
+        *he = NETDB_INTERNAL;
+        errno = EINVAL;
+        return NULL;
+    }
+    char* p = NULL;
+
+    /* Allocate a new space to read file lines like upstream does.
+     * To keep reentrancy we cannot use res_get_static()->hostbuf here,
+     * as the buffer may be used to store content for a previous hostent
+     * returned by non-reentrant functions like gethostbyname().
+     */
+    if ((p = (char*) malloc(line_buf_size)) == NULL) {
+        goto nospc;
+    }
+    for (;;) {
+        if (!fgets(p, line_buf_size, hf)) {
+            free(p);
+            *he = HOST_NOT_FOUND;
+            return NULL;
+        }
+        if (*p == '#') {
+            continue;
+        }
+        if (!(cp = strpbrk(p, "#\n"))) {
+            continue;
+        }
+        *cp = '\0';
+        if (!(cp = strpbrk(p, " \t"))) continue;
+        *cp++ = '\0';
+        if (inet_pton(AF_INET6, p, &host_addr) > 0) {
+            af = AF_INET6;
+            len = NS_IN6ADDRSZ;
+        } else {
+            if (inet_pton(AF_INET, p, &host_addr) <= 0) continue;
+
+            res_state res = res_get_state();
+            if (res == NULL) goto nospc;
+            if (res->options & RES_USE_INET6) {
+                map_v4v6_address(buf, buf);
+                af = AF_INET6;
+                len = NS_IN6ADDRSZ;
+            } else {
+                af = AF_INET;
+                len = NS_INADDRSZ;
+            }
+        }
+
+        /* if this is not something we're looking for, skip it. */
+        if (hent->h_addrtype != 0 && hent->h_addrtype != af) continue;
+        if (hent->h_length != 0 && hent->h_length != len) continue;
+
+        while (*cp == ' ' || *cp == '\t') cp++;
+        if ((cp = strpbrk(name = cp, " \t")) != NULL) *cp++ = '\0';
+        while (cp && *cp) {
+            if (*cp == ' ' || *cp == '\t') {
+                cp++;
+                continue;
+            }
+            aliases.push_back(cp);
+            if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0';
+        }
+        break;
+    }
+    hent->h_length = len;
+    hent->h_addrtype = af;
+    HENT_ARRAY(hent->h_addr_list, 1, buf, buflen);
+    anum = aliases.size();
+    HENT_ARRAY(hent->h_aliases, anum, buf, buflen);
+    HENT_COPY(hent->h_addr_list[0], &host_addr, hent->h_length, buf, buflen);
+    hent->h_addr_list[1] = NULL;
+
+    /* Reserve space for mapping IPv4 address to IPv6 address in place */
+    if (hent->h_addrtype == AF_INET) {
+        HENT_COPY(buf, NAT64_PAD, sizeof(NAT64_PAD), buf, buflen);
+    }
+
+    HENT_SCOPY(hent->h_name, name, buf, buflen);
+    for (size_t i = 0; i < anum; i++) HENT_SCOPY(hent->h_aliases[i], aliases[i], buf, buflen);
+    hent->h_aliases[anum] = NULL;
+    *he = NETDB_SUCCESS;
+    free(p);
+    return hent;
+nospc:
+    free(p);
+    errno = ENOSPC;
+    *he = NETDB_INTERNAL;
+    return NULL;
+}
+
+static void map_v4v6_address(const char* src, char* dst) {
+    u_char* p = (u_char*) dst;
+    char tmp[NS_INADDRSZ];
+    int i;
+
+    _DIAGASSERT(src != NULL);
+    _DIAGASSERT(dst != NULL);
+
+    /* Stash a temporary copy so our caller can update in place. */
+    memcpy(tmp, src, NS_INADDRSZ);
+    /* Mark this ipv6 addr as a mapped ipv4. */
+    for (i = 0; i < 10; i++) *p++ = 0x00;
+    *p++ = 0xff;
+    *p++ = 0xff;
+    /* Retrieve the saved copy and we're done. */
+    memcpy(p, tmp, NS_INADDRSZ);
+}
+
+static void convert_v4v6_hostent(struct hostent* hp, char** bpp, char* ep,
+                                 std::function<void(struct hostent* hp)> map_param,
+                                 std::function<void(char* src, char* dst)> map_addr) {
+    _DIAGASSERT(hp != NULL);
+    _DIAGASSERT(bpp != NULL);
+    _DIAGASSERT(ep != NULL);
+
+    if (hp->h_addrtype != AF_INET || hp->h_length != NS_INADDRSZ) return;
+    map_param(hp);
+    for (char** ap = hp->h_addr_list; *ap; ap++) {
+        int i = (int) (sizeof(align) - (size_t)((u_long) *bpp % sizeof(align)));
+
+        if (ep - *bpp < (i + NS_IN6ADDRSZ)) {
+            /* Out of memory.  Truncate address list here.  XXX */
+            *ap = NULL;
+            return;
+        }
+        *bpp += i;
+        map_addr(*ap, *bpp);
+        *ap = *bpp;
+        *bpp += NS_IN6ADDRSZ;
+    }
+}
+
+static void map_v4v6_hostent(struct hostent* hp, char** bpp, char* ep) {
+    convert_v4v6_hostent(hp, bpp, ep,
+                         [](struct hostent* hp) {
+                             hp->h_addrtype = AF_INET6;
+                             hp->h_length = NS_IN6ADDRSZ;
+                         },
+                         [](char* src, char* dst) { map_v4v6_address(src, dst); });
+}
+
+/* Reserve space for mapping IPv4 address to IPv6 address in place */
+static void pad_v4v6_hostent(struct hostent* hp, char** bpp, char* ep) {
+    convert_v4v6_hostent(hp, bpp, ep,
+                         [](struct hostent* hp) {
+                             (void) hp; /* unused */
+                         },
+                         [](char* src, char* dst) {
+                             memcpy(dst, src, NS_INADDRSZ);
+                             memcpy(dst + NS_INADDRSZ, NAT64_PAD, sizeof(NAT64_PAD));
+                         });
+}
+
+static void addrsort(char** ap, int num, res_state res) {
+    int i, j;
+    char** p;
+    short aval[MAXADDRS];
+    int needsort = 0;
+
+    _DIAGASSERT(ap != NULL);
+
+    p = ap;
+    for (i = 0; i < num; i++, p++) {
+        for (j = 0; (unsigned) j < res->nsort; j++)
+            if (res->sort_list[j].addr.s_addr ==
+                (((struct in_addr*) (void*) (*p))->s_addr & res->sort_list[j].mask))
+                break;
+        aval[i] = j;
+        if (needsort == 0 && i > 0 && j < aval[i - 1]) needsort = i;
+    }
+    if (!needsort) return;
+
+    while (needsort < num) {
+        for (j = needsort - 1; j >= 0; j--) {
+            if (aval[j] > aval[j + 1]) {
+                char* hp;
+
+                i = aval[j];
+                aval[j] = aval[j + 1];
+                aval[j + 1] = i;
+
+                hp = ap[j];
+                ap[j] = ap[j + 1];
+                ap[j + 1] = hp;
+            } else
+                break;
+        }
+        needsort++;
+    }
+}
+
+static int dns_gethtbyname(const char* name, int addr_type, getnamaddr* info) {
+    int n, type;
+    info->hp->h_addrtype = addr_type;
+
+    switch (info->hp->h_addrtype) {
+        case AF_INET:
+            info->hp->h_length = NS_INADDRSZ;
+            type = T_A;
+            break;
+        case AF_INET6:
+            info->hp->h_length = NS_IN6ADDRSZ;
+            type = T_AAAA;
+            break;
+        default:
+            return EAI_FAMILY;
+    }
+    auto buf = std::make_unique<querybuf>();
+
+    res_state res = res_get_state();
+    if (!res) return EAI_MEMORY;
+
+    int he;
+    n = res_nsearch(res, name, C_IN, type, buf->buf, (int)sizeof(buf->buf), &he);
+    if (n < 0) {
+        LOG(DEBUG) << __func__ << ": res_nsearch failed (" << n << ")";
+        // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA.
+        // Note that res_nsearch() doesn't set the pair NETDB_INTERNAL and errno.
+        // See also herrnoToAiErrno().
+        return herrnoToAiErrno(he);
+    }
+    hostent* hp = getanswer(buf.get(), n, name, type, res, info->hp, info->buf, info->buflen, &he);
+    if (hp == NULL) return herrnoToAiErrno(he);
+
+    return 0;
+}
+
+static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
+                           const android_net_context* netcontext, getnamaddr* info,
+                           NetworkDnsEventReported* event) {
+    char qbuf[MAXDNAME + 1], *qp, *ep;
+    int n;
+    int advance;
+
+    info->hp->h_length = len;
+    info->hp->h_addrtype = af;
+
+    switch (info->hp->h_addrtype) {
+        case AF_INET:
+            (void) snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa", (uaddr[3] & 0xff),
+                            (uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff));
+            break;
+
+        case AF_INET6:
+            qp = qbuf;
+            ep = qbuf + sizeof(qbuf) - 1;
+            for (n = NS_IN6ADDRSZ - 1; n >= 0; n--) {
+                advance = snprintf(qp, (size_t)(ep - qp), "%x.%x.", uaddr[n] & 0xf,
+                                   ((unsigned int) uaddr[n] >> 4) & 0xf);
+                if (advance > 0 && qp + advance < ep)
+                    qp += advance;
+                else {
+                    // TODO: Consider converting to a private extended EAI_* error code.
+                    // Currently, the EAI_* value has no corresponding error code for an internal
+                    // out of buffer space. In order to not rely on errno, convert the original
+                    // error code EAI_SYSTEM to EAI_MEMORY.
+                    return EAI_MEMORY;
+                }
+            }
+            if (strlcat(qbuf, "ip6.arpa", sizeof(qbuf)) >= sizeof(qbuf)) {
+                // TODO: Consider converting to a private extended EAI_* error code.
+                // Currently, the EAI_* value has no corresponding error code for an internal
+                // out of buffer space. In order to not rely on errno, convert the original
+                // error code EAI_SYSTEM to EAI_MEMORY.
+                return EAI_MEMORY;
+            }
+            break;
+        default:
+            return EAI_FAMILY;
+    }
+
+    auto buf = std::make_unique<querybuf>();
+
+    res_state res = res_get_state();
+    if (!res) return EAI_MEMORY;
+
+    res_setnetcontext(res, netcontext, event);
+    int he;
+    n = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, (int)sizeof(buf->buf), &he);
+    if (n < 0) {
+        LOG(DEBUG) << __func__ << ": res_nquery failed (" << n << ")";
+        // Note that res_nquery() doesn't set the pair NETDB_INTERNAL and errno.
+        // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA.
+        // See also herrnoToAiErrno().
+        return herrnoToAiErrno(he);
+    }
+    hostent* hp = getanswer(buf.get(), n, qbuf, T_PTR, res, info->hp, info->buf, info->buflen, &he);
+    if (hp == NULL) return herrnoToAiErrno(he);
+
+    char* bf = (char*) (hp->h_addr_list + 2);
+    size_t blen = (size_t)(bf - info->buf);
+    if (blen + info->hp->h_length > info->buflen) goto nospc;
+    hp->h_addr_list[0] = bf;
+    hp->h_addr_list[1] = NULL;
+    memcpy(bf, uaddr, (size_t) info->hp->h_length);
+    if (info->hp->h_addrtype == AF_INET && (res->options & RES_USE_INET6)) {
+        if (blen + NS_IN6ADDRSZ > info->buflen) goto nospc;
+        map_v4v6_address(bf, bf);
+        hp->h_addrtype = AF_INET6;
+        hp->h_length = NS_IN6ADDRSZ;
+    }
+
+    /* Reserve enough space for mapping IPv4 address to IPv6 address in place */
+    if (info->hp->h_addrtype == AF_INET) {
+        if (blen + NS_IN6ADDRSZ > info->buflen) goto nospc;
+        // Pad zero to the unused address space
+        memcpy(bf + NS_INADDRSZ, NAT64_PAD, sizeof(NAT64_PAD));
+    }
+
+    return 0;
+
+nospc:
+    return EAI_MEMORY;
+}
+
+/*
+ * Non-reentrant versions.
+ */
+
+int android_gethostbynamefornetcontext(const char* name, int af,
+                                       const struct android_net_context* netcontext, hostent** hp,
+                                       NetworkDnsEventReported* event) {
+    assert(event != nullptr);
+
+    res_state res = res_get_state();
+    if (res == NULL) return EAI_MEMORY;
+    res_static* rs = res_get_static();  // For thread-safety.
+    int error;
+    error = gethostbyname_internal(name, af, res, &rs->host, rs->hostbuf, sizeof(rs->hostbuf),
+                                   netcontext, event);
+    if (error == 0) {
+        *hp = &rs->host;
+    }
+    return error;
+}
+
+int android_gethostbyaddrfornetcontext(const void* addr, socklen_t len, int af,
+                                       const struct android_net_context* netcontext, hostent** hp,
+                                       NetworkDnsEventReported* event) {
+    return android_gethostbyaddrfornetcontext_proxy(addr, len, af, netcontext, hp, event);
+}
+
+static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
+                                                    const struct android_net_context* netcontext,
+                                                    hostent** hp, NetworkDnsEventReported* event) {
+    assert(event != nullptr);
+
+    struct res_static* rs = res_get_static();  // For thread-safety.
+    int error = android_gethostbyaddrfornetcontext_proxy_internal(
+            addr, len, af, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), netcontext, event);
+    if (error == 0) *hp = &rs->host;
+    return error;
+}
+
+int herrnoToAiErrno(int he) {
+    switch (he) {
+        // extended h_errno
+        case NETD_RESOLV_H_ERRNO_EXT_TIMEOUT:
+            return NETD_RESOLV_TIMEOUT;
+        // legacy h_errno
+        case NETDB_SUCCESS:
+            return 0;
+        case HOST_NOT_FOUND:  // TODO: Perhaps convert HOST_NOT_FOUND to EAI_NONAME instead
+        case NO_DATA:         // NO_ADDRESS
+            return EAI_NODATA;
+        case TRY_AGAIN:
+            return EAI_AGAIN;
+        case NETDB_INTERNAL:
+            // TODO: Remove ENOSPC and call abort() immediately whenever any allocation fails.
+            if (errno == ENOSPC) return EAI_MEMORY;
+            // Theoretically, this should not happen. Leave this here just in case.
+            // Currently, getanswer() of {gethnamaddr, getaddrinfo}.cpp, res_nsearch() and
+            // res_searchN() use this function to convert error code. Only getanswer()
+            // of gethnamaddr.cpp may return the error code pair, herrno NETDB_INTERNAL and
+            // errno ENOSPC, which has already converted to EAI_MEMORY. The remaining functions
+            // don't set the pair herrno and errno.
+            return EAI_SYSTEM;  // see errno for detail
+        case NO_RECOVERY:
+        default:
+            return EAI_FAIL;  // TODO: Perhaps convert default to EAI_MAX (unknown error) instead
+    }
+}
diff --git a/resolv/gethnamaddr.h b/resolv/gethnamaddr.h
new file mode 100644
index 0000000..bfdb14e
--- /dev/null
+++ b/resolv/gethnamaddr.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <netdb.h>               // struct hostent
+#include "netd_resolv/resolv.h"  // struct android_net_context
+#include "stats.pb.h"
+
+// This is the entry point for the gethostbyname() family of legacy calls.
+int android_gethostbynamefornetcontext(const char*, int, const android_net_context*, hostent**,
+                                       android::net::NetworkDnsEventReported*);
+
+// This is the entry point for the gethostbyaddr() family of legacy calls.
+int android_gethostbyaddrfornetcontext(const void*, socklen_t, int, const android_net_context*,
+                                       hostent**, android::net::NetworkDnsEventReported*);
diff --git a/resolv/hostent.h b/resolv/hostent.h
new file mode 100644
index 0000000..4f6a33b
--- /dev/null
+++ b/resolv/hostent.h
@@ -0,0 +1,72 @@
+/*	$NetBSD: hostent.h,v 1.2 2013/08/27 09:56:12 christos Exp $	*/
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef NETD_RESOLV_HOSTENT_H
+#define NETD_RESOLV_HOSTENT_H
+
+#include <netdb.h>
+#include <stdio.h>
+
+struct getnamaddr {
+    struct hostent* hp;
+    char* buf;
+    size_t buflen;
+};
+
+// /etc/hosts lookup
+int _hf_gethtbyaddr(const unsigned char* uaddr, int len, int af, getnamaddr* info);
+int _hf_gethtbyname2(const char* name, int af, getnamaddr* info);
+hostent* netbsd_gethostent_r(FILE*, struct hostent*, char*, size_t, int*);
+
+// Reserved padding for remapping IPv4 address to NAT64 synthesis IPv6 address
+static const char NAT64_PAD[NS_IN6ADDRSZ - NS_INADDRSZ] = {};
+
+#define HENT_ARRAY(dst, anum, ptr, len) do {     \
+        size_t _len = (anum + 1) * sizeof(*dst); \
+        if (_len > len) goto nospc;              \
+        dst = (char**) ptr;                      \
+        ptr += _len;                             \
+        len -= _len;                             \
+    } while (0)
+
+#define HENT_COPY(dst, src, slen, ptr, len) do { \
+        if ((size_t) slen > len) goto nospc;     \
+        memcpy(ptr, src, (size_t) slen);         \
+        dst = ptr;                               \
+        ptr += slen;                             \
+        len -= slen;                             \
+    } while (0)
+
+#define HENT_SCOPY(dst, src, ptr, len) do {  \
+        size_t _len = strlen(src) + 1;       \
+        HENT_COPY(dst, src, _len, ptr, len); \
+    } while (0)
+
+#endif  // NETD_RESOLV_HOSTENT_H
diff --git a/resolv/include/netd_resolv/params.h b/resolv/include/netd_resolv/params.h
new file mode 100644
index 0000000..93e6287
--- /dev/null
+++ b/resolv/include/netd_resolv/params.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NETD_RESOLV_PARAMS_H
+#define NETD_RESOLV_PARAMS_H
+
+#include <stdint.h>
+
+#define MAXNS 4            // max # name servers we'll track
+#define MAXDNSRCH 6        // max # domains in search path
+#define MAXDNSRCHPATH 256  // max length of domain search paths
+#define MAXNSSAMPLES 64    // max # samples to store per server
+
+// Per-netid configuration parameters passed from netd to the resolver
+struct res_params {
+    uint16_t sample_validity;  // sample lifetime in s
+    // threshold of success / total samples below which a server is considered broken
+    uint8_t success_threshold;  // 0: disable, value / 100 otherwise
+    uint8_t min_samples;        // min # samples needed for statistics to be considered meaningful
+    uint8_t max_samples;        // max # samples taken into account for statistics
+    int base_timeout_msec;      // base query retry timeout (if 0, use RES_TIMEOUT)
+    int retry_count;            // number of retries
+};
+
+#define LIBNETD_RESOLV_PUBLIC extern "C" [[gnu::visibility("default")]]
+
+#endif  // NETD_RESOLV_PARAMS_H
diff --git a/resolv/include/netd_resolv/resolv.h b/resolv/include/netd_resolv/resolv.h
new file mode 100644
index 0000000..3a71110
--- /dev/null
+++ b/resolv/include/netd_resolv/resolv.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "params.h"
+
+#include <netinet/in.h>
+
+typedef union sockaddr_union {
+    struct sockaddr sa;
+    struct sockaddr_in sin;
+    struct sockaddr_in6 sin6;
+} sockaddr_union;
+
+/*
+ * Passing NETID_UNSET as the netId causes system/netd/resolv/DnsProxyListener.cpp to
+ * fill in the appropriate default netId for the query.
+ */
+#define NETID_UNSET 0u
+
+/*
+ * MARK_UNSET represents the default (i.e. unset) value for a socket mark.
+ */
+#define MARK_UNSET 0u
+
+/*
+ * Error code extending EAI_* codes defined in bionic/libc/include/netdb.h.
+ * This error code, including EAI_*, returned from android_getaddrinfofornetcontext()
+ * and android_gethostbynamefornetcontext() are used for DNS metrics.
+ */
+#define NETD_RESOLV_TIMEOUT 255  // consistent with RCODE_TIMEOUT
+
+/*
+ * A struct to capture context relevant to network operations.
+ *
+ * Application and DNS netids/marks can differ from one another under certain
+ * circumstances, notably when a VPN applies to the given uid's traffic but the
+ * VPN network does not have its own DNS servers explicitly provisioned.
+ *
+ * The introduction of per-UID routing means the uid is also an essential part
+ * of the evaluation context. Its proper uninitialized value is
+ * NET_CONTEXT_INVALID_UID.
+ */
+struct android_net_context {
+    unsigned app_netid;
+    unsigned app_mark;
+    unsigned dns_netid;
+    unsigned dns_mark;
+    uid_t uid;
+    unsigned flags;
+};
+
+#define NET_CONTEXT_INVALID_UID ((uid_t) -1)
+#define NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS 0x00000001
+#define NET_CONTEXT_FLAG_USE_EDNS 0x00000002
+
+// TODO: investigate having the resolver check permissions itself, either by adding support to
+// libbinder_ndk or by converting IPermissionController into a stable AIDL interface.
+typedef bool (*check_calling_permission_callback)(const char* permission);
+typedef void (*get_network_context_callback)(unsigned netid, uid_t uid,
+                                             android_net_context* netcontext);
+typedef void (*log_callback)(const char* msg);
+
+/*
+ * Some functions needed by the resolver (e.g. checkCallingPermission()) live in
+ * libraries with no ABI stability guarantees, such as libbinder.so.
+ * As a temporary workaround, we keep these functions in netd and call them via
+ * function pointers.
+ */
+struct ResolverNetdCallbacks {
+    check_calling_permission_callback check_calling_permission;
+    get_network_context_callback get_network_context;
+    log_callback log;
+};
+
+LIBNETD_RESOLV_PUBLIC bool resolv_has_nameservers(unsigned netid);
+
+// Set callbacks and bring DnsResolver up.
+LIBNETD_RESOLV_PUBLIC bool resolv_init(const ResolverNetdCallbacks* callbacks);
diff --git a/resolv/include/netd_resolv/resolv_stub.h b/resolv/include/netd_resolv/resolv_stub.h
new file mode 100644
index 0000000..41f56fa
--- /dev/null
+++ b/resolv/include/netd_resolv/resolv_stub.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef NETD_RESOLV_RESOLV_STUB_H
+#define NETD_RESOLV_RESOLV_STUB_H
+
+#include "resolv.h"
+#include "stats.h"
+
+// Struct containing function pointers for every function exported by libnetd_resolv.
+extern struct ResolvStub {
+    bool (*resolv_has_nameservers)(unsigned netid);
+
+    bool (*resolv_init)(const ResolverNetdCallbacks& callbacks);
+} RESOLV_STUB;
+
+int resolv_stub_init();
+
+#endif  // NETD_RESOLV_RESOLV_STUB_H
diff --git a/resolv/include/netd_resolv/stats.h b/resolv/include/netd_resolv/stats.h
new file mode 100644
index 0000000..7bfe845
--- /dev/null
+++ b/resolv/include/netd_resolv/stats.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NETD_RES_STATS_H
+#define NETD_RES_STATS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <time.h>
+
+#include "params.h"
+
+#define RCODE_INTERNAL_ERROR 254
+#define RCODE_TIMEOUT 255
+
+struct res_sample {
+    time_t at;      // time in s at which the sample was recorded
+    uint16_t rtt;   // round-trip time in ms
+    uint8_t rcode;  // the DNS rcode or RCODE_XXX defined above
+};
+
+// Resolver reachability statistics and run-time parameters.
+struct res_stats {
+    // Stats of the last <sample_count> queries.
+    res_sample samples[MAXNSSAMPLES];
+    // The number of samples stored.
+    uint8_t sample_count;
+    // The next sample to modify.
+    uint8_t sample_next;
+};
+
+// Aggregates the reachability statistics for the given server based on on the stored samples.
+LIBNETD_RESOLV_PUBLIC void android_net_res_stats_aggregate(res_stats* stats, int* successes,
+                                                           int* errors, int* timeouts,
+                                                           int* internal_errors, int* rtt_avg,
+                                                           time_t* last_sample_time);
+
+LIBNETD_RESOLV_PUBLIC int android_net_res_stats_get_info_for_net(
+        unsigned netid, int* nscount, sockaddr_storage servers[MAXNS], int* dcount,
+        char domains[MAXDNSRCH][MAXDNSRCHPATH], res_params* params, res_stats stats[MAXNS],
+        int* wait_for_pending_req_timeout_count);
+
+// Returns an array of bools indicating which servers are considered good
+LIBNETD_RESOLV_PUBLIC int android_net_res_stats_get_usable_servers(const res_params* params,
+                                                                   res_stats stats[], int nscount,
+                                                                   bool valid_servers[]);
+
+#endif  // NETD_RES_STATS_H
diff --git a/resolv/libnetd_resolv.map.txt b/resolv/libnetd_resolv.map.txt
new file mode 100644
index 0000000..be193db
--- /dev/null
+++ b/resolv/libnetd_resolv.map.txt
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This lists the entry points visible to applications that use the
+# libnetd_resolv library. Other entry points present in the library won't be
+# usable.
+
+LIBNETD_RESOLV {
+  global:
+    resolv_has_nameservers;
+    resolv_init;
+  local:
+    *;
+};
diff --git a/resolv/libnetd_resolv_test.cpp b/resolv/libnetd_resolv_test.cpp
new file mode 100644
index 0000000..6e4b9ee
--- /dev/null
+++ b/resolv/libnetd_resolv_test.cpp
@@ -0,0 +1,609 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "libnetd_resolv_test"
+
+#include <gtest/gtest.h>
+
+#include <android-base/stringprintf.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include "dns_responder.h"
+#include "getaddrinfo.h"
+#include "gethnamaddr.h"
+#include "resolv_cache.h"
+#include "stats.pb.h"
+
+// TODO: make this dynamic and stop depending on implementation details.
+constexpr unsigned int TEST_NETID = 30;
+
+// Specifying 0 in ai_socktype or ai_protocol of struct addrinfo indicates that any type or
+// protocol can be returned by getaddrinfo().
+constexpr unsigned int ANY = 0;
+
+using android::base::StringPrintf;
+
+namespace android {
+namespace net {
+
+using android::net::NetworkDnsEventReported;
+
+// Minimize class ResolverTest to be class TestBase because class TestBase doesn't need all member
+// functions of class ResolverTest and class DnsResponderClient.
+class TestBase : public ::testing::Test {
+  protected:
+    void SetUp() override {
+        // Create cache for test
+        resolv_create_cache_for_net(TEST_NETID);
+    }
+    void TearDown() override {
+        // Delete cache for test
+        resolv_delete_cache_for_net(TEST_NETID);
+    }
+
+    static std::string ToString(const hostent* he) {
+        if (he == nullptr) return "<null>";
+        char buffer[INET6_ADDRSTRLEN];
+        if (!inet_ntop(he->h_addrtype, he->h_addr_list[0], buffer, sizeof(buffer))) {
+            return "<invalid>";
+        }
+        return buffer;
+    }
+
+    static std::string ToString(const addrinfo* ai) {
+        if (!ai) return "<null>";
+        for (const auto* aip = ai; aip != nullptr; aip = aip->ai_next) {
+            char host[NI_MAXHOST];
+            int rv = getnameinfo(aip->ai_addr, aip->ai_addrlen, host, sizeof(host), nullptr, 0,
+                                 NI_NUMERICHOST);
+            if (rv != 0) return gai_strerror(rv);
+            return host;
+        }
+        return "<invalid>";
+    }
+
+    size_t GetNumQueries(const test::DNSResponder& dns, const char* name) const {
+        auto queries = dns.queries();
+        size_t found = 0;
+        for (const auto& p : queries) {
+            if (p.first == name) {
+                ++found;
+            }
+        }
+        return found;
+    }
+
+    const char* mDefaultSearchDomains = "example.com";
+    const res_params mDefaultParams_Binder = {
+            .sample_validity = 300,
+            .success_threshold = 25,
+            .min_samples = 8,
+            .max_samples = 8,
+            .base_timeout_msec = 1000,
+            .retry_count = 2,
+    };
+    const android_net_context mNetcontext = {
+            .app_netid = TEST_NETID,
+            .app_mark = MARK_UNSET,
+            .dns_netid = TEST_NETID,
+            .dns_mark = MARK_UNSET,
+            .uid = NET_CONTEXT_INVALID_UID,
+    };
+};
+
+class GetAddrInfoForNetContextTest : public TestBase {};
+class GetHostByNameForNetContextTest : public TestBase {};
+
+TEST_F(GetAddrInfoForNetContextTest, InvalidParameters) {
+    // Both null "netcontext" and null "res" of android_getaddrinfofornetcontext() are not tested
+    // here because they are checked by assert() without returning any error number.
+
+    // Invalid hostname and servname.
+    // Both hostname and servname are null pointers. Expect error number EAI_NONAME.
+    struct addrinfo* result = nullptr;
+    NetworkDnsEventReported event;
+    int rv = android_getaddrinfofornetcontext(nullptr /*hostname*/, nullptr /*servname*/,
+                                              nullptr /*hints*/, &mNetcontext, &result, &event);
+    EXPECT_EQ(EAI_NONAME, rv);
+    if (result) {
+        freeaddrinfo(result);
+        result = nullptr;
+    }
+
+    // Invalid hints.
+    // These place holders are used to test function call with unrequired parameters.
+    // The content is not important because function call returns error directly if
+    // there have any unrequired parameter.
+    char placeholder_cname[] = "invalid_cname";
+    sockaddr placeholder_addr = {};
+    addrinfo placeholder_next = {};
+    static const struct TestConfig {
+        int ai_flags;
+        socklen_t ai_addrlen;
+        char* ai_canonname;
+        struct sockaddr* ai_addr;
+        struct addrinfo* ai_next;
+        int expected_errorno;  // expected result
+
+        std::string asParameters() const {
+            return StringPrintf("0x%x/%u/%s/%p/%p", ai_flags, ai_addrlen,
+                                ai_canonname ? ai_canonname : "(null)", (void*) ai_addr,
+                                (void*) ai_next);
+        }
+    } testConfigs[]{
+            {0, sizeof(struct in_addr) /*bad*/, nullptr, nullptr, nullptr, EAI_BADHINTS},
+            {0, 0, placeholder_cname /*bad*/, nullptr, nullptr, EAI_BADHINTS},
+            {0, 0, nullptr, &placeholder_addr /*bad*/, nullptr, EAI_BADHINTS},
+            {0, 0, nullptr, nullptr, &placeholder_next /*bad*/, EAI_BADHINTS},
+            {AI_ALL /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS},
+            {AI_V4MAPPED_CFG /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS},
+            {AI_V4MAPPED /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS},
+            {AI_DEFAULT /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS},
+    };
+
+    for (const auto& config : testConfigs) {
+        SCOPED_TRACE(config.asParameters());
+
+        // In current test configuration set, ai_family, ai_protocol and ai_socktype are not
+        // checked because other fields cause hints error check failed first.
+        const struct addrinfo hints = {
+                .ai_flags = config.ai_flags,
+                .ai_family = AF_UNSPEC,
+                .ai_socktype = ANY,
+                .ai_protocol = ANY,
+                .ai_addrlen = config.ai_addrlen,
+                .ai_canonname = config.ai_canonname,
+                .ai_addr = config.ai_addr,
+                .ai_next = config.ai_next,
+        };
+
+        NetworkDnsEventReported event;
+        rv = android_getaddrinfofornetcontext("localhost", nullptr /*servname*/, &hints,
+                                              &mNetcontext, &result, &event);
+        EXPECT_EQ(config.expected_errorno, rv);
+
+        if (result) {
+            freeaddrinfo(result);
+            result = nullptr;
+        }
+    }
+}
+
+TEST_F(GetAddrInfoForNetContextTest, InvalidParameters_Family) {
+    for (int family = 0; family < AF_MAX; ++family) {
+        if (family == AF_UNSPEC || family == AF_INET || family == AF_INET6) {
+            continue;  // skip supported family
+        }
+        SCOPED_TRACE(StringPrintf("family: %d", family));
+
+        struct addrinfo* result = nullptr;
+        const struct addrinfo hints = {
+                .ai_family = family,  // unsupported family
+        };
+
+        NetworkDnsEventReported event;
+        int rv = android_getaddrinfofornetcontext("localhost", nullptr /*servname*/, &hints,
+                                                  &mNetcontext, &result, &event);
+        EXPECT_EQ(EAI_FAMILY, rv);
+
+        if (result) freeaddrinfo(result);
+    }
+}
+
+TEST_F(GetAddrInfoForNetContextTest, InvalidParameters_MeaningfulSocktypeAndProtocolCombination) {
+    static const int families[] = {PF_INET, PF_INET6, PF_UNSPEC};
+    // Skip to test socket type SOCK_RAW in meaningful combination (explore_options[]) of
+    // system\netd\resolv\getaddrinfo.cpp. In explore_options[], the socket type SOCK_RAW always
+    // comes with protocol ANY which causes skipping meaningful socktype/protocol combination
+    // check. So it nerver returns error number EAI_BADHINTS which we want to test in this test
+    // case.
+    static const int socktypes[] = {SOCK_STREAM, SOCK_DGRAM};
+
+    // If both socktype/protocol are specified, check non-meaningful combination returns
+    // expected error number EAI_BADHINTS. See meaningful combination in explore_options[] of
+    // system\netd\resolv\getaddrinfo.cpp.
+    for (const auto& family : families) {
+        for (const auto& socktype : socktypes) {
+            for (int protocol = 0; protocol < IPPROTO_MAX; ++protocol) {
+                SCOPED_TRACE(StringPrintf("family: %d, socktype: %d, protocol: %d", family,
+                                          socktype, protocol));
+
+                // Both socktype/protocol need to be specified.
+                if (!socktype || !protocol) continue;
+
+                // Skip meaningful combination in explore_options[] of
+                // system\netd\resolv\getaddrinfo.cpp.
+                if ((family == AF_INET6 && socktype == SOCK_DGRAM && protocol == IPPROTO_UDP) ||
+                    (family == AF_INET6 && socktype == SOCK_STREAM && protocol == IPPROTO_TCP) ||
+                    (family == AF_INET && socktype == SOCK_DGRAM && protocol == IPPROTO_UDP) ||
+                    (family == AF_INET && socktype == SOCK_STREAM && protocol == IPPROTO_TCP) ||
+                    (family == AF_UNSPEC && socktype == SOCK_DGRAM && protocol == IPPROTO_UDP) ||
+                    (family == AF_UNSPEC && socktype == SOCK_STREAM && protocol == IPPROTO_TCP)) {
+                    continue;
+                }
+
+                struct addrinfo* result = nullptr;
+                const struct addrinfo hints = {
+                        .ai_family = family,
+                        .ai_protocol = protocol,
+                        .ai_socktype = socktype,
+                };
+
+                NetworkDnsEventReported event;
+                int rv = android_getaddrinfofornetcontext("localhost", nullptr /*servname*/, &hints,
+                                                          &mNetcontext, &result, &event);
+                EXPECT_EQ(EAI_BADHINTS, rv);
+
+                if (result) freeaddrinfo(result);
+            }
+        }
+    }
+}
+
+TEST_F(GetAddrInfoForNetContextTest, InvalidParameters_PortNameAndNumber) {
+    constexpr char http_portno[] = "80";
+    constexpr char invalid_portno[] = "65536";  // out of valid port range from 0 to 65535
+    constexpr char http_portname[] = "http";
+    constexpr char invalid_portname[] = "invalid_portname";
+
+    static const struct TestConfig {
+        int ai_flags;
+        int ai_family;
+        int ai_socktype;
+        const char* servname;
+        int expected_errorno;  // expected result
+
+        std::string asParameters() const {
+            return StringPrintf("0x%x/%d/%d/%s", ai_flags, ai_family, ai_socktype,
+                                servname ? servname : "(null)");
+        }
+    } testConfigs[]{
+            {0, AF_INET, SOCK_RAW /*bad*/, http_portno, EAI_SERVICE},
+            {0, AF_INET6, SOCK_RAW /*bad*/, http_portno, EAI_SERVICE},
+            {0, AF_UNSPEC, SOCK_RAW /*bad*/, http_portno, EAI_SERVICE},
+            {0, AF_INET, SOCK_RDM /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_INET6, SOCK_RDM /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_UNSPEC, SOCK_RDM /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_INET, SOCK_SEQPACKET /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_INET6, SOCK_SEQPACKET /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_UNSPEC, SOCK_SEQPACKET /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_INET, SOCK_DCCP /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_INET6, SOCK_DCCP /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_UNSPEC, SOCK_DCCP /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_INET, SOCK_PACKET /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_INET6, SOCK_PACKET /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_UNSPEC, SOCK_PACKET /*bad*/, http_portno, EAI_SOCKTYPE},
+            {0, AF_INET, ANY, invalid_portno /*bad*/, EAI_SERVICE},
+            {0, AF_INET, SOCK_STREAM, invalid_portno /*bad*/, EAI_SERVICE},
+            {0, AF_INET, SOCK_DGRAM, invalid_portno /*bad*/, EAI_SERVICE},
+            {0, AF_INET6, ANY, invalid_portno /*bad*/, EAI_SERVICE},
+            {0, AF_INET6, SOCK_STREAM, invalid_portno /*bad*/, EAI_SERVICE},
+            {0, AF_INET6, SOCK_DGRAM, invalid_portno /*bad*/, EAI_SERVICE},
+            {0, AF_UNSPEC, ANY, invalid_portno /*bad*/, EAI_SERVICE},
+            {0, AF_UNSPEC, SOCK_STREAM, invalid_portno /*bad*/, EAI_SERVICE},
+            {0, AF_UNSPEC, SOCK_DGRAM, invalid_portno /*bad*/, EAI_SERVICE},
+            {AI_NUMERICSERV, AF_INET, ANY, http_portname /*bad*/, EAI_NONAME},
+            {AI_NUMERICSERV, AF_INET, SOCK_STREAM, http_portname /*bad*/, EAI_NONAME},
+            {AI_NUMERICSERV, AF_INET, SOCK_DGRAM, http_portname /*bad*/, EAI_NONAME},
+            {AI_NUMERICSERV, AF_INET6, ANY, http_portname /*bad*/, EAI_NONAME},
+            {AI_NUMERICSERV, AF_INET6, SOCK_STREAM, http_portname /*bad*/, EAI_NONAME},
+            {AI_NUMERICSERV, AF_INET6, SOCK_DGRAM, http_portname /*bad*/, EAI_NONAME},
+            {AI_NUMERICSERV, AF_UNSPEC, ANY, http_portname /*bad*/, EAI_NONAME},
+            {AI_NUMERICSERV, AF_UNSPEC, SOCK_STREAM, http_portname /*bad*/, EAI_NONAME},
+            {AI_NUMERICSERV, AF_UNSPEC, SOCK_DGRAM, http_portname /*bad*/, EAI_NONAME},
+            {0, AF_INET, ANY, invalid_portname /*bad*/, EAI_SERVICE},
+            {0, AF_INET, SOCK_STREAM, invalid_portname /*bad*/, EAI_SERVICE},
+            {0, AF_INET, SOCK_DGRAM, invalid_portname /*bad*/, EAI_SERVICE},
+            {0, AF_INET6, ANY, invalid_portname /*bad*/, EAI_SERVICE},
+            {0, AF_INET6, SOCK_STREAM, invalid_portname /*bad*/, EAI_SERVICE},
+            {0, AF_INET6, SOCK_DGRAM, invalid_portname /*bad*/, EAI_SERVICE},
+            {0, AF_UNSPEC, ANY, invalid_portname /*bad*/, EAI_SERVICE},
+            {0, AF_UNSPEC, SOCK_STREAM, invalid_portname /*bad*/, EAI_SERVICE},
+            {0, AF_UNSPEC, SOCK_DGRAM, invalid_portname /*bad*/, EAI_SERVICE},
+    };
+
+    for (const auto& config : testConfigs) {
+        const std::string testParameters = config.asParameters();
+        SCOPED_TRACE(testParameters);
+
+        const struct addrinfo hints = {
+                .ai_flags = config.ai_flags,
+                .ai_family = config.ai_family,
+                .ai_socktype = config.ai_socktype,
+        };
+
+        struct addrinfo* result = nullptr;
+        NetworkDnsEventReported event;
+        int rv = android_getaddrinfofornetcontext("localhost", config.servname, &hints,
+                                                  &mNetcontext, &result, &event);
+        EXPECT_EQ(config.expected_errorno, rv);
+
+        if (result) freeaddrinfo(result);
+    }
+}
+
+TEST_F(GetAddrInfoForNetContextTest, AlphabeticalHostname_NoData) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_srv[] = "53";
+    constexpr char v4_host_name[] = "v4only.example.com.";
+    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
+    dns.addMapping(v4_host_name, ns_type::ns_t_a, "1.2.3.3");
+    ASSERT_TRUE(dns.startServer());
+    const char* servers[] = {listen_addr};
+    ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
+                                                sizeof(servers) / sizeof(servers[0]),
+                                                mDefaultSearchDomains, &mDefaultParams_Binder));
+    dns.clearQueries();
+
+    // Want AAAA answer but DNS server has A answer only.
+    struct addrinfo* result = nullptr;
+    const addrinfo hints = {.ai_family = AF_INET6};
+    NetworkDnsEventReported event;
+    int rv = android_getaddrinfofornetcontext("v4only", nullptr, &hints, &mNetcontext, &result,
+                                              &event);
+    EXPECT_LE(1U, GetNumQueries(dns, v4_host_name));
+    EXPECT_TRUE(result == nullptr);
+    EXPECT_EQ(EAI_NODATA, rv);
+
+    if (result) freeaddrinfo(result);
+}
+
+TEST_F(GetAddrInfoForNetContextTest, AlphabeticalHostname) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_srv[] = "53";
+    constexpr char host_name[] = "sawadee.example.com.";
+    constexpr char v4addr[] = "1.2.3.4";
+    constexpr char v6addr[] = "::1.2.3.4";
+
+    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
+    dns.addMapping(host_name, ns_type::ns_t_a, v4addr);
+    dns.addMapping(host_name, ns_type::ns_t_aaaa, v6addr);
+    ASSERT_TRUE(dns.startServer());
+    const char* servers[] = {listen_addr};
+    ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
+                                                sizeof(servers) / sizeof(servers[0]),
+                                                mDefaultSearchDomains, &mDefaultParams_Binder));
+
+    static const struct TestConfig {
+        int ai_family;
+        const std::string expected_addr;
+    } testConfigs[]{
+            {AF_INET, v4addr},
+            {AF_INET6, v6addr},
+    };
+
+    for (const auto& config : testConfigs) {
+        SCOPED_TRACE(StringPrintf("family: %d", config.ai_family));
+        dns.clearQueries();
+
+        struct addrinfo* result = nullptr;
+        const struct addrinfo hints = {.ai_family = config.ai_family};
+        NetworkDnsEventReported event;
+        int rv = android_getaddrinfofornetcontext("sawadee", nullptr, &hints, &mNetcontext, &result,
+                                                  &event);
+        EXPECT_EQ(0, rv);
+        EXPECT_TRUE(result != nullptr);
+        EXPECT_EQ(1U, GetNumQueries(dns, host_name));
+        EXPECT_EQ(config.expected_addr, ToString(result));
+
+        if (result) freeaddrinfo(result);
+    }
+}
+
+TEST_F(GetAddrInfoForNetContextTest, ServerResponseError) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_srv[] = "53";
+    constexpr char host_name[] = "hello.example.com.";
+
+    static const struct TestConfig {
+        ns_rcode rcode;
+        int expected_errorno;  // expected result
+
+        // Only test failure RCODE [1..5] in RFC 1035 section 4.1.1 and skip successful RCODE 0
+        // which means no error.
+    } testConfigs[]{
+            // clang-format off
+            {ns_rcode::ns_r_formerr, EAI_FAIL},
+            {ns_rcode::ns_r_servfail, EAI_AGAIN},
+            {ns_rcode::ns_r_nxdomain, EAI_NODATA},
+            {ns_rcode::ns_r_notimpl, EAI_FAIL},
+            {ns_rcode::ns_r_refused, EAI_FAIL},
+            // clang-format on
+    };
+
+    for (const auto& config : testConfigs) {
+        SCOPED_TRACE(StringPrintf("rcode: %d", config.rcode));
+
+        test::DNSResponder dns(listen_addr, listen_srv, 250,
+                               config.rcode /*response specific rcode*/);
+        dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
+        dns.setResponseProbability(0.0);  // always ignore requests and response preset rcode
+        ASSERT_TRUE(dns.startServer());
+        const char* servers[] = {listen_addr};
+        ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
+                                                    sizeof(servers) / sizeof(servers[0]),
+                                                    mDefaultSearchDomains, &mDefaultParams_Binder));
+
+        struct addrinfo* result = nullptr;
+        const struct addrinfo hints = {.ai_family = AF_UNSPEC};
+        NetworkDnsEventReported event;
+        int rv = android_getaddrinfofornetcontext(host_name, nullptr, &hints, &mNetcontext, &result,
+                                                  &event);
+        EXPECT_EQ(config.expected_errorno, rv);
+
+        if (result) freeaddrinfo(result);
+    }
+}
+
+// TODO: Add private DNS server timeout test.
+TEST_F(GetAddrInfoForNetContextTest, ServerTimeout) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_srv[] = "53";
+    constexpr char host_name[] = "hello.example.com.";
+    test::DNSResponder dns(listen_addr, listen_srv, 250, static_cast<ns_rcode>(-1) /*no response*/);
+    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
+    dns.setResponseProbability(0.0);  // always ignore requests and don't response
+    ASSERT_TRUE(dns.startServer());
+    const char* servers[] = {listen_addr};
+    ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
+                                                sizeof(servers) / sizeof(servers[0]),
+                                                mDefaultSearchDomains, &mDefaultParams_Binder));
+
+    struct addrinfo* result = nullptr;
+    const struct addrinfo hints = {.ai_family = AF_UNSPEC};
+    NetworkDnsEventReported event;
+    int rv = android_getaddrinfofornetcontext("hello", nullptr, &hints, &mNetcontext, &result,
+                                              &event);
+    EXPECT_EQ(NETD_RESOLV_TIMEOUT, rv);
+
+    if (result) freeaddrinfo(result);
+}
+
+TEST_F(GetHostByNameForNetContextTest, AlphabeticalHostname) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_srv[] = "53";
+    constexpr char host_name[] = "jiababuei.example.com.";
+    constexpr char v4addr[] = "1.2.3.4";
+    constexpr char v6addr[] = "::1.2.3.4";
+
+    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
+    dns.addMapping(host_name, ns_type::ns_t_a, v4addr);
+    dns.addMapping(host_name, ns_type::ns_t_aaaa, v6addr);
+    ASSERT_TRUE(dns.startServer());
+    const char* servers[] = {listen_addr};
+    ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
+                                                sizeof(servers) / sizeof(servers[0]),
+                                                mDefaultSearchDomains, &mDefaultParams_Binder));
+
+    static const struct TestConfig {
+        int ai_family;
+        const std::string expected_addr;
+    } testConfigs[]{
+            {AF_INET, v4addr},
+            {AF_INET6, v6addr},
+    };
+
+    for (const auto& config : testConfigs) {
+        SCOPED_TRACE(StringPrintf("family: %d", config.ai_family));
+        dns.clearQueries();
+
+        struct hostent* hp = nullptr;
+        NetworkDnsEventReported event;
+        int rv = android_gethostbynamefornetcontext("jiababuei", config.ai_family, &mNetcontext,
+                                                    &hp, &event);
+        EXPECT_EQ(0, rv);
+        EXPECT_TRUE(hp != nullptr);
+        EXPECT_EQ(1U, GetNumQueries(dns, host_name));
+        EXPECT_EQ(config.expected_addr, ToString(hp));
+    }
+}
+
+TEST_F(GetHostByNameForNetContextTest, NoData) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_srv[] = "53";
+    constexpr char v4_host_name[] = "v4only.example.com.";
+    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
+    dns.addMapping(v4_host_name, ns_type::ns_t_a, "1.2.3.3");
+    ASSERT_TRUE(dns.startServer());
+    const char* servers[] = {listen_addr};
+    ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
+                                                sizeof(servers) / sizeof(servers[0]),
+                                                mDefaultSearchDomains, &mDefaultParams_Binder));
+    dns.clearQueries();
+
+    // Want AAAA answer but DNS server has A answer only.
+    struct hostent* hp = nullptr;
+    NetworkDnsEventReported event;
+    int rv = android_gethostbynamefornetcontext("v4only", AF_INET6, &mNetcontext, &hp, &event);
+    EXPECT_LE(1U, GetNumQueries(dns, v4_host_name));
+    EXPECT_TRUE(hp == nullptr);
+    EXPECT_EQ(EAI_NODATA, rv);
+}
+
+TEST_F(GetHostByNameForNetContextTest, ServerResponseError) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_srv[] = "53";
+    constexpr char host_name[] = "hello.example.com.";
+
+    static const struct TestConfig {
+        ns_rcode rcode;
+        int expected_errorno;  // expected result
+
+        // Only test failure RCODE [1..5] in RFC 1035 section 4.1.1 and skip successful RCODE 0
+        // which means no error. Note that the return error codes aren't mapped by rcode in the
+        // test case SERVFAIL, NOTIMP and REFUSED. See the comment of res_nsend()
+        // in system\netd\resolv\res_query.cpp for more detail.
+    } testConfigs[]{
+            // clang-format off
+            {ns_rcode::ns_r_formerr, EAI_FAIL},
+            {ns_rcode::ns_r_servfail, EAI_AGAIN},  // Not mapped by rcode.
+            {ns_rcode::ns_r_nxdomain, EAI_NODATA},
+            {ns_rcode::ns_r_notimpl, EAI_AGAIN},  // Not mapped by rcode.
+            {ns_rcode::ns_r_refused, EAI_AGAIN},  // Not mapped by rcode.
+            // clang-format on
+    };
+
+    for (const auto& config : testConfigs) {
+        SCOPED_TRACE(StringPrintf("rcode: %d", config.rcode));
+
+        test::DNSResponder dns(listen_addr, listen_srv, 250,
+                               config.rcode /*response specific rcode*/);
+        dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
+        dns.setResponseProbability(0.0);  // always ignore requests and response preset rcode
+        ASSERT_TRUE(dns.startServer());
+        const char* servers[] = {listen_addr};
+        ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
+                                                    sizeof(servers) / sizeof(servers[0]),
+                                                    mDefaultSearchDomains, &mDefaultParams_Binder));
+
+        struct hostent* hp = nullptr;
+        NetworkDnsEventReported event;
+        int rv = android_gethostbynamefornetcontext(host_name, AF_INET, &mNetcontext, &hp, &event);
+        EXPECT_TRUE(hp == nullptr);
+        EXPECT_EQ(config.expected_errorno, rv);
+    }
+}
+
+// TODO: Add private DNS server timeout test.
+TEST_F(GetHostByNameForNetContextTest, ServerTimeout) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_srv[] = "53";
+    constexpr char host_name[] = "hello.example.com.";
+    test::DNSResponder dns(listen_addr, listen_srv, 250, static_cast<ns_rcode>(-1) /*no response*/);
+    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
+    dns.setResponseProbability(0.0);  // always ignore requests and don't response
+    ASSERT_TRUE(dns.startServer());
+    const char* servers[] = {listen_addr};
+    ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
+                                                sizeof(servers) / sizeof(servers[0]),
+                                                mDefaultSearchDomains, &mDefaultParams_Binder));
+
+    struct hostent* hp = nullptr;
+    NetworkDnsEventReported event;
+    int rv = android_gethostbynamefornetcontext(host_name, AF_INET, &mNetcontext, &hp, &event);
+    EXPECT_EQ(NETD_RESOLV_TIMEOUT, rv);
+}
+
+// Note that local host file function, files_getaddrinfo(), of android_getaddrinfofornetcontext()
+// is not tested because it only returns a boolean (success or failure) without any error number.
+
+// TODO: Add test NULL hostname, or numeric hostname for android_getaddrinfofornetcontext.
+// TODO: Add test invalid parameters for android_gethostbynamefornetcontext.
+// TODO: Add test for android_gethostbyaddrfornetcontext.
+
+}  // end of namespace net
+}  // end of namespace android
diff --git a/resolv/res_cache.cpp b/resolv/res_cache.cpp
new file mode 100644
index 0000000..d6f0cd8
--- /dev/null
+++ b/resolv/res_cache.cpp
@@ -0,0 +1,2113 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define LOG_TAG "res_cache"
+
+#include "resolv_cache.h"
+
+#include <resolv.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <mutex>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <linux/if.h>
+#include <net/if.h>
+#include <netdb.h>
+
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android-base/thread_annotations.h>
+#include <android/multinetwork.h>  // ResNsendFlags
+
+#include <server_configurable_flags/get_flags.h>
+
+#include "res_state_ext.h"
+#include "resolv_private.h"
+
+// NOTE: verbose logging MUST NOT be left enabled in production binaries.
+// It floods logs at high rate, and can leak privacy-sensitive information.
+constexpr bool kDumpData = false;
+
+/* This code implements a small and *simple* DNS resolver cache.
+ *
+ * It is only used to cache DNS answers for a time defined by the smallest TTL
+ * among the answer records in order to reduce DNS traffic. It is not supposed
+ * to be a full DNS cache, since we plan to implement that in the future in a
+ * dedicated process running on the system.
+ *
+ * Note that its design is kept simple very intentionally, i.e.:
+ *
+ *  - it takes raw DNS query packet data as input, and returns raw DNS
+ *    answer packet data as output
+ *
+ *    (this means that two similar queries that encode the DNS name
+ *     differently will be treated distinctly).
+ *
+ *    the smallest TTL value among the answer records are used as the time
+ *    to keep an answer in the cache.
+ *
+ *    this is bad, but we absolutely want to avoid parsing the answer packets
+ *    (and should be solved by the later full DNS cache process).
+ *
+ *  - the implementation is just a (query-data) => (answer-data) hash table
+ *    with a trivial least-recently-used expiration policy.
+ *
+ * Doing this keeps the code simple and avoids to deal with a lot of things
+ * that a full DNS cache is expected to do.
+ *
+ * The API is also very simple:
+ *
+ *   - the client calls _resolv_cache_get() to obtain a handle to the cache.
+ *     this will initialize the cache on first usage. the result can be NULL
+ *     if the cache is disabled.
+ *
+ *   - the client calls _resolv_cache_lookup() before performing a query
+ *
+ *     if the function returns RESOLV_CACHE_FOUND, a copy of the answer data
+ *     has been copied into the client-provided answer buffer.
+ *
+ *     if the function returns RESOLV_CACHE_NOTFOUND, the client should perform
+ *     a request normally, *then* call _resolv_cache_add() to add the received
+ *     answer to the cache.
+ *
+ *     if the function returns RESOLV_CACHE_UNSUPPORTED, the client should
+ *     perform a request normally, and *not* call _resolv_cache_add()
+ *
+ *     note that RESOLV_CACHE_UNSUPPORTED is also returned if the answer buffer
+ *     is too short to accomodate the cached result.
+ */
+
+/* default number of entries kept in the cache. This value has been
+ * determined by browsing through various sites and counting the number
+ * of corresponding requests. Keep in mind that our framework is currently
+ * performing two requests per name lookup (one for IPv4, the other for IPv6)
+ *
+ *    www.google.com      4
+ *    www.ysearch.com     6
+ *    www.amazon.com      8
+ *    www.nytimes.com     22
+ *    www.espn.com        28
+ *    www.msn.com         28
+ *    www.lemonde.fr      35
+ *
+ * (determined in 2009-2-17 from Paris, France, results may vary depending
+ *  on location)
+ *
+ * most high-level websites use lots of media/ad servers with different names
+ * but these are generally reused when browsing through the site.
+ *
+ * As such, a value of 64 should be relatively comfortable at the moment.
+ *
+ * ******************************************
+ * * NOTE - this has changed.
+ * * 1) we've added IPv6 support so each dns query results in 2 responses
+ * * 2) we've made this a system-wide cache, so the cost is less (it's not
+ * *    duplicated in each process) and the need is greater (more processes
+ * *    making different requests).
+ * * Upping by 2x for IPv6
+ * * Upping by another 5x for the centralized nature
+ * *****************************************
+ */
+#define CONFIG_MAX_ENTRIES (64 * 2 * 5)
+
+/** BOUNDED BUFFER FORMATTING **/
+
+/* technical note:
+ *
+ *   the following debugging routines are used to append data to a bounded
+ *   buffer they take two parameters that are:
+ *
+ *   - p : a pointer to the current cursor position in the buffer
+ *         this value is initially set to the buffer's address.
+ *
+ *   - end : the address of the buffer's limit, i.e. of the first byte
+ *           after the buffer. this address should never be touched.
+ *
+ *           IMPORTANT: it is assumed that end > buffer_address, i.e.
+ *                      that the buffer is at least one byte.
+ *
+ *   the bprint_x() functions return the new value of 'p' after the data
+ *   has been appended, and also ensure the following:
+ *
+ *   - the returned value will never be strictly greater than 'end'
+ *
+ *   - a return value equal to 'end' means that truncation occurred
+ *     (in which case, end[-1] will be set to 0)
+ *
+ *   - after returning from a bprint_x() function, the content of the buffer
+ *     is always 0-terminated, even in the event of truncation.
+ *
+ *  these conventions allow you to call bprint_x() functions multiple times and
+ *  only check for truncation at the end of the sequence, as in:
+ *
+ *     char  buff[1000], *p = buff, *end = p + sizeof(buff);
+ *
+ *     p = bprint_c(p, end, '"');
+ *     p = bprint_s(p, end, my_string);
+ *     p = bprint_c(p, end, '"');
+ *
+ *     if (p >= end) {
+ *        // buffer was too small
+ *     }
+ *
+ *     printf( "%s", buff );
+ */
+
+/* Defaults used for initializing res_params */
+
+// If successes * 100 / total_samples is less than this value, the server is considered failing
+#define SUCCESS_THRESHOLD 75
+// Sample validity in seconds. Set to -1 to disable skipping failing servers.
+#define NSSAMPLE_VALIDITY 1800
+
+/* add a char to a bounded buffer */
+static char* bprint_c(char* p, char* end, int c) {
+    if (p < end) {
+        if (p + 1 == end)
+            *p++ = 0;
+        else {
+            *p++ = (char) c;
+            *p = 0;
+        }
+    }
+    return p;
+}
+
+/* add a sequence of bytes to a bounded buffer */
+static char* bprint_b(char* p, char* end, const char* buf, int len) {
+    int avail = end - p;
+
+    if (avail <= 0 || len <= 0) return p;
+
+    if (avail > len) avail = len;
+
+    memcpy(p, buf, avail);
+    p += avail;
+
+    if (p < end)
+        p[0] = 0;
+    else
+        end[-1] = 0;
+
+    return p;
+}
+
+/* add a string to a bounded buffer */
+static char* bprint_s(char* p, char* end, const char* str) {
+    return bprint_b(p, end, str, strlen(str));
+}
+
+/* add a formatted string to a bounded buffer */
+static char* bprint(char* p, char* end, const char* format, ...) {
+    int avail, n;
+    va_list args;
+
+    avail = end - p;
+
+    if (avail <= 0) return p;
+
+    va_start(args, format);
+    n = vsnprintf(p, avail, format, args);
+    va_end(args);
+
+    /* certain C libraries return -1 in case of truncation */
+    if (n < 0 || n > avail) n = avail;
+
+    p += n;
+    /* certain C libraries do not zero-terminate in case of truncation */
+    if (p == end) p[-1] = 0;
+
+    return p;
+}
+
+/* add a hex value to a bounded buffer, up to 8 digits */
+static char* bprint_hex(char* p, char* end, unsigned value, int numDigits) {
+    char text[sizeof(unsigned) * 2];
+    int nn = 0;
+
+    while (numDigits-- > 0) {
+        text[nn++] = "0123456789abcdef"[(value >> (numDigits * 4)) & 15];
+    }
+    return bprint_b(p, end, text, nn);
+}
+
+/* add the hexadecimal dump of some memory area to a bounded buffer */
+static char* bprint_hexdump(char* p, char* end, const uint8_t* data, int datalen) {
+    int lineSize = 16;
+
+    while (datalen > 0) {
+        int avail = datalen;
+        int nn;
+
+        if (avail > lineSize) avail = lineSize;
+
+        for (nn = 0; nn < avail; nn++) {
+            if (nn > 0) p = bprint_c(p, end, ' ');
+            p = bprint_hex(p, end, data[nn], 2);
+        }
+        for (; nn < lineSize; nn++) {
+            p = bprint_s(p, end, "   ");
+        }
+        p = bprint_s(p, end, "  ");
+
+        for (nn = 0; nn < avail; nn++) {
+            int c = data[nn];
+
+            if (c < 32 || c > 127) c = '.';
+
+            p = bprint_c(p, end, c);
+        }
+        p = bprint_c(p, end, '\n');
+
+        data += avail;
+        datalen -= avail;
+    }
+    return p;
+}
+
+/* dump the content of a query of packet to the log */
+static void dump_bytes(const uint8_t* base, int len) {
+    if (!kDumpData) return;
+
+    char buff[1024];
+    char *p = buff, *end = p + sizeof(buff);
+
+    p = bprint_hexdump(p, end, base, len);
+    LOG(INFO) << __func__ << ": " << buff;
+}
+
+static time_t _time_now(void) {
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec;
+}
+
+/* reminder: the general format of a DNS packet is the following:
+ *
+ *    HEADER  (12 bytes)
+ *    QUESTION  (variable)
+ *    ANSWER (variable)
+ *    AUTHORITY (variable)
+ *    ADDITIONNAL (variable)
+ *
+ * the HEADER is made of:
+ *
+ *   ID     : 16 : 16-bit unique query identification field
+ *
+ *   QR     :  1 : set to 0 for queries, and 1 for responses
+ *   Opcode :  4 : set to 0 for queries
+ *   AA     :  1 : set to 0 for queries
+ *   TC     :  1 : truncation flag, will be set to 0 in queries
+ *   RD     :  1 : recursion desired
+ *
+ *   RA     :  1 : recursion available (0 in queries)
+ *   Z      :  3 : three reserved zero bits
+ *   RCODE  :  4 : response code (always 0=NOERROR in queries)
+ *
+ *   QDCount: 16 : question count
+ *   ANCount: 16 : Answer count (0 in queries)
+ *   NSCount: 16: Authority Record count (0 in queries)
+ *   ARCount: 16: Additionnal Record count (0 in queries)
+ *
+ * the QUESTION is made of QDCount Question Record (QRs)
+ * the ANSWER is made of ANCount RRs
+ * the AUTHORITY is made of NSCount RRs
+ * the ADDITIONNAL is made of ARCount RRs
+ *
+ * Each Question Record (QR) is made of:
+ *
+ *   QNAME   : variable : Query DNS NAME
+ *   TYPE    : 16       : type of query (A=1, PTR=12, MX=15, AAAA=28, ALL=255)
+ *   CLASS   : 16       : class of query (IN=1)
+ *
+ * Each Resource Record (RR) is made of:
+ *
+ *   NAME    : variable : DNS NAME
+ *   TYPE    : 16       : type of query (A=1, PTR=12, MX=15, AAAA=28, ALL=255)
+ *   CLASS   : 16       : class of query (IN=1)
+ *   TTL     : 32       : seconds to cache this RR (0=none)
+ *   RDLENGTH: 16       : size of RDDATA in bytes
+ *   RDDATA  : variable : RR data (depends on TYPE)
+ *
+ * Each QNAME contains a domain name encoded as a sequence of 'labels'
+ * terminated by a zero. Each label has the following format:
+ *
+ *    LEN  : 8     : lenght of label (MUST be < 64)
+ *    NAME : 8*LEN : label length (must exclude dots)
+ *
+ * A value of 0 in the encoding is interpreted as the 'root' domain and
+ * terminates the encoding. So 'www.android.com' will be encoded as:
+ *
+ *   <3>www<7>android<3>com<0>
+ *
+ * Where <n> represents the byte with value 'n'
+ *
+ * Each NAME reflects the QNAME of the question, but has a slightly more
+ * complex encoding in order to provide message compression. This is achieved
+ * by using a 2-byte pointer, with format:
+ *
+ *    TYPE   : 2  : 0b11 to indicate a pointer, 0b01 and 0b10 are reserved
+ *    OFFSET : 14 : offset to another part of the DNS packet
+ *
+ * The offset is relative to the start of the DNS packet and must point
+ * A pointer terminates the encoding.
+ *
+ * The NAME can be encoded in one of the following formats:
+ *
+ *   - a sequence of simple labels terminated by 0 (like QNAMEs)
+ *   - a single pointer
+ *   - a sequence of simple labels terminated by a pointer
+ *
+ * A pointer shall always point to either a pointer of a sequence of
+ * labels (which can themselves be terminated by either a 0 or a pointer)
+ *
+ * The expanded length of a given domain name should not exceed 255 bytes.
+ *
+ * NOTE: we don't parse the answer packets, so don't need to deal with NAME
+ *       records, only QNAMEs.
+ */
+
+#define DNS_HEADER_SIZE 12
+
+#define DNS_TYPE_A "\00\01"     /* big-endian decimal 1 */
+#define DNS_TYPE_PTR "\00\014"  /* big-endian decimal 12 */
+#define DNS_TYPE_MX "\00\017"   /* big-endian decimal 15 */
+#define DNS_TYPE_AAAA "\00\034" /* big-endian decimal 28 */
+#define DNS_TYPE_ALL "\00\0377" /* big-endian decimal 255 */
+
+#define DNS_CLASS_IN "\00\01" /* big-endian decimal 1 */
+
+typedef struct {
+    const uint8_t* base;
+    const uint8_t* end;
+    const uint8_t* cursor;
+} DnsPacket;
+
+static void _dnsPacket_init(DnsPacket* packet, const uint8_t* buff, int bufflen) {
+    packet->base = buff;
+    packet->end = buff + bufflen;
+    packet->cursor = buff;
+}
+
+static void _dnsPacket_rewind(DnsPacket* packet) {
+    packet->cursor = packet->base;
+}
+
+static void _dnsPacket_skip(DnsPacket* packet, int count) {
+    const uint8_t* p = packet->cursor + count;
+
+    if (p > packet->end) p = packet->end;
+
+    packet->cursor = p;
+}
+
+static int _dnsPacket_readInt16(DnsPacket* packet) {
+    const uint8_t* p = packet->cursor;
+
+    if (p + 2 > packet->end) return -1;
+
+    packet->cursor = p + 2;
+    return (p[0] << 8) | p[1];
+}
+
+/** QUERY CHECKING **/
+
+/* check bytes in a dns packet. returns 1 on success, 0 on failure.
+ * the cursor is only advanced in the case of success
+ */
+static int _dnsPacket_checkBytes(DnsPacket* packet, int numBytes, const void* bytes) {
+    const uint8_t* p = packet->cursor;
+
+    if (p + numBytes > packet->end) return 0;
+
+    if (memcmp(p, bytes, numBytes) != 0) return 0;
+
+    packet->cursor = p + numBytes;
+    return 1;
+}
+
+/* parse and skip a given QNAME stored in a query packet,
+ * from the current cursor position. returns 1 on success,
+ * or 0 for malformed data.
+ */
+static int _dnsPacket_checkQName(DnsPacket* packet) {
+    const uint8_t* p = packet->cursor;
+    const uint8_t* end = packet->end;
+
+    for (;;) {
+        int c;
+
+        if (p >= end) break;
+
+        c = *p++;
+
+        if (c == 0) {
+            packet->cursor = p;
+            return 1;
+        }
+
+        /* we don't expect label compression in QNAMEs */
+        if (c >= 64) break;
+
+        p += c;
+        /* we rely on the bound check at the start
+         * of the loop here */
+    }
+    /* malformed data */
+    LOG(INFO) << __func__ << ": malformed QNAME";
+    return 0;
+}
+
+/* parse and skip a given QR stored in a packet.
+ * returns 1 on success, and 0 on failure
+ */
+static int _dnsPacket_checkQR(DnsPacket* packet) {
+    if (!_dnsPacket_checkQName(packet)) return 0;
+
+    /* TYPE must be one of the things we support */
+    if (!_dnsPacket_checkBytes(packet, 2, DNS_TYPE_A) &&
+        !_dnsPacket_checkBytes(packet, 2, DNS_TYPE_PTR) &&
+        !_dnsPacket_checkBytes(packet, 2, DNS_TYPE_MX) &&
+        !_dnsPacket_checkBytes(packet, 2, DNS_TYPE_AAAA) &&
+        !_dnsPacket_checkBytes(packet, 2, DNS_TYPE_ALL)) {
+        LOG(INFO) << __func__ << ": unsupported TYPE";
+        return 0;
+    }
+    /* CLASS must be IN */
+    if (!_dnsPacket_checkBytes(packet, 2, DNS_CLASS_IN)) {
+        LOG(INFO) << __func__ << ": unsupported CLASS";
+        return 0;
+    }
+
+    return 1;
+}
+
+/* check the header of a DNS Query packet, return 1 if it is one
+ * type of query we can cache, or 0 otherwise
+ */
+static int _dnsPacket_checkQuery(DnsPacket* packet) {
+    const uint8_t* p = packet->base;
+    int qdCount, anCount, dnCount, arCount;
+
+    if (p + DNS_HEADER_SIZE > packet->end) {
+        LOG(INFO) << __func__ << ": query packet too small";
+        return 0;
+    }
+
+    /* QR must be set to 0, opcode must be 0 and AA must be 0 */
+    /* RA, Z, and RCODE must be 0 */
+    if ((p[2] & 0xFC) != 0 || (p[3] & 0xCF) != 0) {
+        LOG(INFO) << __func__ << ": query packet flags unsupported";
+        return 0;
+    }
+
+    /* Note that we ignore the TC, RD, CD, and AD bits here for the
+     * following reasons:
+     *
+     * - there is no point for a query packet sent to a server
+     *   to have the TC bit set, but the implementation might
+     *   set the bit in the query buffer for its own needs
+     *   between a _resolv_cache_lookup and a
+     *   _resolv_cache_add. We should not freak out if this
+     *   is the case.
+     *
+     * - we consider that the result from a query might depend on
+     *   the RD, AD, and CD bits, so these bits
+     *   should be used to differentiate cached result.
+     *
+     *   this implies that these bits are checked when hashing or
+     *   comparing query packets, but not TC
+     */
+
+    /* ANCOUNT, DNCOUNT and ARCOUNT must be 0 */
+    qdCount = (p[4] << 8) | p[5];
+    anCount = (p[6] << 8) | p[7];
+    dnCount = (p[8] << 8) | p[9];
+    arCount = (p[10] << 8) | p[11];
+
+    if (anCount != 0 || dnCount != 0 || arCount > 1) {
+        LOG(INFO) << __func__ << ": query packet contains non-query records";
+        return 0;
+    }
+
+    if (qdCount == 0) {
+        LOG(INFO) << __func__ << ": query packet doesn't contain query record";
+        return 0;
+    }
+
+    /* Check QDCOUNT QRs */
+    packet->cursor = p + DNS_HEADER_SIZE;
+
+    for (; qdCount > 0; qdCount--)
+        if (!_dnsPacket_checkQR(packet)) return 0;
+
+    return 1;
+}
+
+/** QUERY DEBUGGING **/
+static char* dnsPacket_bprintQName(DnsPacket* packet, char* bp, char* bend) {
+    const uint8_t* p = packet->cursor;
+    const uint8_t* end = packet->end;
+    int first = 1;
+
+    for (;;) {
+        int c;
+
+        if (p >= end) break;
+
+        c = *p++;
+
+        if (c == 0) {
+            packet->cursor = p;
+            return bp;
+        }
+
+        /* we don't expect label compression in QNAMEs */
+        if (c >= 64) break;
+
+        if (first)
+            first = 0;
+        else
+            bp = bprint_c(bp, bend, '.');
+
+        bp = bprint_b(bp, bend, (const char*) p, c);
+
+        p += c;
+        /* we rely on the bound check at the start
+         * of the loop here */
+    }
+    /* malformed data */
+    bp = bprint_s(bp, bend, "<MALFORMED>");
+    return bp;
+}
+
+static char* dnsPacket_bprintQR(DnsPacket* packet, char* p, char* end) {
+#define QQ(x) \
+    { DNS_TYPE_##x, #x }
+    static const struct {
+        const char* typeBytes;
+        const char* typeString;
+    } qTypes[] = {QQ(A), QQ(PTR), QQ(MX), QQ(AAAA), QQ(ALL), {NULL, NULL}};
+    int nn;
+    const char* typeString = NULL;
+
+    /* dump QNAME */
+    p = dnsPacket_bprintQName(packet, p, end);
+
+    /* dump TYPE */
+    p = bprint_s(p, end, " (");
+
+    for (nn = 0; qTypes[nn].typeBytes != NULL; nn++) {
+        if (_dnsPacket_checkBytes(packet, 2, qTypes[nn].typeBytes)) {
+            typeString = qTypes[nn].typeString;
+            break;
+        }
+    }
+
+    if (typeString != NULL)
+        p = bprint_s(p, end, typeString);
+    else {
+        int typeCode = _dnsPacket_readInt16(packet);
+        p = bprint(p, end, "UNKNOWN-%d", typeCode);
+    }
+
+    p = bprint_c(p, end, ')');
+
+    /* skip CLASS */
+    _dnsPacket_skip(packet, 2);
+    return p;
+}
+
+/* this function assumes the packet has already been checked */
+static char* dnsPacket_bprintQuery(DnsPacket* packet, char* p, char* end) {
+    int qdCount;
+
+    if (packet->base[2] & 0x1) {
+        p = bprint_s(p, end, "RECURSIVE ");
+    }
+
+    _dnsPacket_skip(packet, 4);
+    qdCount = _dnsPacket_readInt16(packet);
+    _dnsPacket_skip(packet, 6);
+
+    for (; qdCount > 0; qdCount--) {
+        p = dnsPacket_bprintQR(packet, p, end);
+    }
+    return p;
+}
+
+/** QUERY HASHING SUPPORT
+ **
+ ** THE FOLLOWING CODE ASSUMES THAT THE INPUT PACKET HAS ALREADY
+ ** BEEN SUCCESFULLY CHECKED.
+ **/
+
+/* use 32-bit FNV hash function */
+#define FNV_MULT 16777619U
+#define FNV_BASIS 2166136261U
+
+static unsigned _dnsPacket_hashBytes(DnsPacket* packet, int numBytes, unsigned hash) {
+    const uint8_t* p = packet->cursor;
+    const uint8_t* end = packet->end;
+
+    while (numBytes > 0 && p < end) {
+        hash = hash * FNV_MULT ^ *p++;
+    }
+    packet->cursor = p;
+    return hash;
+}
+
+static unsigned _dnsPacket_hashQName(DnsPacket* packet, unsigned hash) {
+    const uint8_t* p = packet->cursor;
+    const uint8_t* end = packet->end;
+
+    for (;;) {
+        int c;
+
+        if (p >= end) { /* should not happen */
+            LOG(INFO) << __func__ << ": INTERNAL_ERROR: read-overflow";
+            break;
+        }
+
+        c = *p++;
+
+        if (c == 0) break;
+
+        if (c >= 64) {
+            LOG(INFO) << __func__ << ": INTERNAL_ERROR: malformed domain";
+            break;
+        }
+        if (p + c >= end) {
+            LOG(INFO) << __func__ << ": INTERNAL_ERROR: simple label read-overflow";
+            break;
+        }
+        while (c > 0) {
+            hash = hash * FNV_MULT ^ *p++;
+            c -= 1;
+        }
+    }
+    packet->cursor = p;
+    return hash;
+}
+
+static unsigned _dnsPacket_hashQR(DnsPacket* packet, unsigned hash) {
+    hash = _dnsPacket_hashQName(packet, hash);
+    hash = _dnsPacket_hashBytes(packet, 4, hash); /* TYPE and CLASS */
+    return hash;
+}
+
+static unsigned _dnsPacket_hashRR(DnsPacket* packet, unsigned hash) {
+    int rdlength;
+    hash = _dnsPacket_hashQR(packet, hash);
+    hash = _dnsPacket_hashBytes(packet, 4, hash); /* TTL */
+    rdlength = _dnsPacket_readInt16(packet);
+    hash = _dnsPacket_hashBytes(packet, rdlength, hash); /* RDATA */
+    return hash;
+}
+
+static unsigned _dnsPacket_hashQuery(DnsPacket* packet) {
+    unsigned hash = FNV_BASIS;
+    int count, arcount;
+    _dnsPacket_rewind(packet);
+
+    /* ignore the ID */
+    _dnsPacket_skip(packet, 2);
+
+    /* we ignore the TC bit for reasons explained in
+     * _dnsPacket_checkQuery().
+     *
+     * however we hash the RD bit to differentiate
+     * between answers for recursive and non-recursive
+     * queries.
+     */
+    hash = hash * FNV_MULT ^ (packet->base[2] & 1);
+
+    /* mark the first header byte as processed */
+    _dnsPacket_skip(packet, 1);
+
+    /* process the second header byte */
+    hash = _dnsPacket_hashBytes(packet, 1, hash);
+
+    /* read QDCOUNT */
+    count = _dnsPacket_readInt16(packet);
+
+    /* assume: ANcount and NScount are 0 */
+    _dnsPacket_skip(packet, 4);
+
+    /* read ARCOUNT */
+    arcount = _dnsPacket_readInt16(packet);
+
+    /* hash QDCOUNT QRs */
+    for (; count > 0; count--) hash = _dnsPacket_hashQR(packet, hash);
+
+    /* hash ARCOUNT RRs */
+    for (; arcount > 0; arcount--) hash = _dnsPacket_hashRR(packet, hash);
+
+    return hash;
+}
+
+/** QUERY COMPARISON
+ **
+ ** THE FOLLOWING CODE ASSUMES THAT THE INPUT PACKETS HAVE ALREADY
+ ** BEEN SUCCESSFULLY CHECKED.
+ **/
+
+static int _dnsPacket_isEqualDomainName(DnsPacket* pack1, DnsPacket* pack2) {
+    const uint8_t* p1 = pack1->cursor;
+    const uint8_t* end1 = pack1->end;
+    const uint8_t* p2 = pack2->cursor;
+    const uint8_t* end2 = pack2->end;
+
+    for (;;) {
+        int c1, c2;
+
+        if (p1 >= end1 || p2 >= end2) {
+            LOG(INFO) << __func__ << ": INTERNAL_ERROR: read-overflow";
+            break;
+        }
+        c1 = *p1++;
+        c2 = *p2++;
+        if (c1 != c2) break;
+
+        if (c1 == 0) {
+            pack1->cursor = p1;
+            pack2->cursor = p2;
+            return 1;
+        }
+        if (c1 >= 64) {
+            LOG(INFO) << __func__ << ": INTERNAL_ERROR: malformed domain";
+            break;
+        }
+        if ((p1 + c1 > end1) || (p2 + c1 > end2)) {
+            LOG(INFO) << __func__ << ": INTERNAL_ERROR: simple label read-overflow";
+            break;
+        }
+        if (memcmp(p1, p2, c1) != 0) break;
+        p1 += c1;
+        p2 += c1;
+        /* we rely on the bound checks at the start of the loop */
+    }
+    /* not the same, or one is malformed */
+    LOG(INFO) << __func__ << ": different DN";
+    return 0;
+}
+
+static int _dnsPacket_isEqualBytes(DnsPacket* pack1, DnsPacket* pack2, int numBytes) {
+    const uint8_t* p1 = pack1->cursor;
+    const uint8_t* p2 = pack2->cursor;
+
+    if (p1 + numBytes > pack1->end || p2 + numBytes > pack2->end) return 0;
+
+    if (memcmp(p1, p2, numBytes) != 0) return 0;
+
+    pack1->cursor += numBytes;
+    pack2->cursor += numBytes;
+    return 1;
+}
+
+static int _dnsPacket_isEqualQR(DnsPacket* pack1, DnsPacket* pack2) {
+    /* compare domain name encoding + TYPE + CLASS */
+    if (!_dnsPacket_isEqualDomainName(pack1, pack2) ||
+        !_dnsPacket_isEqualBytes(pack1, pack2, 2 + 2))
+        return 0;
+
+    return 1;
+}
+
+static int _dnsPacket_isEqualRR(DnsPacket* pack1, DnsPacket* pack2) {
+    int rdlength1, rdlength2;
+    /* compare query + TTL */
+    if (!_dnsPacket_isEqualQR(pack1, pack2) || !_dnsPacket_isEqualBytes(pack1, pack2, 4)) return 0;
+
+    /* compare RDATA */
+    rdlength1 = _dnsPacket_readInt16(pack1);
+    rdlength2 = _dnsPacket_readInt16(pack2);
+    if (rdlength1 != rdlength2 || !_dnsPacket_isEqualBytes(pack1, pack2, rdlength1)) return 0;
+
+    return 1;
+}
+
+static int _dnsPacket_isEqualQuery(DnsPacket* pack1, DnsPacket* pack2) {
+    int count1, count2, arcount1, arcount2;
+
+    /* compare the headers, ignore most fields */
+    _dnsPacket_rewind(pack1);
+    _dnsPacket_rewind(pack2);
+
+    /* compare RD, ignore TC, see comment in _dnsPacket_checkQuery */
+    if ((pack1->base[2] & 1) != (pack2->base[2] & 1)) {
+        LOG(INFO) << __func__ << ": different RD";
+        return 0;
+    }
+
+    if (pack1->base[3] != pack2->base[3]) {
+        LOG(INFO) << __func__ << ": different CD or AD";
+        return 0;
+    }
+
+    /* mark ID and header bytes as compared */
+    _dnsPacket_skip(pack1, 4);
+    _dnsPacket_skip(pack2, 4);
+
+    /* compare QDCOUNT */
+    count1 = _dnsPacket_readInt16(pack1);
+    count2 = _dnsPacket_readInt16(pack2);
+    if (count1 != count2 || count1 < 0) {
+        LOG(INFO) << __func__ << ": different QDCOUNT";
+        return 0;
+    }
+
+    /* assume: ANcount and NScount are 0 */
+    _dnsPacket_skip(pack1, 4);
+    _dnsPacket_skip(pack2, 4);
+
+    /* compare ARCOUNT */
+    arcount1 = _dnsPacket_readInt16(pack1);
+    arcount2 = _dnsPacket_readInt16(pack2);
+    if (arcount1 != arcount2 || arcount1 < 0) {
+        LOG(INFO) << __func__ << ": different ARCOUNT";
+        return 0;
+    }
+
+    /* compare the QDCOUNT QRs */
+    for (; count1 > 0; count1--) {
+        if (!_dnsPacket_isEqualQR(pack1, pack2)) {
+            LOG(INFO) << __func__ << ": different QR";
+            return 0;
+        }
+    }
+
+    /* compare the ARCOUNT RRs */
+    for (; arcount1 > 0; arcount1--) {
+        if (!_dnsPacket_isEqualRR(pack1, pack2)) {
+            LOG(INFO) << __func__ << ": different additional RR";
+            return 0;
+        }
+    }
+    return 1;
+}
+
+/* cache entry. for simplicity, 'hash' and 'hlink' are inlined in this
+ * structure though they are conceptually part of the hash table.
+ *
+ * similarly, mru_next and mru_prev are part of the global MRU list
+ */
+typedef struct Entry {
+    unsigned int hash;   /* hash value */
+    struct Entry* hlink; /* next in collision chain */
+    struct Entry* mru_prev;
+    struct Entry* mru_next;
+
+    const uint8_t* query;
+    int querylen;
+    const uint8_t* answer;
+    int answerlen;
+    time_t expires; /* time_t when the entry isn't valid any more */
+    int id;         /* for debugging purpose */
+} Entry;
+
+/*
+ * Find the TTL for a negative DNS result.  This is defined as the minimum
+ * of the SOA records TTL and the MINIMUM-TTL field (RFC-2308).
+ *
+ * Return 0 if not found.
+ */
+static u_long answer_getNegativeTTL(ns_msg handle) {
+    int n, nscount;
+    u_long result = 0;
+    ns_rr rr;
+
+    nscount = ns_msg_count(handle, ns_s_ns);
+    for (n = 0; n < nscount; n++) {
+        if ((ns_parserr(&handle, ns_s_ns, n, &rr) == 0) && (ns_rr_type(rr) == ns_t_soa)) {
+            const u_char* rdata = ns_rr_rdata(rr);          // find the data
+            const u_char* edata = rdata + ns_rr_rdlen(rr);  // add the len to find the end
+            int len;
+            u_long ttl, rec_result = ns_rr_ttl(rr);
+
+            // find the MINIMUM-TTL field from the blob of binary data for this record
+            // skip the server name
+            len = dn_skipname(rdata, edata);
+            if (len == -1) continue;  // error skipping
+            rdata += len;
+
+            // skip the admin name
+            len = dn_skipname(rdata, edata);
+            if (len == -1) continue;  // error skipping
+            rdata += len;
+
+            if (edata - rdata != 5 * NS_INT32SZ) continue;
+            // skip: serial number + refresh interval + retry interval + expiry
+            rdata += NS_INT32SZ * 4;
+            // finally read the MINIMUM TTL
+            ttl = ntohl(*reinterpret_cast<const uint32_t*>(rdata));
+            if (ttl < rec_result) {
+                rec_result = ttl;
+            }
+            // Now that the record is read successfully, apply the new min TTL
+            if (n == 0 || rec_result < result) {
+                result = rec_result;
+            }
+        }
+    }
+    return result;
+}
+
+/*
+ * Parse the answer records and find the appropriate
+ * smallest TTL among the records.  This might be from
+ * the answer records if found or from the SOA record
+ * if it's a negative result.
+ *
+ * The returned TTL is the number of seconds to
+ * keep the answer in the cache.
+ *
+ * In case of parse error zero (0) is returned which
+ * indicates that the answer shall not be cached.
+ */
+static u_long answer_getTTL(const void* answer, int answerlen) {
+    ns_msg handle;
+    int ancount, n;
+    u_long result, ttl;
+    ns_rr rr;
+
+    result = 0;
+    if (ns_initparse((const uint8_t*) answer, answerlen, &handle) >= 0) {
+        // get number of answer records
+        ancount = ns_msg_count(handle, ns_s_an);
+
+        if (ancount == 0) {
+            // a response with no answers?  Cache this negative result.
+            result = answer_getNegativeTTL(handle);
+        } else {
+            for (n = 0; n < ancount; n++) {
+                if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
+                    ttl = ns_rr_ttl(rr);
+                    if (n == 0 || ttl < result) {
+                        result = ttl;
+                    }
+                } else {
+                    PLOG(INFO) << __func__ << ": ns_parserr failed ancount no = " << n;
+                }
+            }
+        }
+    } else {
+        PLOG(INFO) << __func__ << ": ns_initparse failed";
+    }
+
+    LOG(INFO) << __func__ << ": TTL = " << result;
+    return result;
+}
+
+static void entry_free(Entry* e) {
+    /* everything is allocated in a single memory block */
+    if (e) {
+        free(e);
+    }
+}
+
+static void entry_mru_remove(Entry* e) {
+    e->mru_prev->mru_next = e->mru_next;
+    e->mru_next->mru_prev = e->mru_prev;
+}
+
+static void entry_mru_add(Entry* e, Entry* list) {
+    Entry* first = list->mru_next;
+
+    e->mru_next = first;
+    e->mru_prev = list;
+
+    list->mru_next = e;
+    first->mru_prev = e;
+}
+
+/* compute the hash of a given entry, this is a hash of most
+ * data in the query (key) */
+static unsigned entry_hash(const Entry* e) {
+    DnsPacket pack[1];
+
+    _dnsPacket_init(pack, e->query, e->querylen);
+    return _dnsPacket_hashQuery(pack);
+}
+
+/* initialize an Entry as a search key, this also checks the input query packet
+ * returns 1 on success, or 0 in case of unsupported/malformed data */
+static int entry_init_key(Entry* e, const void* query, int querylen) {
+    DnsPacket pack[1];
+
+    memset(e, 0, sizeof(*e));
+
+    e->query = (const uint8_t*) query;
+    e->querylen = querylen;
+    e->hash = entry_hash(e);
+
+    _dnsPacket_init(pack, e->query, e->querylen);
+
+    return _dnsPacket_checkQuery(pack);
+}
+
+/* allocate a new entry as a cache node */
+static Entry* entry_alloc(const Entry* init, const void* answer, int answerlen) {
+    Entry* e;
+    int size;
+
+    size = sizeof(*e) + init->querylen + answerlen;
+    e = (Entry*) calloc(size, 1);
+    if (e == NULL) return e;
+
+    e->hash = init->hash;
+    e->query = (const uint8_t*) (e + 1);
+    e->querylen = init->querylen;
+
+    memcpy((char*) e->query, init->query, e->querylen);
+
+    e->answer = e->query + e->querylen;
+    e->answerlen = answerlen;
+
+    memcpy((char*) e->answer, answer, e->answerlen);
+
+    return e;
+}
+
+static int entry_equals(const Entry* e1, const Entry* e2) {
+    DnsPacket pack1[1], pack2[1];
+
+    if (e1->querylen != e2->querylen) {
+        return 0;
+    }
+    _dnsPacket_init(pack1, e1->query, e1->querylen);
+    _dnsPacket_init(pack2, e2->query, e2->querylen);
+
+    return _dnsPacket_isEqualQuery(pack1, pack2);
+}
+
+/* We use a simple hash table with external collision lists
+ * for simplicity, the hash-table fields 'hash' and 'hlink' are
+ * inlined in the Entry structure.
+ */
+
+/* Maximum time for a thread to wait for an pending request */
+constexpr int PENDING_REQUEST_TIMEOUT = 20;
+
+typedef struct resolv_cache {
+    int max_entries;
+    int num_entries;
+    Entry mru_list;
+    int last_id;
+    Entry* entries;
+    struct pending_req_info {
+        unsigned int hash;
+        struct pending_req_info* next;
+    } pending_requests;
+} Cache;
+
+struct resolv_cache_info {
+    unsigned netid;
+    Cache* cache;
+    struct resolv_cache_info* next;
+    int nscount;
+    char* nameservers[MAXNS];
+    struct addrinfo* nsaddrinfo[MAXNS];
+    int revision_id;  // # times the nameservers have been replaced
+    res_params params;
+    struct res_stats nsstats[MAXNS];
+    char defdname[MAXDNSRCHPATH];
+    int dnsrch_offset[MAXDNSRCH + 1];  // offsets into defdname
+    int wait_for_pending_req_timeout_count;
+    // Map format: ReturnCode:rate_denom
+    std::unordered_map<int, uint32_t> dns_event_subsampling_map;
+};
+
+// A helper class for the Clang Thread Safety Analysis to deal with
+// std::unique_lock.
+class SCOPED_CAPABILITY ScopedAssumeLocked {
+  public:
+    ScopedAssumeLocked(std::mutex& mutex) ACQUIRE(mutex) {}
+    ~ScopedAssumeLocked() RELEASE() {}
+};
+
+// lock protecting everything in the resolve_cache_info structs (next ptr, etc)
+static std::mutex cache_mutex;
+static std::condition_variable cv;
+
+/* gets cache associated with a network, or NULL if none exists */
+static resolv_cache* find_named_cache_locked(unsigned netid) REQUIRES(cache_mutex);
+static int resolv_create_cache_for_net_locked(unsigned netid) REQUIRES(cache_mutex);
+
+static void cache_flush_pending_requests_locked(struct resolv_cache* cache) {
+    resolv_cache::pending_req_info *ri, *tmp;
+    if (!cache) return;
+
+    ri = cache->pending_requests.next;
+
+    while (ri) {
+        tmp = ri;
+        ri = ri->next;
+        free(tmp);
+    }
+
+    cache->pending_requests.next = NULL;
+    cv.notify_all();
+}
+
+// Return true - if there is a pending request in |cache| matching |key|.
+// Return false - if no pending request is found matching the key. Optionally
+//                link a new one if parameter append_if_not_found is true.
+static bool cache_has_pending_request_locked(resolv_cache* cache, const Entry* key,
+                                             bool append_if_not_found) {
+    if (!cache || !key) return false;
+
+    resolv_cache::pending_req_info* ri = cache->pending_requests.next;
+    resolv_cache::pending_req_info* prev = &cache->pending_requests;
+    while (ri) {
+        if (ri->hash == key->hash) {
+            return true;
+        }
+        prev = ri;
+        ri = ri->next;
+    }
+
+    if (append_if_not_found) {
+        ri = (resolv_cache::pending_req_info*)calloc(1, sizeof(resolv_cache::pending_req_info));
+        if (ri) {
+            ri->hash = key->hash;
+            prev->next = ri;
+        }
+    }
+    return false;
+}
+
+// Notify all threads that the cache entry |key| has become available
+static void _cache_notify_waiting_tid_locked(struct resolv_cache* cache, const Entry* key) {
+    if (!cache || !key) return;
+
+    resolv_cache::pending_req_info* ri = cache->pending_requests.next;
+    resolv_cache::pending_req_info* prev = &cache->pending_requests;
+    while (ri) {
+        if (ri->hash == key->hash) {
+            // remove item from list and destroy
+            prev->next = ri->next;
+            free(ri);
+            cv.notify_all();
+            return;
+        }
+        prev = ri;
+        ri = ri->next;
+    }
+}
+
+void _resolv_cache_query_failed(unsigned netid, const void* query, int querylen, uint32_t flags) {
+    // We should not notify with these flags.
+    if (flags & (ANDROID_RESOLV_NO_CACHE_STORE | ANDROID_RESOLV_NO_CACHE_LOOKUP)) {
+        return;
+    }
+    Entry key[1];
+    Cache* cache;
+
+    if (!entry_init_key(key, query, querylen)) return;
+
+    std::lock_guard guard(cache_mutex);
+
+    cache = find_named_cache_locked(netid);
+
+    if (cache) {
+        _cache_notify_waiting_tid_locked(cache, key);
+    }
+}
+
+static void cache_flush_locked(Cache* cache) {
+    int nn;
+
+    for (nn = 0; nn < cache->max_entries; nn++) {
+        Entry** pnode = (Entry**) &cache->entries[nn];
+
+        while (*pnode != NULL) {
+            Entry* node = *pnode;
+            *pnode = node->hlink;
+            entry_free(node);
+        }
+    }
+
+    // flush pending request
+    cache_flush_pending_requests_locked(cache);
+
+    cache->mru_list.mru_next = cache->mru_list.mru_prev = &cache->mru_list;
+    cache->num_entries = 0;
+    cache->last_id = 0;
+
+    LOG(INFO) << __func__ << ": *** DNS CACHE FLUSHED ***";
+}
+
+static resolv_cache* resolv_cache_create() {
+    struct resolv_cache* cache;
+
+    cache = (struct resolv_cache*) calloc(sizeof(*cache), 1);
+    if (cache) {
+        cache->max_entries = CONFIG_MAX_ENTRIES;
+        cache->entries = (Entry*) calloc(sizeof(*cache->entries), cache->max_entries);
+        if (cache->entries) {
+            cache->mru_list.mru_prev = cache->mru_list.mru_next = &cache->mru_list;
+            LOG(INFO) << __func__ << ": cache created";
+        } else {
+            free(cache);
+            cache = NULL;
+        }
+    }
+    return cache;
+}
+
+static void dump_query(const uint8_t* query, int querylen) {
+    if (!WOULD_LOG(VERBOSE)) return;
+
+    char temp[256], *p = temp, *end = p + sizeof(temp);
+    DnsPacket pack[1];
+
+    _dnsPacket_init(pack, query, querylen);
+    p = dnsPacket_bprintQuery(pack, p, end);
+    LOG(VERBOSE) << __func__ << ": " << temp;
+}
+
+static void cache_dump_mru(Cache* cache) {
+    char temp[512], *p = temp, *end = p + sizeof(temp);
+    Entry* e;
+
+    p = bprint(temp, end, "MRU LIST (%2d): ", cache->num_entries);
+    for (e = cache->mru_list.mru_next; e != &cache->mru_list; e = e->mru_next)
+        p = bprint(p, end, " %d", e->id);
+
+    LOG(INFO) << __func__ << ": " << temp;
+}
+
+/* This function tries to find a key within the hash table
+ * In case of success, it will return a *pointer* to the hashed key.
+ * In case of failure, it will return a *pointer* to NULL
+ *
+ * So, the caller must check '*result' to check for success/failure.
+ *
+ * The main idea is that the result can later be used directly in
+ * calls to _resolv_cache_add or _resolv_cache_remove as the 'lookup'
+ * parameter. This makes the code simpler and avoids re-searching
+ * for the key position in the htable.
+ *
+ * The result of a lookup_p is only valid until you alter the hash
+ * table.
+ */
+static Entry** _cache_lookup_p(Cache* cache, Entry* key) {
+    int index = key->hash % cache->max_entries;
+    Entry** pnode = (Entry**) &cache->entries[index];
+
+    while (*pnode != NULL) {
+        Entry* node = *pnode;
+
+        if (node == NULL) break;
+
+        if (node->hash == key->hash && entry_equals(node, key)) break;
+
+        pnode = &node->hlink;
+    }
+    return pnode;
+}
+
+/* Add a new entry to the hash table. 'lookup' must be the
+ * result of an immediate previous failed _lookup_p() call
+ * (i.e. with *lookup == NULL), and 'e' is the pointer to the
+ * newly created entry
+ */
+static void _cache_add_p(Cache* cache, Entry** lookup, Entry* e) {
+    *lookup = e;
+    e->id = ++cache->last_id;
+    entry_mru_add(e, &cache->mru_list);
+    cache->num_entries += 1;
+
+    LOG(INFO) << __func__ << ": entry " << e->id << " added (count=" << cache->num_entries << ")";
+}
+
+/* Remove an existing entry from the hash table,
+ * 'lookup' must be the result of an immediate previous
+ * and succesful _lookup_p() call.
+ */
+static void _cache_remove_p(Cache* cache, Entry** lookup) {
+    Entry* e = *lookup;
+
+    LOG(INFO) << __func__ << ": entry " << e->id << " removed (count=" << cache->num_entries - 1
+              << ")";
+
+    entry_mru_remove(e);
+    *lookup = e->hlink;
+    entry_free(e);
+    cache->num_entries -= 1;
+}
+
+/* Remove the oldest entry from the hash table.
+ */
+static void _cache_remove_oldest(Cache* cache) {
+    Entry* oldest = cache->mru_list.mru_prev;
+    Entry** lookup = _cache_lookup_p(cache, oldest);
+
+    if (*lookup == NULL) { /* should not happen */
+        LOG(INFO) << __func__ << ": OLDEST NOT IN HTABLE ?";
+        return;
+    }
+    LOG(INFO) << __func__ << ": Cache full - removing oldest";
+    dump_query(oldest->query, oldest->querylen);
+    _cache_remove_p(cache, lookup);
+}
+
+/* Remove all expired entries from the hash table.
+ */
+static void _cache_remove_expired(Cache* cache) {
+    Entry* e;
+    time_t now = _time_now();
+
+    for (e = cache->mru_list.mru_next; e != &cache->mru_list;) {
+        // Entry is old, remove
+        if (now >= e->expires) {
+            Entry** lookup = _cache_lookup_p(cache, e);
+            if (*lookup == NULL) { /* should not happen */
+                LOG(INFO) << __func__ << ": ENTRY NOT IN HTABLE ?";
+                return;
+            }
+            e = e->mru_next;
+            _cache_remove_p(cache, lookup);
+        } else {
+            e = e->mru_next;
+        }
+    }
+}
+
+// gets a resolv_cache_info associated with a network, or NULL if not found
+static resolv_cache_info* find_cache_info_locked(unsigned netid) REQUIRES(cache_mutex);
+
+ResolvCacheStatus _resolv_cache_lookup(unsigned netid, const void* query, int querylen,
+                                       void* answer, int answersize, int* answerlen,
+                                       uint32_t flags) {
+    // Skip cache lookup, return RESOLV_CACHE_NOTFOUND directly so that it is
+    // possible to cache the answer of this query.
+    // If ANDROID_RESOLV_NO_CACHE_STORE is set, return RESOLV_CACHE_SKIP to skip possible cache
+    // storing.
+    if (flags & ANDROID_RESOLV_NO_CACHE_LOOKUP) {
+        return flags & ANDROID_RESOLV_NO_CACHE_STORE ? RESOLV_CACHE_SKIP : RESOLV_CACHE_NOTFOUND;
+    }
+    Entry key;
+    Entry** lookup;
+    Entry* e;
+    time_t now;
+    Cache* cache;
+
+    LOG(INFO) << __func__ << ": lookup";
+    dump_query((u_char*) query, querylen);
+
+    /* we don't cache malformed queries */
+    if (!entry_init_key(&key, query, querylen)) {
+        LOG(INFO) << __func__ << ": unsupported query";
+        return RESOLV_CACHE_UNSUPPORTED;
+    }
+    /* lookup cache */
+    std::unique_lock lock(cache_mutex);
+    ScopedAssumeLocked assume_lock(cache_mutex);
+    cache = find_named_cache_locked(netid);
+    if (cache == NULL) {
+        return RESOLV_CACHE_UNSUPPORTED;
+    }
+
+    /* see the description of _lookup_p to understand this.
+     * the function always return a non-NULL pointer.
+     */
+    lookup = _cache_lookup_p(cache, &key);
+    e = *lookup;
+
+    if (e == NULL) {
+        LOG(INFO) << __func__ << ": NOT IN CACHE";
+        // If it is no-cache-store mode, we won't wait for possible query.
+        if (flags & ANDROID_RESOLV_NO_CACHE_STORE) {
+            return RESOLV_CACHE_SKIP;
+        }
+
+        if (!cache_has_pending_request_locked(cache, &key, true)) {
+            return RESOLV_CACHE_NOTFOUND;
+
+        } else {
+            LOG(INFO) << __func__ << ": Waiting for previous request";
+            // wait until (1) timeout OR
+            //            (2) cv is notified AND no pending request matching the |key|
+            // (cv notifier should delete pending request before sending notification.)
+            bool ret = cv.wait_for(lock, std::chrono::seconds(PENDING_REQUEST_TIMEOUT),
+                                   [netid, &cache, &key]() REQUIRES(cache_mutex) {
+                                       // Must update cache as it could have been deleted
+                                       cache = find_named_cache_locked(netid);
+                                       return !cache_has_pending_request_locked(cache, &key, false);
+                                   });
+            if (!cache) {
+                return RESOLV_CACHE_NOTFOUND;
+            }
+            if (ret == false) {
+                resolv_cache_info* info = find_cache_info_locked(netid);
+                if (info != NULL) {
+                    info->wait_for_pending_req_timeout_count++;
+                }
+            }
+            lookup = _cache_lookup_p(cache, &key);
+            e = *lookup;
+            if (e == NULL) {
+                return RESOLV_CACHE_NOTFOUND;
+            }
+        }
+    }
+
+    now = _time_now();
+
+    /* remove stale entries here */
+    if (now >= e->expires) {
+        LOG(INFO) << __func__ << ": NOT IN CACHE (STALE ENTRY " << *lookup << "DISCARDED)";
+        dump_query(e->query, e->querylen);
+        _cache_remove_p(cache, lookup);
+        return RESOLV_CACHE_NOTFOUND;
+    }
+
+    *answerlen = e->answerlen;
+    if (e->answerlen > answersize) {
+        /* NOTE: we return UNSUPPORTED if the answer buffer is too short */
+        LOG(INFO) << __func__ << ": ANSWER TOO LONG";
+        return RESOLV_CACHE_UNSUPPORTED;
+    }
+
+    memcpy(answer, e->answer, e->answerlen);
+
+    /* bump up this entry to the top of the MRU list */
+    if (e != cache->mru_list.mru_next) {
+        entry_mru_remove(e);
+        entry_mru_add(e, &cache->mru_list);
+    }
+
+    LOG(INFO) << __func__ << ": FOUND IN CACHE entry=" << e;
+    return RESOLV_CACHE_FOUND;
+}
+
+void _resolv_cache_add(unsigned netid, const void* query, int querylen, const void* answer,
+                       int answerlen) {
+    Entry key[1];
+    Entry* e;
+    Entry** lookup;
+    u_long ttl;
+    Cache* cache = NULL;
+
+    /* don't assume that the query has already been cached
+     */
+    if (!entry_init_key(key, query, querylen)) {
+        LOG(INFO) << __func__ << ": passed invalid query?";
+        return;
+    }
+
+    std::lock_guard guard(cache_mutex);
+
+    cache = find_named_cache_locked(netid);
+    if (cache == NULL) {
+        return;
+    }
+
+    LOG(INFO) << __func__ << ": query:";
+    dump_query((u_char*)query, querylen);
+    res_pquery((u_char*)answer, answerlen);
+    if (kDumpData) {
+        LOG(INFO) << __func__ << ": answer:";
+        dump_bytes((u_char*)answer, answerlen);
+    }
+
+    lookup = _cache_lookup_p(cache, key);
+    e = *lookup;
+
+    // Should only happen on ANDROID_RESOLV_NO_CACHE_LOOKUP
+    if (e != NULL) {
+        LOG(INFO) << __func__ << ": ALREADY IN CACHE (" << e << ") ? IGNORING ADD";
+        _cache_notify_waiting_tid_locked(cache, key);
+        return;
+    }
+
+    if (cache->num_entries >= cache->max_entries) {
+        _cache_remove_expired(cache);
+        if (cache->num_entries >= cache->max_entries) {
+            _cache_remove_oldest(cache);
+        }
+        // TODO: It looks useless, remove below code after having test to prove it.
+        lookup = _cache_lookup_p(cache, key);
+        e = *lookup;
+        if (e != NULL) {
+            LOG(INFO) << __func__ << ": ALREADY IN CACHE (" << e << ") ? IGNORING ADD";
+            _cache_notify_waiting_tid_locked(cache, key);
+            return;
+        }
+    }
+
+    ttl = answer_getTTL(answer, answerlen);
+    if (ttl > 0) {
+        e = entry_alloc(key, answer, answerlen);
+        if (e != NULL) {
+            e->expires = ttl + _time_now();
+            _cache_add_p(cache, lookup, e);
+        }
+    }
+
+    cache_dump_mru(cache);
+    _cache_notify_waiting_tid_locked(cache, key);
+}
+
+// Head of the list of caches.
+static struct resolv_cache_info res_cache_list GUARDED_BY(cache_mutex);
+
+// insert resolv_cache_info into the list of resolv_cache_infos
+static void insert_cache_info_locked(resolv_cache_info* cache_info);
+// creates a resolv_cache_info
+static resolv_cache_info* create_cache_info();
+// empty the nameservers set for the named cache
+static void free_nameservers_locked(resolv_cache_info* cache_info);
+// return 1 if the provided list of name servers differs from the list of name servers
+// currently attached to the provided cache_info
+static int resolv_is_nameservers_equal_locked(resolv_cache_info* cache_info, const char** servers,
+                                              int numservers);
+// clears the stats samples contained withing the given cache_info
+static void res_cache_clear_stats_locked(resolv_cache_info* cache_info);
+
+// public API for netd to query if name server is set on specific netid
+bool resolv_has_nameservers(unsigned netid) {
+    std::lock_guard guard(cache_mutex);
+    resolv_cache_info* info = find_cache_info_locked(netid);
+    return (info != nullptr) && (info->nscount > 0);
+}
+
+namespace {
+
+// Map format: ReturnCode:rate_denom
+// if the ReturnCode is not associated with any rate_denom, use default
+// Sampling rate varies by return code; events to log are chosen randomly, with a
+// probability proportional to the sampling rate.
+constexpr const char DEFAULT_SUBSAMPLING_MAP[] = "default:1 0:100 7:10";
+
+std::unordered_map<int, uint32_t> resolv_get_dns_event_subsampling_map() {
+    using android::base::ParseInt;
+    using android::base::ParseUint;
+    using android::base::Split;
+    using server_configurable_flags::GetServerConfigurableFlag;
+    std::unordered_map<int, uint32_t> sampling_rate_map{};
+    std::vector<std::string> subsampling_vector =
+            Split(GetServerConfigurableFlag("netd_native", "dns_event_subsample_map",
+                                            DEFAULT_SUBSAMPLING_MAP),
+                  " ");
+    for (const auto& pair : subsampling_vector) {
+        std::vector<std::string> rate_denom = Split(pair, ":");
+        int return_code;
+        uint32_t denom;
+        if (rate_denom.size() != 2) {
+            LOG(ERROR) << __func__ << ": invalid subsampling_pair = " << pair;
+            continue;
+        }
+        if (rate_denom[0] == "default") {
+            return_code = DNSEVENT_SUBSAMPLING_MAP_DEFAULT_KEY;
+        } else if (!ParseInt(rate_denom[0], &return_code)) {
+            LOG(ERROR) << __func__ << ": parse subsampling_pair failed = " << pair;
+            continue;
+        }
+        if (!ParseUint(rate_denom[1], &denom)) {
+            LOG(ERROR) << __func__ << ": parse subsampling_pair failed = " << pair;
+            continue;
+        }
+        sampling_rate_map[return_code] = denom;
+    }
+    return sampling_rate_map;
+}
+
+}  // namespace
+
+static int resolv_create_cache_for_net_locked(unsigned netid) {
+    resolv_cache* cache = find_named_cache_locked(netid);
+    // Should not happen
+    if (cache) {
+        LOG(ERROR) << __func__ << ": Cache is already created, netId: " << netid;
+        return -EEXIST;
+    }
+
+    resolv_cache_info* cache_info = create_cache_info();
+    if (!cache_info) return -ENOMEM;
+    cache = resolv_cache_create();
+    if (!cache) {
+        free(cache_info);
+        return -ENOMEM;
+    }
+    cache_info->cache = cache;
+    cache_info->netid = netid;
+    cache_info->dns_event_subsampling_map = resolv_get_dns_event_subsampling_map();
+    insert_cache_info_locked(cache_info);
+
+    return 0;
+}
+
+int resolv_create_cache_for_net(unsigned netid) {
+    std::lock_guard guard(cache_mutex);
+    return resolv_create_cache_for_net_locked(netid);
+}
+
+void resolv_delete_cache_for_net(unsigned netid) {
+    std::lock_guard guard(cache_mutex);
+
+    struct resolv_cache_info* prev_cache_info = &res_cache_list;
+
+    while (prev_cache_info->next) {
+        struct resolv_cache_info* cache_info = prev_cache_info->next;
+
+        if (cache_info->netid == netid) {
+            prev_cache_info->next = cache_info->next;
+            cache_flush_locked(cache_info->cache);
+            free(cache_info->cache->entries);
+            free(cache_info->cache);
+            free_nameservers_locked(cache_info);
+            free(cache_info);
+            break;
+        }
+
+        prev_cache_info = prev_cache_info->next;
+    }
+}
+
+std::vector<unsigned> resolv_list_caches() {
+    std::lock_guard guard(cache_mutex);
+    struct resolv_cache_info* cache_info = res_cache_list.next;
+    std::vector<unsigned> result;
+    while (cache_info) {
+        result.push_back(cache_info->netid);
+        cache_info = cache_info->next;
+    }
+    return result;
+}
+
+static resolv_cache_info* create_cache_info() {
+    return (struct resolv_cache_info*) calloc(sizeof(struct resolv_cache_info), 1);
+}
+
+// TODO: convert this to a simple and efficient C++ container.
+static void insert_cache_info_locked(struct resolv_cache_info* cache_info) {
+    struct resolv_cache_info* last;
+    for (last = &res_cache_list; last->next; last = last->next) {}
+    last->next = cache_info;
+}
+
+static resolv_cache* find_named_cache_locked(unsigned netid) {
+    resolv_cache_info* info = find_cache_info_locked(netid);
+    if (info != NULL) return info->cache;
+    return NULL;
+}
+
+static resolv_cache_info* find_cache_info_locked(unsigned netid) {
+    struct resolv_cache_info* cache_info = res_cache_list.next;
+
+    while (cache_info) {
+        if (cache_info->netid == netid) {
+            break;
+        }
+
+        cache_info = cache_info->next;
+    }
+    return cache_info;
+}
+
+static void resolv_set_default_params(res_params* params) {
+    params->sample_validity = NSSAMPLE_VALIDITY;
+    params->success_threshold = SUCCESS_THRESHOLD;
+    params->min_samples = 0;
+    params->max_samples = 0;
+    params->base_timeout_msec = 0;  // 0 = legacy algorithm
+    params->retry_count = 0;
+}
+
+static void resolv_set_experiment_params(res_params* params) {
+    using android::base::ParseInt;
+    using server_configurable_flags::GetServerConfigurableFlag;
+
+    if (params->retry_count == 0) {
+        params->retry_count = RES_DFLRETRY;
+        ParseInt(GetServerConfigurableFlag("netd_native", "retry_count", ""), &params->retry_count);
+    }
+
+    if (params->base_timeout_msec == 0) {
+        params->base_timeout_msec = RES_TIMEOUT;
+        ParseInt(GetServerConfigurableFlag("netd_native", "retransmission_time_interval", ""),
+                 &params->base_timeout_msec);
+    }
+}
+
+int resolv_set_nameservers_for_net(unsigned netid, const char** servers, const int numservers,
+                                   const char* domains, const res_params* params) {
+    char* cp;
+    int* offset;
+    struct addrinfo* nsaddrinfo[MAXNS];
+
+    if (numservers > MAXNS) {
+        LOG(ERROR) << __func__ << ": numservers=" << numservers << ", MAXNS=" << MAXNS;
+        return E2BIG;
+    }
+
+    // Parse the addresses before actually locking or changing any state, in case there is an error.
+    // As a side effect this also reduces the time the lock is kept.
+    char sbuf[NI_MAXSERV];
+    snprintf(sbuf, sizeof(sbuf), "%u", NAMESERVER_PORT);
+    for (int i = 0; i < numservers; i++) {
+        // The addrinfo structures allocated here are freed in free_nameservers_locked().
+        const addrinfo hints = {
+                .ai_family = AF_UNSPEC, .ai_socktype = SOCK_DGRAM, .ai_flags = AI_NUMERICHOST};
+        int rt = getaddrinfo_numeric(servers[i], sbuf, hints, &nsaddrinfo[i]);
+        if (rt != 0) {
+            for (int j = 0; j < i; j++) {
+                freeaddrinfo(nsaddrinfo[j]);
+            }
+            LOG(INFO) << __func__ << ": getaddrinfo_numeric(" << servers[i]
+                      << ") = " << gai_strerror(rt);
+            return EINVAL;
+        }
+    }
+
+    std::lock_guard guard(cache_mutex);
+
+    resolv_cache_info* cache_info = find_cache_info_locked(netid);
+
+    if (cache_info == NULL) return ENONET;
+
+    uint8_t old_max_samples = cache_info->params.max_samples;
+    if (params != NULL) {
+        cache_info->params = *params;
+    } else {
+        resolv_set_default_params(&cache_info->params);
+    }
+    resolv_set_experiment_params(&cache_info->params);
+    if (!resolv_is_nameservers_equal_locked(cache_info, servers, numservers)) {
+        // free current before adding new
+        free_nameservers_locked(cache_info);
+        for (int i = 0; i < numservers; i++) {
+            cache_info->nsaddrinfo[i] = nsaddrinfo[i];
+            cache_info->nameservers[i] = strdup(servers[i]);
+            LOG(INFO) << __func__ << ": netid = " << netid << ", addr = " << servers[i];
+        }
+        cache_info->nscount = numservers;
+
+        // Clear the NS statistics because the mapping to nameservers might have changed.
+        res_cache_clear_stats_locked(cache_info);
+
+        // increment the revision id to ensure that sample state is not written back if the
+        // servers change; in theory it would suffice to do so only if the servers or
+        // max_samples actually change, in practice the overhead of checking is higher than the
+        // cost, and overflows are unlikely
+        ++cache_info->revision_id;
+    } else {
+        if (cache_info->params.max_samples != old_max_samples) {
+            // If the maximum number of samples changes, the overhead of keeping the most recent
+            // samples around is not considered worth the effort, so they are cleared instead.
+            // All other parameters do not affect shared state: Changing these parameters does
+            // not invalidate the samples, as they only affect aggregation and the conditions
+            // under which servers are considered usable.
+            res_cache_clear_stats_locked(cache_info);
+            ++cache_info->revision_id;
+        }
+        for (int j = 0; j < numservers; j++) {
+            freeaddrinfo(nsaddrinfo[j]);
+        }
+    }
+
+    // Always update the search paths, since determining whether they actually changed is
+    // complex due to the zero-padding, and probably not worth the effort. Cache-flushing
+    // however is not necessary, since the stored cache entries do contain the domain, not
+    // just the host name.
+    strlcpy(cache_info->defdname, domains, sizeof(cache_info->defdname));
+    if ((cp = strchr(cache_info->defdname, '\n')) != NULL) *cp = '\0';
+    LOG(INFO) << __func__ << ": domains=\"" << cache_info->defdname << "\"";
+
+    cp = cache_info->defdname;
+    offset = cache_info->dnsrch_offset;
+    while (offset < cache_info->dnsrch_offset + MAXDNSRCH) {
+        while (*cp == ' ' || *cp == '\t') /* skip leading white space */
+            cp++;
+        if (*cp == '\0') /* stop if nothing more to do */
+            break;
+        *offset++ = cp - cache_info->defdname; /* record this search domain */
+        while (*cp) {                          /* zero-terminate it */
+            if (*cp == ' ' || *cp == '\t') {
+                *cp++ = '\0';
+                break;
+            }
+            cp++;
+        }
+    }
+    *offset = -1; /* cache_info->dnsrch_offset has MAXDNSRCH+1 items */
+
+    return 0;
+}
+
+static int resolv_is_nameservers_equal_locked(resolv_cache_info* cache_info, const char** servers,
+                                              int numservers) {
+    if (cache_info->nscount != numservers) {
+        return 0;
+    }
+
+    // Compare each name server against current name servers.
+    // TODO: this is incorrect if the list of current or previous nameservers
+    // contains duplicates. This does not really matter because the framework
+    // filters out duplicates, but we should probably fix it. It's also
+    // insensitive to the order of the nameservers; we should probably fix that
+    // too.
+    for (int i = 0; i < numservers; i++) {
+        for (int j = 0;; j++) {
+            if (j >= numservers) {
+                return 0;
+            }
+            if (strcmp(cache_info->nameservers[i], servers[j]) == 0) {
+                break;
+            }
+        }
+    }
+
+    return 1;
+}
+
+static void free_nameservers_locked(resolv_cache_info* cache_info) {
+    int i;
+    for (i = 0; i < cache_info->nscount; i++) {
+        free(cache_info->nameservers[i]);
+        cache_info->nameservers[i] = NULL;
+        if (cache_info->nsaddrinfo[i] != NULL) {
+            freeaddrinfo(cache_info->nsaddrinfo[i]);
+            cache_info->nsaddrinfo[i] = NULL;
+        }
+        cache_info->nsstats[i].sample_count = cache_info->nsstats[i].sample_next = 0;
+    }
+    cache_info->nscount = 0;
+    res_cache_clear_stats_locked(cache_info);
+    ++cache_info->revision_id;
+}
+
+void _resolv_populate_res_for_net(res_state statp) {
+    if (statp == NULL) {
+        return;
+    }
+    LOG(INFO) << __func__ << ": netid=" << statp->netid;
+
+    std::lock_guard guard(cache_mutex);
+    resolv_cache_info* info = find_cache_info_locked(statp->netid);
+    if (info != NULL) {
+        int nserv;
+        struct addrinfo* ai;
+        for (nserv = 0; nserv < MAXNS; nserv++) {
+            ai = info->nsaddrinfo[nserv];
+            if (ai == NULL) {
+                break;
+            }
+
+            if ((size_t) ai->ai_addrlen <= sizeof(statp->_u._ext.ext->nsaddrs[0])) {
+                if (statp->_u._ext.ext != NULL) {
+                    memcpy(&statp->_u._ext.ext->nsaddrs[nserv], ai->ai_addr, ai->ai_addrlen);
+                    statp->nsaddr_list[nserv].sin_family = AF_UNSPEC;
+                } else {
+                    if ((size_t) ai->ai_addrlen <= sizeof(statp->nsaddr_list[0])) {
+                        memcpy(&statp->nsaddr_list[nserv], ai->ai_addr, ai->ai_addrlen);
+                    } else {
+                        statp->nsaddr_list[nserv].sin_family = AF_UNSPEC;
+                    }
+                }
+            } else {
+                LOG(INFO) << __func__ << ": found too long addrlen";
+            }
+        }
+        statp->nscount = nserv;
+        // now do search domains.  Note that we cache the offsets as this code runs alot
+        // but the setting/offset-computer only runs when set/changed
+        // WARNING: Don't use str*cpy() here, this string contains zeroes.
+        memcpy(statp->defdname, info->defdname, sizeof(statp->defdname));
+        char** pp = statp->dnsrch;
+        int* p = info->dnsrch_offset;
+        while (pp < statp->dnsrch + MAXDNSRCH && *p != -1) {
+            *pp++ = &statp->defdname[0] + *p++;
+        }
+    }
+}
+
+/* Resolver reachability statistics. */
+
+static void _res_cache_add_stats_sample_locked(res_stats* stats, const res_sample* sample,
+                                               int max_samples) {
+    // Note: This function expects max_samples > 0, otherwise a (harmless) modification of the
+    // allocated but supposedly unused memory for samples[0] will happen
+    LOG(INFO) << __func__ << ": adding sample to stats, next = " << unsigned(stats->sample_next)
+              << ", count = " << unsigned(stats->sample_count);
+    stats->samples[stats->sample_next] = *sample;
+    if (stats->sample_count < max_samples) {
+        ++stats->sample_count;
+    }
+    if (++stats->sample_next >= max_samples) {
+        stats->sample_next = 0;
+    }
+}
+
+static void res_cache_clear_stats_locked(resolv_cache_info* cache_info) {
+    if (cache_info) {
+        for (int i = 0; i < MAXNS; ++i) {
+            cache_info->nsstats->sample_count = cache_info->nsstats->sample_next = 0;
+        }
+    }
+}
+
+int android_net_res_stats_get_info_for_net(unsigned netid, int* nscount,
+                                           struct sockaddr_storage servers[MAXNS], int* dcount,
+                                           char domains[MAXDNSRCH][MAXDNSRCHPATH],
+                                           res_params* params, struct res_stats stats[MAXNS],
+                                           int* wait_for_pending_req_timeout_count) {
+    int revision_id = -1;
+    std::lock_guard guard(cache_mutex);
+
+    resolv_cache_info* info = find_cache_info_locked(netid);
+    if (info) {
+        if (info->nscount > MAXNS) {
+            LOG(INFO) << __func__ << ": nscount " << info->nscount << " > MAXNS " << MAXNS;
+            errno = EFAULT;
+            return -1;
+        }
+        int i;
+        for (i = 0; i < info->nscount; i++) {
+            // Verify that the following assumptions are held, failure indicates corruption:
+            //  - getaddrinfo() may never return a sockaddr > sockaddr_storage
+            //  - all addresses are valid
+            //  - there is only one address per addrinfo thanks to numeric resolution
+            int addrlen = info->nsaddrinfo[i]->ai_addrlen;
+            if (addrlen < (int) sizeof(struct sockaddr) || addrlen > (int) sizeof(servers[0])) {
+                LOG(INFO) << __func__ << ": nsaddrinfo[" << i << "].ai_addrlen == " << addrlen;
+                errno = EMSGSIZE;
+                return -1;
+            }
+            if (info->nsaddrinfo[i]->ai_addr == NULL) {
+                LOG(INFO) << __func__ << ": nsaddrinfo[" << i << "].ai_addr == NULL";
+                errno = ENOENT;
+                return -1;
+            }
+            if (info->nsaddrinfo[i]->ai_next != NULL) {
+                LOG(INFO) << __func__ << ": nsaddrinfo[" << i << "].ai_next != NULL";
+                errno = ENOTUNIQ;
+                return -1;
+            }
+        }
+        *nscount = info->nscount;
+        for (i = 0; i < info->nscount; i++) {
+            memcpy(&servers[i], info->nsaddrinfo[i]->ai_addr, info->nsaddrinfo[i]->ai_addrlen);
+            stats[i] = info->nsstats[i];
+        }
+        for (i = 0; i < MAXDNSRCH; i++) {
+            const char* cur_domain = info->defdname + info->dnsrch_offset[i];
+            // dnsrch_offset[i] can either be -1 or point to an empty string to indicate the end
+            // of the search offsets. Checking for < 0 is not strictly necessary, but safer.
+            // TODO: Pass in a search domain array instead of a string to
+            // resolv_set_nameservers_for_net() and make this double check unnecessary.
+            if (info->dnsrch_offset[i] < 0 ||
+                ((size_t) info->dnsrch_offset[i]) >= sizeof(info->defdname) || !cur_domain[0]) {
+                break;
+            }
+            strlcpy(domains[i], cur_domain, MAXDNSRCHPATH);
+        }
+        *dcount = i;
+        *params = info->params;
+        revision_id = info->revision_id;
+        *wait_for_pending_req_timeout_count = info->wait_for_pending_req_timeout_count;
+    }
+
+    return revision_id;
+}
+
+std::vector<std::string> resolv_cache_dump_subsampling_map(unsigned netid) {
+    using android::base::StringPrintf;
+    std::lock_guard guard(cache_mutex);
+    resolv_cache_info* cache_info = find_cache_info_locked(netid);
+    if (cache_info == nullptr) return {};
+    std::vector<std::string> result;
+    for (const auto& pair : cache_info->dns_event_subsampling_map) {
+        result.push_back(StringPrintf("%s:%d",
+                                      (pair.first == DNSEVENT_SUBSAMPLING_MAP_DEFAULT_KEY)
+                                              ? "default"
+                                              : std::to_string(pair.first).c_str(),
+                                      pair.second));
+    }
+    return result;
+}
+
+// Decides whether an event should be sampled using a random number generator and
+// a sampling factor derived from the netid and the return code.
+//
+// Returns the subsampling rate if the event should be sampled, or 0 if it should be discarded.
+uint32_t resolv_cache_get_subsampling_denom(unsigned netid, int return_code) {
+    std::lock_guard guard(cache_mutex);
+    resolv_cache_info* cache_info = find_cache_info_locked(netid);
+    if (cache_info == nullptr) return 0;  // Don't log anything at all.
+    const auto& subsampling_map = cache_info->dns_event_subsampling_map;
+    auto search_returnCode = subsampling_map.find(return_code);
+    uint32_t denom;
+    if (search_returnCode != subsampling_map.end()) {
+        denom = search_returnCode->second;
+    } else {
+        auto search_default = subsampling_map.find(DNSEVENT_SUBSAMPLING_MAP_DEFAULT_KEY);
+        denom = (search_default == subsampling_map.end()) ? 0 : search_default->second;
+    }
+    return denom;
+}
+
+int resolv_cache_get_resolver_stats(unsigned netid, res_params* params, res_stats stats[MAXNS]) {
+    std::lock_guard guard(cache_mutex);
+    resolv_cache_info* info = find_cache_info_locked(netid);
+    if (info) {
+        memcpy(stats, info->nsstats, sizeof(info->nsstats));
+        *params = info->params;
+        return info->revision_id;
+    }
+
+    return -1;
+}
+
+void _resolv_cache_add_resolver_stats_sample(unsigned netid, int revision_id, int ns,
+                                             const res_sample* sample, int max_samples) {
+    if (max_samples <= 0) return;
+
+    std::lock_guard guard(cache_mutex);
+    resolv_cache_info* info = find_cache_info_locked(netid);
+
+    if (info && info->revision_id == revision_id) {
+        _res_cache_add_stats_sample_locked(&info->nsstats[ns], sample, max_samples);
+    }
+}
diff --git a/resolv/res_cache_test.cpp b/resolv/res_cache_test.cpp
new file mode 100644
index 0000000..0b09d88
--- /dev/null
+++ b/resolv/res_cache_test.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <netdb.h>
+
+#include <cutils/properties.h>
+#include <gmock/gmock-matchers.h>
+#include <gtest/gtest.h>
+
+#include "netd_resolv/stats.h"
+#include "resolv_cache.h"
+
+constexpr int TEST_NETID = 30;
+
+namespace {
+
+constexpr int EAI_OK = 0;
+constexpr char DNS_EVENT_SUBSAMPLING_MAP_FLAG[] =
+        "persist.device_config.netd_native.dns_event_subsample_map";
+
+class ScopedCacheCreate {
+  public:
+    explicit ScopedCacheCreate(unsigned netid, const char* subsampling_map,
+                               const char* property = DNS_EVENT_SUBSAMPLING_MAP_FLAG)
+        : mStoredNetId(netid), mStoredProperty(property) {
+        property_get(property, mStoredMap, "");
+        property_set(property, subsampling_map);
+        EXPECT_EQ(0, resolv_create_cache_for_net(netid));
+    }
+    ~ScopedCacheCreate() {
+        resolv_delete_cache_for_net(mStoredNetId);
+        property_set(mStoredProperty, mStoredMap);
+    }
+
+  private:
+    unsigned mStoredNetId;
+    const char* mStoredProperty;
+    char mStoredMap[PROPERTY_VALUE_MAX]{};
+};
+
+}  // namespace
+
+TEST(ResolvCacheTest, DnsEventSubsampling) {
+    // Test defaults, default flag is "default:1 0:100 7:10" if no experiment flag is set
+    {
+        ScopedCacheCreate scopedCacheCreate(TEST_NETID, "");
+        EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA), 10U);
+        EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK), 100U);
+        EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_BADFLAGS),
+                  1U);  // default
+        EXPECT_THAT(resolv_cache_dump_subsampling_map(TEST_NETID),
+                    testing::UnorderedElementsAreArray({"default:1", "0:100", "7:10"}));
+    }
+    // Now change the experiment flag to "0:42 default:666"
+    {
+        ScopedCacheCreate scopedCacheCreate(TEST_NETID, "0:42 default:666");
+        EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK), 42U);
+        EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA),
+                  666U);  // default
+        EXPECT_THAT(resolv_cache_dump_subsampling_map(TEST_NETID),
+                    testing::UnorderedElementsAreArray({"default:666", "0:42"}));
+    }
+    // Now change the experiment flag to something illegal
+    {
+        ScopedCacheCreate scopedCacheCreate(TEST_NETID, "asvaxx");
+        // 0(disable log) is the default value if experiment flag is invalid.
+        EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK), 0U);
+        EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA), 0U);
+        EXPECT_TRUE(resolv_cache_dump_subsampling_map(TEST_NETID).empty());
+    }
+    // Test negative and zero denom
+    {
+        ScopedCacheCreate scopedCacheCreate(TEST_NETID, "0:-42 default:-666 7:10 10:0");
+        // 0(disable log) is the default value if no valid denom is set
+        EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK), 0U);
+        EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_BADFLAGS), 0U);
+        EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA), 10U);
+        EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_SOCKTYPE), 0U);
+        EXPECT_THAT(resolv_cache_dump_subsampling_map(TEST_NETID),
+                    testing::UnorderedElementsAreArray({"7:10", "10:0"}));
+    }
+}
diff --git a/resolv/res_comp.cpp b/resolv/res_comp.cpp
new file mode 100644
index 0000000..98461b3
--- /dev/null
+++ b/resolv/res_comp.cpp
@@ -0,0 +1,212 @@
+/*	$NetBSD: res_comp.c,v 1.6 2004/05/22 23:47:09 christos Exp $	*/
+
+/*
+ * Copyright (c) 1985, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <netinet/in.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "resolv_private.h"
+
+/*
+ * Expand compressed domain name 'src' to full domain name.
+ * 'msg' is a pointer to the begining of the message,
+ * 'eom' points to the first location after the message,
+ * 'dst' is a pointer to a buffer of size 'dstsiz' for the result.
+ * Return size of compressed name or -1 if there was an error.
+ */
+int dn_expand(const u_char* msg, const u_char* eom, const u_char* src, char* dst, int dstsiz) {
+    int n = ns_name_uncompress(msg, eom, src, dst, (size_t) dstsiz);
+
+    if (n > 0 && dst[0] == '.') dst[0] = '\0';
+    return (n);
+}
+
+/*
+ * Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
+ * Return the size of the compressed name or -1.
+ * 'length' is the size of the array pointed to by 'comp_dn'.
+ */
+int dn_comp(const char* src, u_char* dst, int dstsiz, u_char** dnptrs, u_char** lastdnptr) {
+    return (ns_name_compress(src, dst, (size_t) dstsiz, (const u_char**) dnptrs,
+                             (const u_char**) lastdnptr));
+}
+
+/*
+ * Skip over a compressed domain name. Return the size or -1.
+ */
+int dn_skipname(const u_char* ptr, const u_char* eom) {
+    const u_char* saveptr = ptr;
+
+    if (ns_name_skip(&ptr, eom) == -1) return (-1);
+    return (ptr - saveptr);
+}
+
+/*
+ * Verify that a domain name uses an acceptable character set.
+ */
+
+/*
+ * Note the conspicuous absence of ctype macros in these definitions.  On
+ * non-ASCII hosts, we can't depend on string literals or ctype macros to
+ * tell us anything about network-format data.  The rest of the BIND system
+ * is not careful about this, but for some reason, we're doing it right here.
+ */
+
+/* BIONIC: We also accept underscores in the middle of labels.
+ *         This extension is needed to make resolution on some VPN networks
+ *         work properly.
+ */
+
+#define PERIOD 0x2e
+#define hyphenchar(c) ((c) == 0x2d)
+#define bslashchar(c) ((c) == 0x5c)
+#define periodchar(c) ((c) == PERIOD)
+#define asterchar(c) ((c) == 0x2a)
+#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) || ((c) >= 0x61 && (c) <= 0x7a))
+#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
+#define underscorechar(c) ((c) == 0x5f)
+
+#define borderchar(c) (alphachar(c) || digitchar(c))
+#define middlechar(c) (borderchar(c) || hyphenchar(c) || underscorechar(c))
+#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
+
+int res_hnok(const char* dn) {
+    int pch = PERIOD, ch = *dn++;
+
+    while (ch != '\0') {
+        int nch = *dn++;
+
+        if (periodchar(ch)) {
+            ;
+        } else if (periodchar(pch)) {
+            if (!borderchar(ch)) return (0);
+        } else if (periodchar(nch) || nch == '\0') {
+            if (!borderchar(ch)) return (0);
+        } else {
+            if (!middlechar(ch)) return (0);
+        }
+        pch = ch, ch = nch;
+    }
+    return (1);
+}
+
+/*
+ * hostname-like (A, MX, WKS) owners can have "*" as their first label
+ * but must otherwise be as a host name.
+ */
+int res_ownok(const char* dn) {
+    if (asterchar(dn[0])) {
+        if (periodchar(dn[1])) return (res_hnok(dn + 2));
+        if (dn[1] == '\0') return (1);
+    }
+    return (res_hnok(dn));
+}
+
+/*
+ * SOA RNAMEs and RP RNAMEs can have any printable character in their first
+ * label, but the rest of the name has to look like a host name.
+ */
+int res_mailok(const char* dn) {
+    int ch, escaped = 0;
+
+    /* "." is a valid missing representation */
+    if (*dn == '\0') return (1);
+
+    /* otherwise <label>.<hostname> */
+    while ((ch = *dn++) != '\0') {
+        if (!domainchar(ch)) return (0);
+        if (!escaped && periodchar(ch)) break;
+        if (escaped)
+            escaped = 0;
+        else if (bslashchar(ch))
+            escaped = 1;
+    }
+    if (periodchar(ch)) return (res_hnok(dn));
+    return (0);
+}
+
+/*
+ * This function is quite liberal, since RFC 1034's character sets are only
+ * recommendations.
+ */
+int res_dnok(const char* dn) {
+    int ch;
+
+    while ((ch = *dn++) != '\0')
+        if (!domainchar(ch)) return (0);
+    return (1);
+}
diff --git a/resolv/res_debug.cpp b/resolv/res_debug.cpp
new file mode 100644
index 0000000..5b20a58
--- /dev/null
+++ b/resolv/res_debug.cpp
@@ -0,0 +1,540 @@
+/*	$NetBSD: res_debug.c,v 1.13 2012/06/25 22:32:45 abs Exp $	*/
+
+/*
+ * Portions Copyright (C) 2004, 2005, 2008, 2009  Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 1996-2003  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1985
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define LOG_TAG "res_debug"
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netinet/in.h>
+
+#include <aidl/android/net/IDnsResolver.h>
+#include <android-base/logging.h>
+#include <ctype.h>
+#include <errno.h>
+#include <math.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <time.h>
+
+#include "resolv_private.h"
+
+// Default to disabling verbose logging unless overridden by Android.bp
+// for debuggable builds.
+//
+// NOTE: Verbose resolver logs could contain PII -- do NOT enable in production builds
+#ifndef RESOLV_ALLOW_VERBOSE_LOGGING
+#define RESOLV_ALLOW_VERBOSE_LOGGING 0
+#endif
+
+struct res_sym {
+    int number;            /* Identifying number, like T_MX */
+    const char* name;      /* Its symbolic name, like "MX" */
+    const char* humanname; /* Its fun name, like "mail exchanger" */
+};
+
+// add a formatted string to a bounded buffer
+// TODO: convert to std::string
+static char* dbprint(char* p, char* end, const char* format, ...) {
+    int avail, n;
+    va_list args;
+
+    avail = end - p;
+
+    if (avail <= 0) return p;
+
+    va_start(args, format);
+    n = vsnprintf(p, avail, format, args);
+    va_end(args);
+
+    /* certain C libraries return -1 in case of truncation */
+    if (n < 0 || n > avail) n = avail;
+
+    p += n;
+    /* certain C libraries do not zero-terminate in case of truncation */
+    if (p == end) p[-1] = 0;
+
+    return p;
+}
+
+static void do_section(ns_msg* handle, ns_sect section) {
+    int n, rrnum;
+    int buflen = 2048;
+    ns_opcode opcode;
+    ns_rr rr;
+    char temp[2048], *p = temp, *end = p + sizeof(temp);
+
+    /*
+     * Print answer records.
+     */
+
+    char* buf = (char*) malloc((size_t) buflen);
+    if (buf == NULL) {
+        dbprint(p, end, ";; memory allocation failure\n");
+        LOG(VERBOSE) << __func__ << ": " << temp;
+        return;
+    }
+
+    opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
+    rrnum = 0;
+    for (;;) {
+        if (ns_parserr(handle, section, rrnum, &rr)) {
+            if (errno != ENODEV)
+                dbprint(p, end, ";; ns_parserr: %s", strerror(errno));
+            goto cleanup;
+        }
+        if (section == ns_s_qd)
+            dbprint(p, end, ";;\t%s, type = %s, class = %s\n", ns_rr_name(rr),
+                    p_type(ns_rr_type(rr)), p_class(ns_rr_class(rr)));
+        else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) {
+            size_t rdatalen, ttl;
+            uint16_t optcode, optlen;
+
+            rdatalen = ns_rr_rdlen(rr);
+            ttl = ns_rr_ttl(rr);
+            dbprint(p, end, "; EDNS: version: %zu, udp=%u, flags=%04zx\n", (ttl >> 16) & 0xff,
+                    ns_rr_class(rr), ttl & 0xffff);
+            const u_char* cp = ns_rr_rdata(rr);
+            while (rdatalen <= ns_rr_rdlen(rr) && rdatalen >= 4) {
+                int i;
+
+                GETSHORT(optcode, cp);
+                GETSHORT(optlen, cp);
+
+                if (optcode == NS_OPT_NSID) {
+                    p = dbprint(p, end, "; NSID: ");
+                    if (optlen == 0) {
+                        p = dbprint(p, end, "; NSID\n");
+                    } else {
+                        p = dbprint(p, end, "; NSID: ");
+                        for (i = 0; i < optlen; i++) {
+                            p = dbprint(p, end, "%02x ", cp[i]);
+                        }
+                        p = dbprint(p, end, " (");
+                        for (i = 0; i < optlen; i++) {
+                            p = dbprint(p, end, "%c", isprint(cp[i]) ? cp[i] : '.');
+                        }
+                        p = dbprint(p, end, ")\n");
+                    }
+                } else {
+                    if (optlen == 0) {
+                        p = dbprint(p, end, "; OPT=%u\n", optcode);
+                    } else {
+                        p = dbprint(p, end, "; OPT=%u: ", optcode);
+                        for (i = 0; i < optlen; i++) {
+                            p = dbprint(p, end, "%02x ", cp[i]);
+                        }
+                        p = dbprint(p, end, " (");
+                        for (i = 0; i < optlen; i++) {
+                            p = dbprint(p, end, "%c", isprint(cp[i]) ? cp[i] : '.');
+                        }
+                        p = dbprint(p, end, ")\n");
+                    }
+                }
+                rdatalen -= 4 + optlen;
+                cp += optlen;
+            }
+        } else {
+            n = ns_sprintrr(handle, &rr, NULL, NULL, buf, (u_int) buflen);
+            if (n < 0) {
+                if (errno == ENOSPC) {
+                    free(buf);
+                    buf = NULL;
+                    if (buflen < 131072) {
+                        buf = (char*) malloc((size_t)(buflen += 1024));
+                    }
+                    if (buf == NULL) {
+                        p = dbprint(p, end, ";; memory allocation failure\n");
+                        LOG(VERBOSE) << __func__ << ": " << temp;
+                        return;
+                    }
+                    continue;
+                }
+                p = dbprint(p, end, ";; ns_sprintrr: %s\n", strerror(errno));
+                goto cleanup;
+            }
+            p = dbprint(p, end, ";; %s\n", buf);
+        }
+        rrnum++;
+    }
+cleanup:
+    free(buf);
+    LOG(VERBOSE) << temp;
+}
+
+/*
+ * Print the contents of a query.
+ * This is intended to be primarily a debugging routine.
+ */
+void res_pquery(const u_char* msg, int len) {
+    if (!WOULD_LOG(VERBOSE)) return;
+
+    ns_msg handle;
+    int qdcount, ancount, nscount, arcount;
+    u_int opcode, rcode, id;
+    char temp[2048], *p = temp, *end = p + sizeof(temp);
+
+    if (ns_initparse(msg, len, &handle) < 0) {
+        dbprint(p, end, ";; ns_initparse: %s\n", strerror(errno));
+        return;
+    }
+    opcode = ns_msg_getflag(handle, ns_f_opcode);
+    rcode = ns_msg_getflag(handle, ns_f_rcode);
+    id = ns_msg_id(handle);
+    qdcount = ns_msg_count(handle, ns_s_qd);
+    ancount = ns_msg_count(handle, ns_s_an);
+    nscount = ns_msg_count(handle, ns_s_ns);
+    arcount = ns_msg_count(handle, ns_s_ar);
+
+    /*
+     * Print header fields.
+     */
+    dbprint(p, end, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n", _res_opcodes[opcode],
+            p_rcode((int)rcode), id);
+    p = dbprint(p, end, ";");
+    p = dbprint(p, end, "; flags:");
+    if (ns_msg_getflag(handle, ns_f_qr)) p = dbprint(p, end, " qr");
+    if (ns_msg_getflag(handle, ns_f_aa)) p = dbprint(p, end, " aa");
+    if (ns_msg_getflag(handle, ns_f_tc)) p = dbprint(p, end, " tc");
+    if (ns_msg_getflag(handle, ns_f_rd)) p = dbprint(p, end, " rd");
+    if (ns_msg_getflag(handle, ns_f_ra)) p = dbprint(p, end, " ra");
+    if (ns_msg_getflag(handle, ns_f_z)) p = dbprint(p, end, " ??");
+    if (ns_msg_getflag(handle, ns_f_ad)) p = dbprint(p, end, " ad");
+    if (ns_msg_getflag(handle, ns_f_cd)) p = dbprint(p, end, " cd");
+    p = dbprint(p, end, "; %s: %d", p_section(ns_s_qd, (int)opcode), qdcount);
+    p = dbprint(p, end, ", %s: %d", p_section(ns_s_an, (int)opcode), ancount);
+    p = dbprint(p, end, ", %s: %d", p_section(ns_s_ns, (int)opcode), nscount);
+    p = dbprint(p, end, ", %s: %d", p_section(ns_s_ar, (int)opcode), arcount);
+
+    LOG(VERBOSE) << temp;
+
+    /*
+     * Print the various sections.
+     */
+    do_section(&handle, ns_s_qd);
+    do_section(&handle, ns_s_an);
+    do_section(&handle, ns_s_ns);
+    do_section(&handle, ns_s_ar);
+    if (qdcount == 0 && ancount == 0 && nscount == 0 && arcount == 0) LOG(VERBOSE) << ";;";
+}
+
+/*
+ * Names of RR classes and qclasses.  Classes and qclasses are the same, except
+ * that C_ANY is a qclass but not a class.  (You can ask for records of class
+ * C_ANY, but you can't have any records of that class in the database.)
+ */
+static const struct res_sym p_class_syms[] = {
+        {C_IN, "IN", (char*) 0},     {C_CHAOS, "CH", (char*) 0},  {C_CHAOS, "CHAOS", (char*) 0},
+        {C_HS, "HS", (char*) 0},     {C_HS, "HESIOD", (char*) 0}, {C_ANY, "ANY", (char*) 0},
+        {C_NONE, "NONE", (char*) 0}, {C_IN, (char*) 0, (char*) 0}};
+
+/*
+ * Names of message sections.
+ */
+static const struct res_sym p_default_section_syms[] = {{ns_s_qd, "QUERY", (char*) 0},
+                                                        {ns_s_an, "ANSWER", (char*) 0},
+                                                        {ns_s_ns, "AUTHORITY", (char*) 0},
+                                                        {ns_s_ar, "ADDITIONAL", (char*) 0},
+                                                        {0, (char*) 0, (char*) 0}};
+
+static const struct res_sym p_update_section_syms[] = {{S_ZONE, "ZONE", (char*) 0},
+                                                       {S_PREREQ, "PREREQUISITE", (char*) 0},
+                                                       {S_UPDATE, "UPDATE", (char*) 0},
+                                                       {S_ADDT, "ADDITIONAL", (char*) 0},
+                                                       {0, (char*) 0, (char*) 0}};
+
+/*
+ * Names of RR types and qtypes.  Types and qtypes are the same, except
+ * that T_ANY is a qtype but not a type.  (You can ask for records of type
+ * T_ANY, but you can't have any records of that type in the database.)
+ */
+const struct res_sym p_type_syms[] = {
+        {ns_t_a, "A", "address"},
+        {ns_t_ns, "NS", "name server"},
+        {ns_t_md, "MD", "mail destination (deprecated)"},
+        {ns_t_mf, "MF", "mail forwarder (deprecated)"},
+        {ns_t_cname, "CNAME", "canonical name"},
+        {ns_t_soa, "SOA", "start of authority"},
+        {ns_t_mb, "MB", "mailbox"},
+        {ns_t_mg, "MG", "mail group member"},
+        {ns_t_mr, "MR", "mail rename"},
+        {ns_t_null, "NULL", "null"},
+        {ns_t_wks, "WKS", "well-known service (deprecated)"},
+        {ns_t_ptr, "PTR", "domain name pointer"},
+        {ns_t_hinfo, "HINFO", "host information"},
+        {ns_t_minfo, "MINFO", "mailbox information"},
+        {ns_t_mx, "MX", "mail exchanger"},
+        {ns_t_txt, "TXT", "text"},
+        {ns_t_rp, "RP", "responsible person"},
+        {ns_t_afsdb, "AFSDB", "DCE or AFS server"},
+        {ns_t_x25, "X25", "X25 address"},
+        {ns_t_isdn, "ISDN", "ISDN address"},
+        {ns_t_rt, "RT", "router"},
+        {ns_t_nsap, "NSAP", "nsap address"},
+        {ns_t_nsap_ptr, "NSAP_PTR", "domain name pointer"},
+        {ns_t_sig, "SIG", "signature"},
+        {ns_t_key, "KEY", "key"},
+        {ns_t_px, "PX", "mapping information"},
+        {ns_t_gpos, "GPOS", "geographical position (withdrawn)"},
+        {ns_t_aaaa, "AAAA", "IPv6 address"},
+        {ns_t_loc, "LOC", "location"},
+        {ns_t_nxt, "NXT", "next valid name (unimplemented)"},
+        {ns_t_eid, "EID", "endpoint identifier (unimplemented)"},
+        {ns_t_nimloc, "NIMLOC", "NIMROD locator (unimplemented)"},
+        {ns_t_srv, "SRV", "server selection"},
+        {ns_t_atma, "ATMA", "ATM address (unimplemented)"},
+        {ns_t_naptr, "NAPTR", "naptr"},
+        {ns_t_kx, "KX", "key exchange"},
+        {ns_t_cert, "CERT", "certificate"},
+        {ns_t_a6, "A", "IPv6 address (experminental)"},
+        {ns_t_dname, "DNAME", "non-terminal redirection"},
+        {ns_t_opt, "OPT", "opt"},
+        {ns_t_apl, "apl", "apl"},
+        {ns_t_ds, "DS", "delegation signer"},
+        {ns_t_sshfp, "SSFP", "SSH fingerprint"},
+        {ns_t_ipseckey, "IPSECKEY", "IPSEC key"},
+        {ns_t_rrsig, "RRSIG", "rrsig"},
+        {ns_t_nsec, "NSEC", "nsec"},
+        {ns_t_dnskey, "DNSKEY", "DNS key"},
+        {ns_t_dhcid, "DHCID", "dynamic host configuration identifier"},
+        {ns_t_nsec3, "NSEC3", "nsec3"},
+        {ns_t_nsec3param, "NSEC3PARAM", "NSEC3 parameters"},
+        {ns_t_hip, "HIP", "host identity protocol"},
+        {ns_t_spf, "SPF", "sender policy framework"},
+        {ns_t_tkey, "TKEY", "tkey"},
+        {ns_t_tsig, "TSIG", "transaction signature"},
+        {ns_t_ixfr, "IXFR", "incremental zone transfer"},
+        {ns_t_axfr, "AXFR", "zone transfer"},
+        {ns_t_zxfr, "ZXFR", "compressed zone transfer"},
+        {ns_t_mailb, "MAILB", "mailbox-related data (deprecated)"},
+        {ns_t_maila, "MAILA", "mail agent (deprecated)"},
+        {ns_t_naptr, "NAPTR", "URN Naming Authority"},
+        {ns_t_kx, "KX", "Key Exchange"},
+        {ns_t_cert, "CERT", "Certificate"},
+        {ns_t_a6, "A6", "IPv6 Address"},
+        {ns_t_dname, "DNAME", "dname"},
+        {ns_t_sink, "SINK", "Kitchen Sink (experimental)"},
+        {ns_t_opt, "OPT", "EDNS Options"},
+        {ns_t_any, "ANY", "\"any\""},
+        {ns_t_dlv, "DLV", "DNSSEC look-aside validation"},
+        {0, NULL, NULL}};
+
+/*
+ * Names of DNS rcodes.
+ */
+static const struct res_sym p_rcode_syms[] = {{ns_r_noerror, "NOERROR", "no error"},
+                                              {ns_r_formerr, "FORMERR", "format error"},
+                                              {ns_r_servfail, "SERVFAIL", "server failed"},
+                                              {ns_r_nxdomain, "NXDOMAIN", "no such domain name"},
+                                              {ns_r_notimpl, "NOTIMP", "not implemented"},
+                                              {ns_r_refused, "REFUSED", "refused"},
+                                              {ns_r_yxdomain, "YXDOMAIN", "domain name exists"},
+                                              {ns_r_yxrrset, "YXRRSET", "rrset exists"},
+                                              {ns_r_nxrrset, "NXRRSET", "rrset doesn't exist"},
+                                              {ns_r_notauth, "NOTAUTH", "not authoritative"},
+                                              {ns_r_notzone, "NOTZONE", "Not in zone"},
+                                              {ns_r_max, "", ""},
+                                              {ns_r_badsig, "BADSIG", "bad signature"},
+                                              {ns_r_badkey, "BADKEY", "bad key"},
+                                              {ns_r_badtime, "BADTIME", "bad time"},
+                                              {0, NULL, NULL}};
+
+static const char* sym_ntos(const struct res_sym* syms, int number, int* success) {
+    static char unname[20];
+
+    for (; syms->name != 0; syms++) {
+        if (number == syms->number) {
+            if (success) *success = 1;
+            return (syms->name);
+        }
+    }
+
+    snprintf(unname, sizeof(unname), "%d", number); /* XXX nonreentrant */
+    if (success) *success = 0;
+    return (unname);
+}
+
+/*
+ * Return a string for the type.
+ */
+const char* p_type(int type) {
+    int success;
+    const char* result;
+    static char typebuf[20];
+
+    result = sym_ntos(p_type_syms, type, &success);
+    if (success) return (result);
+    if (type < 0 || type > 0xffff) return ("BADTYPE");
+    snprintf(typebuf, sizeof(typebuf), "TYPE%d", type);
+    return (typebuf);
+}
+
+/*
+ * Return a string for the type.
+ */
+const char* p_section(int section, int opcode) {
+    const struct res_sym* symbols;
+
+    switch (opcode) {
+        case ns_o_update:
+            symbols = p_update_section_syms;
+            break;
+        default:
+            symbols = p_default_section_syms;
+            break;
+    }
+    return (sym_ntos(symbols, section, (int*) 0));
+}
+
+/*
+ * Return a mnemonic for class.
+ */
+const char* p_class(int cl) {
+    int success;
+    const char* result;
+    static char classbuf[20];
+
+    result = sym_ntos(p_class_syms, cl, &success);
+    if (success) return (result);
+    if (cl < 0 || cl > 0xffff) return ("BADCLASS");
+    snprintf(classbuf, sizeof(classbuf), "CLASS%d", cl);
+    return (classbuf);
+}
+
+/*
+ * Return a string for the rcode.
+ */
+const char* p_rcode(int rcode) {
+    return (sym_ntos(p_rcode_syms, rcode, (int*) 0));
+}
+
+int resolv_set_log_severity(uint32_t logSeverity) {
+    switch (logSeverity) {
+        case aidl::android::net::IDnsResolver::DNS_RESOLVER_LOG_VERBOSE:
+            logSeverity = android::base::VERBOSE;
+            // *** enable verbose logging only when DBG is set. It prints sensitive data ***
+            if (RESOLV_ALLOW_VERBOSE_LOGGING == false) {
+                logSeverity = android::base::DEBUG;
+                LOG(ERROR) << "Refusing to set VERBOSE logging in non-debuggable build";
+                // TODO: Return EACCES then callers could know if the log
+                // severity is acceptable
+            }
+            break;
+        case aidl::android::net::IDnsResolver::DNS_RESOLVER_LOG_DEBUG:
+            logSeverity = android::base::DEBUG;
+            break;
+        case aidl::android::net::IDnsResolver::DNS_RESOLVER_LOG_INFO:
+            logSeverity = android::base::INFO;
+            break;
+        case aidl::android::net::IDnsResolver::DNS_RESOLVER_LOG_WARNING:
+            logSeverity = android::base::WARNING;
+            break;
+        case aidl::android::net::IDnsResolver::DNS_RESOLVER_LOG_ERROR:
+            logSeverity = android::base::ERROR;
+            break;
+        default:
+            LOG(ERROR) << __func__ << ": invalid log severity: " << logSeverity;
+            return -EINVAL;
+    }
+    android::base::SetMinimumLogSeverity(static_cast<android::base::LogSeverity>(logSeverity));
+    return 0;
+}
diff --git a/resolv/res_debug.h b/resolv/res_debug.h
new file mode 100644
index 0000000..2ba31d4
--- /dev/null
+++ b/resolv/res_debug.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cinttypes>
+
+int resolv_set_log_severity(uint32_t logSeverity);
diff --git a/resolv/res_init.cpp b/resolv/res_init.cpp
new file mode 100644
index 0000000..bdbe162
--- /dev/null
+++ b/resolv/res_init.cpp
@@ -0,0 +1,399 @@
+/*	$NetBSD: res_init.c,v 1.8 2006/03/19 03:10:08 christos Exp $	*/
+
+/*
+ * Copyright (c) 1985, 1989, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define LOG_TAG "res_init"
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netinet/in.h>
+
+#include <android-base/logging.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "netd_resolv/resolv.h"
+#include "res_state_ext.h"
+#include "resolv_private.h"
+
+
+static void res_setoptions(res_state, const char*, const char*);
+
+/*
+ * Resolver state default settings.
+ */
+
+/*
+ * Set up default settings.  If the configuration file exist, the values
+ * there will have precedence.  Otherwise, the server address is set to
+ * INADDR_ANY and the default domain name comes from the gethostname().
+ *
+ * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
+ * rather than INADDR_ANY ("0.0.0.0") as the default name server address
+ * since it was noted that INADDR_ANY actually meant ``the first interface
+ * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
+ * it had to be "up" in order for you to reach your own name server.  It
+ * was later decided that since the recommended practice is to always
+ * install local static routes through 127.0.0.1 for all your network
+ * interfaces, that we could solve this problem without a code change.
+ *
+ * The configuration file should always be used, since it is the only way
+ * to specify a default domain.  If you are running a server on your local
+ * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
+ * in the configuration file.
+ *
+ * Return 0 if completes successfully, -1 on error
+ */
+int res_ninit(res_state statp) {
+    return res_vinit(statp, 0);
+}
+
+/* This function has to be reachable by res_data.c but not publicly. */
+int res_vinit(res_state statp, int preinit) {
+    char *cp, **pp;
+    char buf[BUFSIZ];
+    int nserv = 0; /* number of nameserver records read from file */
+    int havesearch = 0;
+    int dots;
+    sockaddr_union u[2];
+
+    if ((statp->options & RES_INIT) != 0U) res_ndestroy(statp);
+
+    if (!preinit) {
+        statp->netid = NETID_UNSET;
+        statp->options = RES_DEFAULT;
+        statp->id = arc4random_uniform(65536);
+        statp->_mark = MARK_UNSET;
+    }
+
+    memset(u, 0, sizeof(u));
+    u[nserv].sin.sin_addr.s_addr = INADDR_ANY;
+    u[nserv].sin.sin_family = AF_INET;
+    u[nserv].sin.sin_port = htons(NAMESERVER_PORT);
+    nserv++;
+    statp->nscount = 0;
+    statp->ndots = 1;
+    statp->_vcsock = -1;
+    statp->_flags = 0;
+    statp->_u._ext.nscount = 0;
+    statp->_u._ext.ext = (res_state_ext*) malloc(sizeof(*statp->_u._ext.ext));
+    statp->use_local_nameserver = false;
+    if (statp->_u._ext.ext != NULL) {
+        memset(statp->_u._ext.ext, 0, sizeof(*statp->_u._ext.ext));
+        statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
+        strcpy(statp->_u._ext.ext->nsuffix, "ip6.arpa");
+        strcpy(statp->_u._ext.ext->nsuffix2, "ip6.int");
+    }
+    statp->nsort = 0;
+    res_setservers(statp, u, nserv);
+
+    if (statp->defdname[0] == 0 && gethostname(buf, sizeof(statp->defdname) - 1) == 0 &&
+        (cp = strchr(buf, '.')) != NULL)
+        strcpy(statp->defdname, cp + 1);
+
+    /* find components of local domain that might be searched */
+    if (havesearch == 0) {
+        pp = statp->dnsrch;
+        *pp++ = statp->defdname;
+        *pp = NULL;
+
+        dots = 0;
+        for (cp = statp->defdname; *cp; cp++) dots += (*cp == '.');
+
+        cp = statp->defdname;
+        while (pp < statp->dnsrch + MAXDFLSRCH) {
+            if (dots < LOCALDOMAINPARTS) break;
+            cp = strchr(cp, '.') + 1; /* we know there is one */
+            *pp++ = cp;
+            dots--;
+        }
+        *pp = NULL;
+        LOG(DEBUG) << __func__ << ": dnsrch list:";
+        for (pp = statp->dnsrch; *pp; pp++) LOG(DEBUG) << "\t" << *pp;
+    }
+
+    if ((cp = getenv("RES_OPTIONS")) != NULL) res_setoptions(statp, cp, "env");
+    if (nserv > 0) {
+        statp->nscount = nserv;
+        statp->options |= RES_INIT;
+    }
+    return (0);
+}
+
+static void res_setoptions(res_state statp, const char* options, const char* source) {
+    const char* cp = options;
+    int i;
+    res_state_ext* ext = statp->_u._ext.ext;
+
+    LOG(DEBUG) << "res_setoptions(\"" << options << "\", \"" << source << "\")...";
+
+    while (*cp) {
+        /* skip leading and inner runs of spaces */
+        while (*cp == ' ' || *cp == '\t') cp++;
+        /* search for and process individual options */
+        if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
+            i = atoi(cp + sizeof("ndots:") - 1);
+            if (i <= RES_MAXNDOTS)
+                statp->ndots = i;
+            else
+                statp->ndots = RES_MAXNDOTS;
+            LOG(DEBUG) << "\tndots=" << statp->ndots;
+
+        } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
+            if (!(statp->options & RES_DEBUG)) {
+                LOG(DEBUG) << "res_setoptions(\"" << options << "\", \"" << source << "\")..";
+                statp->options |= RES_DEBUG;
+            }
+            LOG(DEBUG) << "\tdebug";
+
+        } else if (!strncmp(cp, "no_tld_query", sizeof("no_tld_query") - 1) ||
+                   !strncmp(cp, "no-tld-query", sizeof("no-tld-query") - 1)) {
+            statp->options |= RES_NOTLDQUERY;
+        } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
+            statp->options |= RES_USE_INET6;
+        } else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) {
+            statp->options |= RES_ROTATE;
+        } else if (!strncmp(cp, "no-check-names", sizeof("no-check-names") - 1)) {
+            statp->options |= RES_NOCHECKNAME;
+        }
+        else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
+            statp->options |= RES_USE_EDNS0;
+        }
+        else if (!strncmp(cp, "dname", sizeof("dname") - 1)) {
+            statp->options |= RES_USE_DNAME;
+        } else if (!strncmp(cp, "nibble:", sizeof("nibble:") - 1)) {
+            if (ext == NULL) goto skip;
+            cp += sizeof("nibble:") - 1;
+            i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix) - 1);
+            strncpy(ext->nsuffix, cp, (size_t) i);
+            ext->nsuffix[i] = '\0';
+        } else if (!strncmp(cp, "nibble2:", sizeof("nibble2:") - 1)) {
+            if (ext == NULL) goto skip;
+            cp += sizeof("nibble2:") - 1;
+            i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix2) - 1);
+            strncpy(ext->nsuffix2, cp, (size_t) i);
+            ext->nsuffix2[i] = '\0';
+        } else if (!strncmp(cp, "v6revmode:", sizeof("v6revmode:") - 1)) {
+            cp += sizeof("v6revmode:") - 1;
+            /* "nibble" and "bitstring" used to be valid */
+            if (!strncmp(cp, "single", sizeof("single") - 1)) {
+                statp->options |= RES_NO_NIBBLE2;
+            } else if (!strncmp(cp, "both", sizeof("both") - 1)) {
+                statp->options &= ~RES_NO_NIBBLE2;
+            }
+        } else {
+            /* XXX - print a warning here? */
+        }
+    skip:
+        /* skip to next run of spaces */
+        while (*cp && *cp != ' ' && *cp != '\t') cp++;
+    }
+}
+
+/*
+ * This routine is for closing the socket if a virtual circuit is used and
+ * the program wants to close it.  This provides support for endhostent()
+ * which expects to close the socket.
+ *
+ * This routine is not expected to be user visible.
+ */
+void res_nclose(res_state statp) {
+    int ns;
+
+    if (statp->_vcsock >= 0) {
+        (void) close(statp->_vcsock);
+        statp->_vcsock = -1;
+        statp->_flags &= ~RES_F_VC;
+    }
+    for (ns = 0; ns < statp->_u._ext.nscount; ns++) {
+        if (statp->_u._ext.nssocks[ns] != -1) {
+            (void) close(statp->_u._ext.nssocks[ns]);
+            statp->_u._ext.nssocks[ns] = -1;
+        }
+    }
+}
+
+void res_ndestroy(res_state statp) {
+    res_nclose(statp);
+    if (statp->_u._ext.ext != NULL) free(statp->_u._ext.ext);
+    statp->options &= ~RES_INIT;
+    statp->_u._ext.ext = NULL;
+}
+
+void res_setservers(res_state statp, const sockaddr_union* set, int cnt) {
+    int i, nserv;
+    size_t size;
+
+    /* close open servers */
+    res_nclose(statp);
+
+    /* cause rtt times to be forgotten */
+    statp->_u._ext.nscount = 0;
+
+    nserv = 0;
+    for (i = 0; i < cnt && nserv < MAXNS; i++) {
+        switch (set->sin.sin_family) {
+            case AF_INET:
+                size = sizeof(set->sin);
+                if (statp->_u._ext.ext)
+                    memcpy(&statp->_u._ext.ext->nsaddrs[nserv], &set->sin, size);
+                if (size <= sizeof(statp->nsaddr_list[nserv]))
+                    memcpy(&statp->nsaddr_list[nserv], &set->sin, size);
+                else
+                    statp->nsaddr_list[nserv].sin_family = 0;
+                nserv++;
+                break;
+
+#ifdef HAS_INET6_STRUCTS
+            case AF_INET6:
+                size = sizeof(set->sin6);
+                if (statp->_u._ext.ext)
+                    memcpy(&statp->_u._ext.ext->nsaddrs[nserv], &set->sin6, size);
+                if (size <= sizeof(statp->nsaddr_list[nserv]))
+                    memcpy(&statp->nsaddr_list[nserv], &set->sin6, size);
+                else
+                    statp->nsaddr_list[nserv].sin_family = 0;
+                nserv++;
+                break;
+#endif
+
+            default:
+                break;
+        }
+        set++;
+    }
+    statp->nscount = nserv;
+}
+
+int res_getservers(res_state statp, sockaddr_union* set, int cnt) {
+    int i;
+    size_t size;
+    uint16_t family;
+
+    for (i = 0; i < statp->nscount && i < cnt; i++) {
+        if (statp->_u._ext.ext)
+            family = statp->_u._ext.ext->nsaddrs[i].sin.sin_family;
+        else
+            family = statp->nsaddr_list[i].sin_family;
+
+        switch (family) {
+            case AF_INET:
+                size = sizeof(set->sin);
+                if (statp->_u._ext.ext)
+                    memcpy(&set->sin, &statp->_u._ext.ext->nsaddrs[i], size);
+                else
+                    memcpy(&set->sin, &statp->nsaddr_list[i], size);
+                break;
+
+#ifdef HAS_INET6_STRUCTS
+            case AF_INET6:
+                size = sizeof(set->sin6);
+                if (statp->_u._ext.ext)
+                    memcpy(&set->sin6, &statp->_u._ext.ext->nsaddrs[i], size);
+                else
+                    memcpy(&set->sin6, &statp->nsaddr_list[i], size);
+                break;
+#endif
+
+            default:
+                set->sin.sin_family = 0;
+                break;
+        }
+        set++;
+    }
+    return (statp->nscount);
+}
+
+void res_setnetcontext(res_state statp, const struct android_net_context* netcontext,
+                       android::net::NetworkDnsEventReported* _Nonnull event) {
+    if (statp != NULL) {
+        statp->netid = netcontext->dns_netid;
+        statp->_mark = netcontext->dns_mark;
+        if (netcontext->flags & NET_CONTEXT_FLAG_USE_EDNS) {
+            statp->options |= RES_USE_EDNS0 | RES_USE_DNSSEC;
+        }
+        if (netcontext->flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) {
+            statp->use_local_nameserver = true;
+        }
+        statp->event = event;
+    }
+}
diff --git a/resolv/res_mkquery.cpp b/resolv/res_mkquery.cpp
new file mode 100644
index 0000000..2371c7e
--- /dev/null
+++ b/resolv/res_mkquery.cpp
@@ -0,0 +1,250 @@
+/*	$NetBSD: res_mkquery.c,v 1.6 2006/01/24 17:40:32 christos Exp $	*/
+
+/*
+ * Copyright (c) 1985, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define LOG_TAG "res_mkquery"
+
+#include <algorithm>  // std::min()
+
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <android-base/logging.h>
+
+#include "resolv_private.h"
+
+// Queries will be padded to a multiple of this length when EDNS0 is active.
+constexpr uint16_t kEdns0Padding = 128;
+
+extern const char* const _res_opcodes[] = {
+        "QUERY",  "IQUERY", "CQUERYM", "CQUERYU", /* experimental */
+        "NOTIFY",                                 /* experimental */
+        "UPDATE", "6",      "7",       "8",        "9",       "10",
+        "11",     "12",     "13",      "ZONEINIT", "ZONEREF",
+};
+
+/*
+ * Form all types of queries.
+ * Returns the size of the result or -1.
+ */
+int res_nmkquery(res_state statp, int op,    /* opcode of query */
+                 const char* dname,          /* domain name */
+                 int cl, int type,           /* class and type of query */
+                 const u_char* data,         /* resource record data */
+                 int datalen,                /* length of data */
+                 const u_char* /*newrr_in*/, /* new rr for modify or append */
+                 u_char* buf,                /* buffer to put query */
+                 int buflen)                 /* size of buffer */
+{
+    HEADER* hp;
+    u_char *cp, *ep;
+    int n;
+    u_char *dnptrs[20], **dpp, **lastdnptr;
+
+    LOG(DEBUG) << __func__ << ": (" << _res_opcodes[op] << ", " << p_class(cl) << ", "
+               << p_type(type) << ")";
+
+    /*
+     * Initialize header fields.
+     */
+    if ((buf == NULL) || (buflen < HFIXEDSZ)) return (-1);
+    memset(buf, 0, HFIXEDSZ);
+    hp = (HEADER*) (void*) buf;
+    hp->id = htons(arc4random_uniform(65536));
+    hp->opcode = op;
+    hp->rd = (statp->options & RES_RECURSE) != 0U;
+    hp->ad = (statp->options & RES_USE_DNSSEC) != 0U;
+    hp->rcode = NOERROR;
+    cp = buf + HFIXEDSZ;
+    ep = buf + buflen;
+    dpp = dnptrs;
+    *dpp++ = buf;
+    *dpp++ = NULL;
+    lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
+    /*
+     * perform opcode specific processing
+     */
+    switch (op) {
+        case QUERY:
+            [[fallthrough]];
+        case NS_NOTIFY_OP:
+            if (ep - cp < QFIXEDSZ) return (-1);
+            if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs, lastdnptr)) < 0) return (-1);
+            cp += n;
+            *reinterpret_cast<uint16_t*>(cp) = htons(type);
+            cp += INT16SZ;
+            *reinterpret_cast<uint16_t*>(cp) = htons(cl);
+            cp += INT16SZ;
+            hp->qdcount = htons(1);
+            if (op == QUERY || data == NULL) break;
+            /*
+             * Make an additional record for completion domain.
+             */
+            if ((ep - cp) < RRFIXEDSZ) return (-1);
+            n = dn_comp((const char*) data, cp, ep - cp - RRFIXEDSZ, dnptrs, lastdnptr);
+            if (n < 0) return (-1);
+            cp += n;
+            *reinterpret_cast<uint16_t*>(cp) = htons(ns_t_null);
+            cp += INT16SZ;
+            *reinterpret_cast<uint16_t*>(cp) = htons(cl);
+            cp += INT16SZ;
+            *reinterpret_cast<uint32_t*>(cp) = htonl(0);
+            cp += INT32SZ;
+            *reinterpret_cast<uint16_t*>(cp) = htons(0);
+            cp += INT16SZ;
+            hp->arcount = htons(1);
+            break;
+
+        case IQUERY:
+            /*
+             * Initialize answer section
+             */
+            if (ep - cp < 1 + RRFIXEDSZ + datalen) return (-1);
+            *cp++ = '\0'; /* no domain name */
+            *reinterpret_cast<uint16_t*>(cp) = htons(type);
+            cp += INT16SZ;
+            *reinterpret_cast<uint16_t*>(cp) = htons(cl);
+            cp += INT16SZ;
+            *reinterpret_cast<uint32_t*>(cp) = htonl(0);
+            cp += INT32SZ;
+            *reinterpret_cast<uint16_t*>(cp) = htons(datalen);
+            cp += INT16SZ;
+            if (datalen) {
+                memcpy(cp, data, (size_t) datalen);
+                cp += datalen;
+            }
+            hp->ancount = htons(1);
+            break;
+
+        default:
+            return (-1);
+    }
+    return (cp - buf);
+}
+
+int res_nopt(res_state statp, int n0, /* current offset in buffer */
+             u_char* buf,             /* buffer to put query */
+             int buflen,              /* size of buffer */
+             int anslen)              /* UDP answer buffer size */
+{
+    HEADER* hp;
+    u_char *cp, *ep;
+    u_int16_t flags = 0;
+
+    LOG(DEBUG) << __func__;
+
+    hp = (HEADER*) (void*) buf;
+    cp = buf + n0;
+    ep = buf + buflen;
+
+    if ((ep - cp) < 1 + RRFIXEDSZ) return (-1);
+
+    *cp++ = 0; /* "." */
+
+    // Attach OPT pseudo-RR, as documented in RFC2671 (EDNS0).
+    *reinterpret_cast<uint16_t*>(cp) = htons(ns_t_opt); /* TYPE */
+    cp += INT16SZ;
+    if (anslen > 0xffff) anslen = 0xffff;
+    *reinterpret_cast<uint16_t*>(cp) = htons(anslen); /* CLASS = UDP payload size */
+    cp += INT16SZ;
+    *cp++ = NOERROR; /* extended RCODE */
+    *cp++ = 0;       /* EDNS version */
+    if (statp->options & RES_USE_DNSSEC) {
+        LOG(DEBUG) << __func__ << ": ENDS0 DNSSEC";
+        flags |= NS_OPT_DNSSEC_OK;
+    }
+    *reinterpret_cast<uint16_t*>(cp) = htons(flags);
+    cp += INT16SZ;
+
+    // EDNS0 padding
+    const uint16_t minlen = static_cast<uint16_t>(cp - buf) + 3 * INT16SZ;
+    const uint16_t extra = minlen % kEdns0Padding;
+    uint16_t padlen = (kEdns0Padding - extra) % kEdns0Padding;
+    if (minlen > buflen) {
+        return -1;
+    }
+    padlen = std::min(padlen, static_cast<uint16_t>(buflen - minlen));
+    *reinterpret_cast<uint16_t*>(cp) = htons(padlen + 2 * INT16SZ); /* RDLEN */
+    cp += INT16SZ;
+    *reinterpret_cast<uint16_t*>(cp) = htons(NS_OPT_PADDING); /* OPTION-CODE */
+    cp += INT16SZ;
+    *reinterpret_cast<uint16_t*>(cp) = htons(padlen); /* OPTION-LENGTH */
+    cp += INT16SZ;
+    memset(cp, 0, padlen);
+    cp += padlen;
+
+    hp->arcount = htons(ntohs(hp->arcount) + 1);
+    return (cp - buf);
+}
diff --git a/resolv/res_query.cpp b/resolv/res_query.cpp
new file mode 100644
index 0000000..fbbcc31
--- /dev/null
+++ b/resolv/res_query.cpp
@@ -0,0 +1,380 @@
+/*	$NetBSD: res_query.c,v 1.7 2006/01/24 17:41:25 christos Exp $	*/
+
+/*
+ * Copyright (c) 1988, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define LOG_TAG "res_query"
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+
+#include "resolv_cache.h"
+#include "resolv_private.h"
+
+#if PACKETSZ > 1024
+#define MAXPACKET PACKETSZ
+#else
+#define MAXPACKET 1024
+#endif
+
+/*
+ * Formulate a normal query, send, and await answer.
+ * Returned answer is placed in supplied buffer "answer".
+ * Perform preliminary check of answer, returning success only
+ * if no error is indicated and the answer count is nonzero.
+ * Return the size of the response on success, -1 on error.
+ * Error number is left in *herrno.
+ *
+ * Caller must parse answer and determine whether it answers the question.
+ */
+int res_nquery(res_state statp, const char* name,  // domain name
+               int cl, int type,                   // class and type of query
+               u_char* answer,                     // buffer to put answer
+               int anslen,                         // size of answer buffer
+               int* herrno)                        // legacy and extended h_errno
+                                                   // NETD_RESOLV_H_ERRNO_EXT_*
+{
+    u_char buf[MAXPACKET];
+    HEADER* hp = (HEADER*) (void*) answer;
+    int n;
+    int rcode = NOERROR;
+    bool retried = false;
+
+again:
+    hp->rcode = NOERROR; /* default */
+
+    LOG(DEBUG) << __func__ << ": (" << cl << ", " << type << ")";
+
+    n = res_nmkquery(statp, QUERY, name, cl, type, NULL, 0, NULL, buf, sizeof(buf));
+    if (n > 0 && (statp->options & (RES_USE_EDNS0 | RES_USE_DNSSEC)) != 0U && !retried)
+        n = res_nopt(statp, n, buf, sizeof(buf), anslen);
+    if (n <= 0) {
+        LOG(DEBUG) << __func__ << ": mkquery failed";
+        *herrno = NO_RECOVERY;
+        return n;
+    }
+    n = res_nsend(statp, buf, n, answer, anslen, &rcode, 0);
+    if (n < 0) {
+        /* if the query choked with EDNS0, retry without EDNS0 */
+        if ((statp->options & (RES_USE_EDNS0 | RES_USE_DNSSEC)) != 0U &&
+            (statp->_flags & RES_F_EDNS0ERR) && !retried) {
+            LOG(DEBUG) << __func__ << ": retry without EDNS0";
+            retried = true;
+            goto again;
+        }
+        LOG(DEBUG) << __func__ << ": send error";
+
+        // Note that rcodes SERVFAIL, NOTIMP, REFUSED may cause res_nquery() to return a general
+        // error code EAI_AGAIN, but mapping the error code from rcode as res_queryN() does for
+        // getaddrinfo(). Different rcodes trigger different behaviors:
+        //
+        // - SERVFAIL, NOTIMP, REFUSED
+        //   These result in send_dg() returning 0, causing res_nsend() to try the next
+        //   nameserver. After all nameservers failed, res_nsend() returns -ETIMEDOUT, causing
+        //   res_nquery() to return EAI_AGAIN here regardless of the rcode from the DNS response.
+        //
+        // - NXDOMAIN, FORMERR
+        //   These rcodes may cause res_nsend() to return successfully (i.e. the result is a
+        //   positive integer). In this case, res_nquery() returns error number by referring
+        //   the rcode from the DNS response.
+        switch (rcode) {
+            case RCODE_TIMEOUT:  // Not defined in RFC.
+                // DNS metrics monitors DNS query timeout.
+                *herrno = NETD_RESOLV_H_ERRNO_EXT_TIMEOUT;  // extended h_errno.
+                break;
+            default:
+                *herrno = TRY_AGAIN;
+                break;
+        }
+        return n;
+    }
+
+    if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
+        LOG(DEBUG) << __func__ << ": rcode = (" << p_rcode(hp->rcode)
+                   << "), counts = an:" << ntohs(hp->ancount) << " ns:" << ntohs(hp->nscount)
+                   << " ar:" << ntohs(hp->arcount);
+
+        switch (hp->rcode) {
+            case NXDOMAIN:
+                *herrno = HOST_NOT_FOUND;
+                break;
+            case SERVFAIL:
+                *herrno = TRY_AGAIN;
+                break;
+            case NOERROR:
+                *herrno = NO_DATA;
+                break;
+            case FORMERR:
+            case NOTIMP:
+            case REFUSED:
+            default:
+                *herrno = NO_RECOVERY;
+                break;
+        }
+        return -1;
+    }
+    return n;
+}
+
+/*
+ * Formulate a normal query, send, and retrieve answer in supplied buffer.
+ * Return the size of the response on success, -1 on error.
+ * If enabled, implement search rules until answer or unrecoverable failure
+ * is detected.  Error code, if any, is left in *herrno.
+ */
+int res_nsearch(res_state statp, const char* name, /* domain name */
+                int cl, int type,                  /* class and type of query */
+                u_char* answer,                    /* buffer to put answer */
+                int anslen,                        /* size of answer */
+                int* herrno)                       /* legacy and extended
+                                                      h_errno NETD_RESOLV_H_ERRNO_EXT_* */
+{
+    const char *cp, *const *domain;
+    HEADER* hp = (HEADER*) (void*) answer;
+    u_int dots;
+    int trailing_dot, ret, saved_herrno;
+    int got_nodata = 0, got_servfail = 0, root_on_list = 0;
+    int tried_as_is = 0;
+    int searched = 0;
+
+    errno = 0;
+    *herrno = HOST_NOT_FOUND; /* True if we never query. */
+
+    dots = 0;
+    for (cp = name; *cp != '\0'; cp++) dots += (*cp == '.');
+    trailing_dot = 0;
+    if (cp > name && *--cp == '.') trailing_dot++;
+
+    /*
+     * If there are enough dots in the name, let's just give it a
+     * try 'as is'. The threshold can be set with the "ndots" option.
+     * Also, query 'as is', if there is a trailing dot in the name.
+     */
+    saved_herrno = -1;
+    if (dots >= statp->ndots || trailing_dot) {
+        ret = res_nquerydomain(statp, name, NULL, cl, type, answer, anslen, herrno);
+        if (ret > 0 || trailing_dot) return ret;
+        saved_herrno = *herrno;
+        tried_as_is++;
+    }
+
+    /*
+     * We do at least one level of search if
+     *	- there is no dot and RES_DEFNAME is set, or
+     *	- there is at least one dot, there is no trailing dot,
+     *	  and RES_DNSRCH is set.
+     */
+    if ((!dots && (statp->options & RES_DEFNAMES) != 0U) ||
+        (dots && !trailing_dot && (statp->options & RES_DNSRCH) != 0U)) {
+        int done = 0;
+
+        /* Unfortunately we need to load network-specific info
+         * (dns servers, search domains) before
+         * the domain stuff is tried.  Will have a better
+         * fix after thread pools are used as this will
+         * be loaded once for the thread instead of each
+         * time a query is tried.
+         */
+        _resolv_populate_res_for_net(statp);
+
+        for (domain = (const char* const*) statp->dnsrch; *domain && !done; domain++) {
+            searched = 1;
+
+            if (domain[0][0] == '\0' || (domain[0][0] == '.' && domain[0][1] == '\0'))
+                root_on_list++;
+
+            ret = res_nquerydomain(statp, name, *domain, cl, type, answer, anslen, herrno);
+            if (ret > 0) return ret;
+
+            /*
+             * If no server present, give up.
+             * If name isn't found in this domain,
+             * keep trying higher domains in the search list
+             * (if that's enabled).
+             * On a NO_DATA error, keep trying, otherwise
+             * a wildcard entry of another type could keep us
+             * from finding this entry higher in the domain.
+             * If we get some other error (negative answer or
+             * server failure), then stop searching up,
+             * but try the input name below in case it's
+             * fully-qualified.
+             */
+            if (errno == ECONNREFUSED) {
+                *herrno = TRY_AGAIN;
+                return -1;
+            }
+
+            switch (*herrno) {
+                case NO_DATA:
+                    got_nodata++;
+                    break;
+                case HOST_NOT_FOUND:
+                    /* keep trying */
+                    break;
+                case TRY_AGAIN:
+                    if (hp->rcode == SERVFAIL) {
+                        /* try next search element, if any */
+                        got_servfail++;
+                        break;
+                    }
+                    [[fallthrough]];
+                default:
+                    /* anything else implies that we're done */
+                    done++;
+            }
+
+            /* if we got here for some reason other than DNSRCH,
+             * we only wanted one iteration of the loop, so stop.
+             */
+            if ((statp->options & RES_DNSRCH) == 0U) done++;
+        }
+    }
+
+    /*
+     * If the query has not already been tried as is then try it
+     * unless RES_NOTLDQUERY is set and there were no dots.
+     */
+    if ((dots || !searched || (statp->options & RES_NOTLDQUERY) == 0U) &&
+        !(tried_as_is || root_on_list)) {
+        ret = res_nquerydomain(statp, name, NULL, cl, type, answer, anslen, herrno);
+        if (ret > 0) return ret;
+    }
+
+    /* if we got here, we didn't satisfy the search.
+     * if we did an initial full query, return that query's H_ERRNO
+     * (note that we wouldn't be here if that query had succeeded).
+     * else if we ever got a nodata, send that back as the reason.
+     * else send back meaningless H_ERRNO, that being the one from
+     * the last DNSRCH we did.
+     */
+    if (saved_herrno != -1)
+        *herrno = saved_herrno;
+    else if (got_nodata)
+        *herrno = NO_DATA;
+    else if (got_servfail)
+        *herrno = TRY_AGAIN;
+    return -1;
+}
+
+/*
+ * Perform a call on res_query on the concatenation of name and domain,
+ * removing a trailing dot from name if domain is NULL.
+ */
+int res_nquerydomain(res_state statp, const char* name, const char* domain, int cl,
+                     int type,       /* class and type of query */
+                     u_char* answer, /* buffer to put answer */
+                     int anslen,     /* size of answer */
+                     int* herrno)    /* legacy and extended h_errno NETD_RESOLV_H_ERRNO_EXT_* */
+{
+    char nbuf[MAXDNAME];
+    const char* longname = nbuf;
+    int n, d;
+
+    if (domain == NULL) {
+        LOG(DEBUG) << __func__ << ": (null, " << cl << ", " << type << ")";
+        /*
+         * Check for trailing '.';
+         * copy without '.' if present.
+         */
+        n = strlen(name);
+        if (n >= MAXDNAME) {
+            *herrno = NO_RECOVERY;
+            return -1;
+        }
+        n--;
+        if (n >= 0 && name[n] == '.') {
+            strncpy(nbuf, name, (size_t) n);
+            nbuf[n] = '\0';
+        } else
+            longname = name;
+    } else {
+        LOG(DEBUG) << __func__ << ": (" << cl << ", " << type << ")";
+        n = strlen(name);
+        d = strlen(domain);
+        if (n + d + 1 >= MAXDNAME) {
+            *herrno = NO_RECOVERY;
+            return -1;
+        }
+        snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
+    }
+    return res_nquery(statp, longname, cl, type, answer, anslen, herrno);
+}
diff --git a/resolv/res_send.cpp b/resolv/res_send.cpp
new file mode 100644
index 0000000..1ccfc74
--- /dev/null
+++ b/resolv/res_send.cpp
@@ -0,0 +1,1372 @@
+/*	$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $	*/
+
+/*
+ * Copyright (c) 1985, 1989, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Send query to name server and wait for reply.
+ */
+
+#define LOG_TAG "res_send"
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netinet/in.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android/multinetwork.h>  // ResNsendFlags
+
+#include <netdutils/Slice.h>
+#include <netdutils/Stopwatch.h>
+#include "DnsTlsDispatcher.h"
+#include "DnsTlsTransport.h"
+#include "PrivateDnsConfiguration.h"
+#include "netd_resolv/resolv.h"
+#include "netd_resolv/stats.h"
+#include "private/android_filesystem_config.h"
+#include "res_state_ext.h"
+#include "resolv_cache.h"
+#include "resolv_private.h"
+#include "stats.pb.h"
+
+// TODO: use the namespace something like android::netd_resolv for libnetd_resolv
+using namespace android::net;
+using android::net::NetworkDnsEventReported;
+using android::netdutils::Slice;
+using android::netdutils::Stopwatch;
+
+static DnsTlsDispatcher sDnsTlsDispatcher;
+
+static int get_salen(const struct sockaddr*);
+static struct sockaddr* get_nsaddr(res_state, size_t);
+static int send_vc(res_state, res_params* params, const u_char*, int, u_char*, int, int*, int,
+                   time_t*, int*, int*);
+static int send_dg(res_state, res_params* params, const u_char*, int, u_char*, int, int*, int, int*,
+                   int*, time_t*, int*, int*);
+static void Aerror(const res_state, const char*, int, const struct sockaddr*, int);
+static void Perror(const res_state, const char*, int);
+
+static int sock_eq(struct sockaddr*, struct sockaddr*);
+static int connect_with_timeout(int sock, const struct sockaddr* nsap, socklen_t salen,
+                                const struct timespec timeout);
+static int retrying_poll(const int sock, short events, const struct timespec* finish);
+static int res_tls_send(res_state, const Slice query, const Slice answer, int* rcode,
+                        bool* fallback);
+
+NsType getQueryType(const uint8_t* msg, size_t msgLen) {
+    ns_msg handle;
+    ns_rr rr;
+    if (ns_initparse((const uint8_t*)msg, msgLen, &handle) < 0 ||
+        ns_parserr(&handle, ns_s_qd, 0, &rr) < 0) {
+        return NS_T_INVALID;
+    }
+    return static_cast<NsType>(ns_rr_type(rr));
+}
+
+IpVersion ipFamilyToIPVersion(const int ipFamily) {
+    switch (ipFamily) {
+        case AF_INET:
+            return IV_IPV4;
+        case AF_INET6:
+            return IV_IPV6;
+        default:
+            return IV_UNKNOWN;
+    }
+}
+
+// BEGIN: Code copied from ISC eventlib
+// TODO: move away from this code
+#define BILLION 1000000000
+
+static struct timespec evConsTime(time_t sec, long nsec) {
+    struct timespec x;
+
+    x.tv_sec = sec;
+    x.tv_nsec = nsec;
+    return (x);
+}
+
+static struct timespec evAddTime(struct timespec addend1, struct timespec addend2) {
+    struct timespec x;
+
+    x.tv_sec = addend1.tv_sec + addend2.tv_sec;
+    x.tv_nsec = addend1.tv_nsec + addend2.tv_nsec;
+    if (x.tv_nsec >= BILLION) {
+        x.tv_sec++;
+        x.tv_nsec -= BILLION;
+    }
+    return (x);
+}
+
+static struct timespec evSubTime(struct timespec minuend, struct timespec subtrahend) {
+    struct timespec x;
+
+    x.tv_sec = minuend.tv_sec - subtrahend.tv_sec;
+    if (minuend.tv_nsec >= subtrahend.tv_nsec)
+        x.tv_nsec = minuend.tv_nsec - subtrahend.tv_nsec;
+    else {
+        x.tv_nsec = BILLION - subtrahend.tv_nsec + minuend.tv_nsec;
+        x.tv_sec--;
+    }
+    return (x);
+}
+
+static int evCmpTime(struct timespec a, struct timespec b) {
+#define SGN(x) ((x) < 0 ? (-1) : (x) > 0 ? (1) : (0));
+    time_t s = a.tv_sec - b.tv_sec;
+    long n;
+
+    if (s != 0) return SGN(s);
+
+    n = a.tv_nsec - b.tv_nsec;
+    return SGN(n);
+}
+
+static struct timespec evNowTime(void) {
+    struct timespec tsnow;
+    clock_gettime(CLOCK_REALTIME, &tsnow);
+    return tsnow;
+}
+
+static struct iovec evConsIovec(void* buf, size_t cnt) {
+    struct iovec ret;
+
+    memset(&ret, 0xf5, sizeof ret);
+    ret.iov_base = buf;
+    ret.iov_len = cnt;
+    return ret;
+}
+
+// END: Code copied from ISC eventlib
+
+/* BIONIC-BEGIN: implement source port randomization */
+static int random_bind(int s, int family) {
+    sockaddr_union u;
+    int j;
+    socklen_t slen;
+
+    /* clear all, this also sets the IP4/6 address to 'any' */
+    memset(&u, 0, sizeof u);
+
+    switch (family) {
+        case AF_INET:
+            u.sin.sin_family = family;
+            slen = sizeof u.sin;
+            break;
+        case AF_INET6:
+            u.sin6.sin6_family = family;
+            slen = sizeof u.sin6;
+            break;
+        default:
+            errno = EPROTO;
+            return -1;
+    }
+
+    /* first try to bind to a random source port a few times */
+    for (j = 0; j < 10; j++) {
+        /* find a random port between 1025 .. 65534 */
+        int port = 1025 + (arc4random_uniform(65535 - 1025));
+        if (family == AF_INET)
+            u.sin.sin_port = htons(port);
+        else
+            u.sin6.sin6_port = htons(port);
+
+        if (!bind(s, &u.sa, slen)) return 0;
+    }
+
+    // nothing after 10 attempts, our network table is probably busy
+    // let the system decide which port is best
+    if (family == AF_INET)
+        u.sin.sin_port = 0;
+    else
+        u.sin6.sin6_port = 0;
+
+    return bind(s, &u.sa, slen);
+}
+/* BIONIC-END */
+
+// Disables all nameservers other than selectedServer
+static void res_set_usable_server(int selectedServer, int nscount, bool usable_servers[]) {
+    int usableIndex = 0;
+    for (int ns = 0; ns < nscount; ns++) {
+        if (usable_servers[ns]) ++usableIndex;
+        if (usableIndex != selectedServer) usable_servers[ns] = false;
+    }
+}
+
+/* int
+ * res_isourserver(ina)
+ *	looks up "ina" in _res.ns_addr_list[]
+ * returns:
+ *	0  : not found
+ *	>0 : found
+ * author:
+ *	paul vixie, 29may94
+ */
+static int res_ourserver_p(const res_state statp, const sockaddr* sa) {
+    const sockaddr_in *inp, *srv;
+    const sockaddr_in6 *in6p, *srv6;
+    int ns;
+
+    switch (sa->sa_family) {
+        case AF_INET:
+            inp = (const struct sockaddr_in*) (const void*) sa;
+            for (ns = 0; ns < statp->nscount; ns++) {
+                srv = (struct sockaddr_in*) (void*) get_nsaddr(statp, (size_t) ns);
+                if (srv->sin_family == inp->sin_family && srv->sin_port == inp->sin_port &&
+                    (srv->sin_addr.s_addr == INADDR_ANY ||
+                     srv->sin_addr.s_addr == inp->sin_addr.s_addr))
+                    return 1;
+            }
+            break;
+        case AF_INET6:
+            if (statp->_u._ext.ext == NULL) break;
+            in6p = (const struct sockaddr_in6*) (const void*) sa;
+            for (ns = 0; ns < statp->nscount; ns++) {
+                srv6 = (struct sockaddr_in6*) (void*) get_nsaddr(statp, (size_t) ns);
+                if (srv6->sin6_family == in6p->sin6_family && srv6->sin6_port == in6p->sin6_port &&
+#ifdef HAVE_SIN6_SCOPE_ID
+                    (srv6->sin6_scope_id == 0 || srv6->sin6_scope_id == in6p->sin6_scope_id) &&
+#endif
+                    (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
+                     IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr)))
+                    return 1;
+            }
+            break;
+        default:
+            break;
+    }
+    return 0;
+}
+
+/* int
+ * res_nameinquery(name, type, cl, buf, eom)
+ *	look for (name, type, cl) in the query section of packet (buf, eom)
+ * requires:
+ *	buf + HFIXEDSZ <= eom
+ * returns:
+ *	-1 : format error
+ *	0  : not found
+ *	>0 : found
+ * author:
+ *	paul vixie, 29may94
+ */
+int res_nameinquery(const char* name, int type, int cl, const u_char* buf, const u_char* eom) {
+    const u_char* cp = buf + HFIXEDSZ;
+    int qdcount = ntohs(((const HEADER*) (const void*) buf)->qdcount);
+
+    while (qdcount-- > 0) {
+        char tname[MAXDNAME + 1];
+        int n = dn_expand(buf, eom, cp, tname, sizeof tname);
+        if (n < 0) return (-1);
+        cp += n;
+        if (cp + 2 * INT16SZ > eom) return (-1);
+        int ttype = ntohs(*reinterpret_cast<const uint16_t*>(cp));
+        cp += INT16SZ;
+        int tclass = ntohs(*reinterpret_cast<const uint16_t*>(cp));
+        cp += INT16SZ;
+        if (ttype == type && tclass == cl && ns_samename(tname, name) == 1) return (1);
+    }
+    return (0);
+}
+
+/* int
+ * res_queriesmatch(buf1, eom1, buf2, eom2)
+ *	is there a 1:1 mapping of (name,type,class)
+ *	in (buf1,eom1) and (buf2,eom2)?
+ * returns:
+ *	-1 : format error
+ *	0  : not a 1:1 mapping
+ *	>0 : is a 1:1 mapping
+ * author:
+ *	paul vixie, 29may94
+ */
+int res_queriesmatch(const u_char* buf1, const u_char* eom1, const u_char* buf2,
+                     const u_char* eom2) {
+    const u_char* cp = buf1 + HFIXEDSZ;
+    int qdcount = ntohs(((const HEADER*) (const void*) buf1)->qdcount);
+
+    if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) return (-1);
+
+    /*
+     * Only header section present in replies to
+     * dynamic update packets.
+     */
+    if ((((const HEADER*) (const void*) buf1)->opcode == ns_o_update) &&
+        (((const HEADER*) (const void*) buf2)->opcode == ns_o_update))
+        return (1);
+
+    if (qdcount != ntohs(((const HEADER*) (const void*) buf2)->qdcount)) return (0);
+    while (qdcount-- > 0) {
+        char tname[MAXDNAME + 1];
+        int n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
+        if (n < 0) return (-1);
+        cp += n;
+        if (cp + 2 * INT16SZ > eom1) return (-1);
+        int ttype = ntohs(*reinterpret_cast<const uint16_t*>(cp));
+        cp += INT16SZ;
+        int tclass = ntohs(*reinterpret_cast<const uint16_t*>(cp));
+        cp += INT16SZ;
+        if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) return (0);
+    }
+    return (1);
+}
+
+static DnsQueryEvent* addDnsQueryEvent(NetworkDnsEventReported* event) {
+    return event->mutable_dns_query_events()->add_dns_query_event();
+}
+
+int res_nsend(res_state statp, const u_char* buf, int buflen, u_char* ans, int anssiz, int* rcode,
+              uint32_t flags) {
+    int gotsomewhere, terrno, v_circuit, resplen, n;
+    ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED;
+
+    if (anssiz < HFIXEDSZ) {
+        // TODO: Remove errno once callers stop using it
+        errno = EINVAL;
+        return -EINVAL;
+    }
+    LOG(DEBUG) << __func__;
+    res_pquery(buf, buflen);
+
+    v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ;
+    gotsomewhere = 0;
+    terrno = ETIMEDOUT;
+
+    int anslen = 0;
+    Stopwatch cache_stopwatch;
+    cache_status = _resolv_cache_lookup(statp->netid, buf, buflen, ans, anssiz, &anslen, flags);
+    const int32_t cacheLatencyUs = saturate_cast<int32_t>(cache_stopwatch.timeTakenUs());
+    if (cache_status == RESOLV_CACHE_FOUND) {
+        HEADER* hp = (HEADER*)(void*)ans;
+        *rcode = hp->rcode;
+        DnsQueryEvent* dnsQueryEvent = addDnsQueryEvent(statp->event);
+        dnsQueryEvent->set_latency_micros(cacheLatencyUs);
+        dnsQueryEvent->set_cache_hit(static_cast<CacheStatus>(cache_status));
+        return anslen;
+    } else if (cache_status != RESOLV_CACHE_UNSUPPORTED) {
+        // had a cache miss for a known network, so populate the thread private
+        // data so the normal resolve path can do its thing
+        _resolv_populate_res_for_net(statp);
+    }
+    if (statp->nscount == 0) {
+        // We have no nameservers configured, so there's no point trying.
+        // Tell the cache the query failed, or any retries and anyone else asking the same
+        // question will block for PENDING_REQUEST_TIMEOUT seconds instead of failing fast.
+        _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
+
+        // TODO: Remove errno once callers stop using it
+        errno = ESRCH;
+        return -ESRCH;
+    }
+
+    /*
+     * If the ns_addr_list in the resolver context has changed, then
+     * invalidate our cached copy and the associated timing data.
+     */
+    if (statp->_u._ext.nscount != 0) {
+        int needclose = 0;
+        struct sockaddr_storage peer;
+        socklen_t peerlen;
+
+        if (statp->_u._ext.nscount != statp->nscount) {
+            needclose++;
+        } else {
+            for (int ns = 0; ns < statp->nscount; ns++) {
+                if (statp->nsaddr_list[ns].sin_family &&
+                    !sock_eq((struct sockaddr*) (void*) &statp->nsaddr_list[ns],
+                             (struct sockaddr*) (void*) &statp->_u._ext.ext->nsaddrs[ns])) {
+                    needclose++;
+                    break;
+                }
+
+                if (statp->_u._ext.nssocks[ns] == -1) continue;
+                peerlen = sizeof(peer);
+                if (getpeername(statp->_u._ext.nssocks[ns], (struct sockaddr*) (void*) &peer,
+                                &peerlen) < 0) {
+                    needclose++;
+                    break;
+                }
+                if (!sock_eq((struct sockaddr*) (void*) &peer, get_nsaddr(statp, (size_t) ns))) {
+                    needclose++;
+                    break;
+                }
+            }
+        }
+        if (needclose) {
+            res_nclose(statp);
+            statp->_u._ext.nscount = 0;
+        }
+    }
+
+    /*
+     * Maybe initialize our private copy of the ns_addr_list.
+     */
+    if (statp->_u._ext.nscount == 0) {
+        for (int ns = 0; ns < statp->nscount; ns++) {
+            statp->_u._ext.nstimes[ns] = RES_MAXTIME;
+            statp->_u._ext.nssocks[ns] = -1;
+            if (!statp->nsaddr_list[ns].sin_family) continue;
+            statp->_u._ext.ext->nsaddrs[ns].sin = statp->nsaddr_list[ns];
+        }
+        statp->_u._ext.nscount = statp->nscount;
+    }
+
+    /*
+     * Some resolvers want to even out the load on their nameservers.
+     * Note that RES_BLAST overrides RES_ROTATE.
+     */
+    if ((statp->options & RES_ROTATE) != 0U && (statp->options & RES_BLAST) == 0U) {
+        sockaddr_union inu;
+        struct sockaddr_in ina;
+        int lastns = statp->nscount - 1;
+        int fd;
+        u_int16_t nstime;
+
+        if (statp->_u._ext.ext != NULL) inu = statp->_u._ext.ext->nsaddrs[0];
+        ina = statp->nsaddr_list[0];
+        fd = statp->_u._ext.nssocks[0];
+        nstime = statp->_u._ext.nstimes[0];
+        for (int ns = 0; ns < lastns; ns++) {
+            if (statp->_u._ext.ext != NULL)
+                statp->_u._ext.ext->nsaddrs[ns] = statp->_u._ext.ext->nsaddrs[ns + 1];
+            statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
+            statp->_u._ext.nssocks[ns] = statp->_u._ext.nssocks[ns + 1];
+            statp->_u._ext.nstimes[ns] = statp->_u._ext.nstimes[ns + 1];
+        }
+        if (statp->_u._ext.ext != NULL) statp->_u._ext.ext->nsaddrs[lastns] = inu;
+        statp->nsaddr_list[lastns] = ina;
+        statp->_u._ext.nssocks[lastns] = fd;
+        statp->_u._ext.nstimes[lastns] = nstime;
+    }
+
+    res_stats stats[MAXNS];
+    res_params params;
+    int revision_id = resolv_cache_get_resolver_stats(statp->netid, &params, stats);
+    if (revision_id < 0) {
+        // TODO: Remove errno once callers stop using it
+        errno = ESRCH;
+        return -ESRCH;
+    }
+    bool usable_servers[MAXNS];
+    int usableServersCount = android_net_res_stats_get_usable_servers(
+            &params, stats, statp->nscount, usable_servers);
+
+    if ((flags & ANDROID_RESOLV_NO_RETRY) && usableServersCount > 1) {
+        auto hp = reinterpret_cast<const HEADER*>(buf);
+
+        // Select a random server based on the query id
+        int selectedServer = (hp->id % usableServersCount) + 1;
+        res_set_usable_server(selectedServer, statp->nscount, usable_servers);
+    }
+
+    /*
+     * Send request, RETRY times, or until successful.
+     */
+    int retryTimes = (flags & ANDROID_RESOLV_NO_RETRY) ? 1 : params.retry_count;
+
+    for (int attempt = 0; attempt < retryTimes; ++attempt) {
+
+        for (int ns = 0; ns < statp->nscount; ns++) {
+            if (!usable_servers[ns]) continue;
+            int nsaplen;
+            time_t now = 0;
+            int delay = 0;
+            *rcode = RCODE_INTERNAL_ERROR;
+            const sockaddr* nsap = get_nsaddr(statp, ns);
+            nsaplen = get_salen(nsap);
+
+        same_ns:
+            // TODO: Since we expect there is only one DNS server being queried here while this
+            // function tries to query all of private DNS servers. Consider moving it to other
+            // reasonable place. In addition, maybe add stats for private DNS.
+            if (!statp->use_local_nameserver) {
+                bool fallback = false;
+                resplen = res_tls_send(statp, Slice(const_cast<u_char*>(buf), buflen),
+                                       Slice(ans, anssiz), rcode, &fallback);
+                if (resplen > 0) {
+                    if (cache_status == RESOLV_CACHE_NOTFOUND) {
+                        _resolv_cache_add(statp->netid, buf, buflen, ans, resplen);
+                    }
+                    return resplen;
+                }
+                if (!fallback) {
+                    _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
+                    res_nclose(statp);
+                    return -terrno;
+                }
+            }
+
+            static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
+            char abuf[NI_MAXHOST];
+            DnsQueryEvent* dnsQueryEvent = addDnsQueryEvent(statp->event);
+            dnsQueryEvent->set_cache_hit(static_cast<CacheStatus>(cache_status));
+
+            if (getnameinfo(nsap, (socklen_t)nsaplen, abuf, sizeof(abuf), NULL, 0, niflags) == 0)
+                LOG(DEBUG) << __func__ << ": Querying server (# " << ns + 1
+                           << ") address = " << abuf;
+
+            Stopwatch query_stopwatch;
+            if (v_circuit) {
+                /* Use VC; at most one attempt per server. */
+                bool shouldRecordStats = (attempt == 0);
+                attempt = retryTimes;
+
+                n = send_vc(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &now, rcode,
+                            &delay);
+
+                dnsQueryEvent->set_latency_micros(
+                        saturate_cast<int32_t>(query_stopwatch.timeTakenUs()));
+                dnsQueryEvent->set_dns_server_index(ns);
+                dnsQueryEvent->set_ip_version(ipFamilyToIPVersion(nsap->sa_family));
+                dnsQueryEvent->set_retry_times(attempt);
+                dnsQueryEvent->set_rcode(static_cast<NsRcode>(*rcode));
+                dnsQueryEvent->set_protocol(PROTO_TCP);
+                dnsQueryEvent->set_type(getQueryType(buf, buflen));
+
+                /*
+                 * Only record stats the first time we try a query. This ensures that
+                 * queries that deterministically fail (e.g., a name that always returns
+                 * SERVFAIL or times out) do not unduly affect the stats.
+                 */
+                if (shouldRecordStats) {
+                    res_sample sample;
+                    _res_stats_set_sample(&sample, now, *rcode, delay);
+                    _resolv_cache_add_resolver_stats_sample(statp->netid, revision_id, ns, &sample,
+                                                            params.max_samples);
+                }
+
+                LOG(INFO) << __func__ << ": used send_vc " << n;
+
+                if (n < 0) {
+                    _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
+                    res_nclose(statp);
+                    return -terrno;
+                };
+                if (n == 0) goto next_ns;
+                resplen = n;
+            } else {
+                /* Use datagrams. */
+                LOG(INFO) << __func__ << ": using send_dg";
+
+                n = send_dg(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &v_circuit,
+                            &gotsomewhere, &now, rcode, &delay);
+
+                dnsQueryEvent->set_latency_micros(
+                        saturate_cast<int32_t>(query_stopwatch.timeTakenUs()));
+                dnsQueryEvent->set_dns_server_index(ns);
+                dnsQueryEvent->set_ip_version(ipFamilyToIPVersion(nsap->sa_family));
+                dnsQueryEvent->set_retry_times(attempt);
+                dnsQueryEvent->set_rcode(static_cast<NsRcode>(*rcode));
+                dnsQueryEvent->set_protocol(PROTO_UDP);
+                dnsQueryEvent->set_type(getQueryType(buf, buflen));
+
+                /* Only record stats the first time we try a query. See above. */
+                if (attempt == 0) {
+                    res_sample sample;
+                    _res_stats_set_sample(&sample, now, *rcode, delay);
+                    _resolv_cache_add_resolver_stats_sample(statp->netid, revision_id, ns, &sample,
+                                                            params.max_samples);
+                }
+
+                LOG(INFO) << __func__ << ": used send_dg " << n;
+
+                if (n < 0) {
+                    _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
+                    res_nclose(statp);
+                    return -terrno;
+                };
+                if (n == 0) goto next_ns;
+                if (v_circuit) goto same_ns;
+                resplen = n;
+            }
+
+            LOG(DEBUG) << __func__ << ": got answer:";
+            res_pquery(ans, (resplen > anssiz) ? anssiz : resplen);
+
+            if (cache_status == RESOLV_CACHE_NOTFOUND) {
+                _resolv_cache_add(statp->netid, buf, buflen, ans, resplen);
+            }
+            /*
+             * If we have temporarily opened a virtual circuit,
+             * or if we haven't been asked to keep a socket open,
+             * close the socket.
+             */
+            if ((v_circuit && (statp->options & RES_USEVC) == 0U) ||
+                (statp->options & RES_STAYOPEN) == 0U) {
+                res_nclose(statp);
+            }
+            return (resplen);
+        next_ns:;
+        }  // for each ns
+    }  // for each retry
+    res_nclose(statp);
+    if (!v_circuit) {
+        if (!gotsomewhere) {
+            // TODO: Remove errno once callers stop using it
+            errno = ECONNREFUSED; /* no nameservers found */
+            terrno = ECONNREFUSED;
+        } else {
+            // TODO: Remove errno once callers stop using it
+            errno = ETIMEDOUT; /* no answer obtained */
+            terrno = ETIMEDOUT;
+        }
+    } else {
+        errno = terrno;
+    }
+    _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
+    return -terrno;
+}
+
+/* Private */
+
+static int get_salen(const struct sockaddr* sa) {
+    if (sa->sa_family == AF_INET)
+        return (sizeof(struct sockaddr_in));
+    else if (sa->sa_family == AF_INET6)
+        return (sizeof(struct sockaddr_in6));
+    else
+        return (0); /* unknown, die on connect */
+}
+
+/*
+ * pick appropriate nsaddr_list for use.  see res_init() for initialization.
+ */
+static struct sockaddr* get_nsaddr(res_state statp, size_t n) {
+    if (!statp->nsaddr_list[n].sin_family && statp->_u._ext.ext) {
+        /*
+         * - statp->_u._ext.ext->nsaddrs[n] holds an address that is larger
+         *   than struct sockaddr, and
+         * - user code did not update statp->nsaddr_list[n].
+         */
+        return (struct sockaddr*) (void*) &statp->_u._ext.ext->nsaddrs[n];
+    } else {
+        /*
+         * - user code updated statp->nsaddr_list[n], or
+         * - statp->nsaddr_list[n] has the same content as
+         *   statp->_u._ext.ext->nsaddrs[n].
+         */
+        return (struct sockaddr*) (void*) &statp->nsaddr_list[n];
+    }
+}
+
+static struct timespec get_timeout(const res_state statp, const res_params* params, const int ns) {
+    int msec;
+    // Legacy algorithm which scales the timeout by nameserver number.
+    // For instance, with 4 nameservers: 5s, 2.5s, 5s, 10s
+    // This has no effect with 1 or 2 nameservers
+    msec = params->base_timeout_msec << ns;
+    if (ns > 0) {
+        msec /= statp->nscount;
+    }
+    // For safety, don't allow OEMs and experiments to configure a timeout shorter than 1s.
+    if (msec < 1000) {
+        msec = 1000;  // Use at least 1000ms
+    }
+    LOG(INFO) << __func__ << ": using timeout of " << msec << " msec";
+
+    struct timespec result;
+    result.tv_sec = msec / 1000;
+    result.tv_nsec = (msec % 1000) * 1000000;
+    return result;
+}
+
+static int send_vc(res_state statp, res_params* params, const u_char* buf, int buflen, u_char* ans,
+                   int anssiz, int* terrno, int ns, time_t* at, int* rcode, int* delay) {
+    *at = time(NULL);
+    *delay = 0;
+    const HEADER* hp = (const HEADER*) (const void*) buf;
+    HEADER* anhp = (HEADER*) (void*) ans;
+    struct sockaddr* nsap;
+    int nsaplen;
+    int truncating, connreset, n;
+    struct iovec iov[2];
+    u_char* cp;
+
+    LOG(INFO) << __func__ << ": using send_vc";
+
+    nsap = get_nsaddr(statp, (size_t) ns);
+    nsaplen = get_salen(nsap);
+
+    connreset = 0;
+same_ns:
+    truncating = 0;
+
+    struct timespec now = evNowTime();
+
+    /* Are we still talking to whom we want to talk to? */
+    if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
+        struct sockaddr_storage peer;
+        socklen_t size = sizeof peer;
+        unsigned old_mark;
+        socklen_t mark_size = sizeof(old_mark);
+        if (getpeername(statp->_vcsock, (struct sockaddr*) (void*) &peer, &size) < 0 ||
+            !sock_eq((struct sockaddr*) (void*) &peer, nsap) ||
+            getsockopt(statp->_vcsock, SOL_SOCKET, SO_MARK, &old_mark, &mark_size) < 0 ||
+            old_mark != statp->_mark) {
+            res_nclose(statp);
+            statp->_flags &= ~RES_F_VC;
+        }
+    }
+
+    if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
+        if (statp->_vcsock >= 0) res_nclose(statp);
+
+        statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0);
+        if (statp->_vcsock < 0) {
+            switch (errno) {
+                case EPROTONOSUPPORT:
+                case EPFNOSUPPORT:
+                case EAFNOSUPPORT:
+                    Perror(statp, "socket(vc)", errno);
+                    return 0;
+                default:
+                    *terrno = errno;
+                    Perror(statp, "socket(vc)", errno);
+                    return -1;
+            }
+        }
+        fchown(statp->_vcsock, AID_DNS, -1);
+        if (statp->_mark != MARK_UNSET) {
+            if (setsockopt(statp->_vcsock, SOL_SOCKET, SO_MARK, &statp->_mark,
+                           sizeof(statp->_mark)) < 0) {
+                *terrno = errno;
+                Perror(statp, "setsockopt", errno);
+                return -1;
+            }
+        }
+        errno = 0;
+        if (random_bind(statp->_vcsock, nsap->sa_family) < 0) {
+            *terrno = errno;
+            Aerror(statp, "bind/vc", errno, nsap, nsaplen);
+            res_nclose(statp);
+            return (0);
+        }
+        if (connect_with_timeout(statp->_vcsock, nsap, (socklen_t) nsaplen,
+                                 get_timeout(statp, params, ns)) < 0) {
+            *terrno = errno;
+            Aerror(statp, "connect/vc", errno, nsap, nsaplen);
+            res_nclose(statp);
+            /*
+             * The way connect_with_timeout() is implemented prevents us from reliably
+             * determining whether this was really a timeout or e.g. ECONNREFUSED. Since
+             * currently both cases are handled in the same way, there is no need to
+             * change this (yet). If we ever need to reliably distinguish between these
+             * cases, both connect_with_timeout() and retrying_poll() need to be
+             * modified, though.
+             */
+            *rcode = RCODE_TIMEOUT;
+            return (0);
+        }
+        statp->_flags |= RES_F_VC;
+    }
+
+    /*
+     * Send length & message
+     */
+    uint16_t len = htons(static_cast<uint16_t>(buflen));
+    iov[0] = evConsIovec(&len, INT16SZ);
+    iov[1] = evConsIovec((void*) buf, (size_t) buflen);
+    if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
+        *terrno = errno;
+        Perror(statp, "write failed", errno);
+        res_nclose(statp);
+        return (0);
+    }
+    /*
+     * Receive length & response
+     */
+read_len:
+    cp = ans;
+    len = INT16SZ;
+    while ((n = read(statp->_vcsock, (char*) cp, (size_t) len)) > 0) {
+        cp += n;
+        if ((len -= n) == 0) break;
+    }
+    if (n <= 0) {
+        *terrno = errno;
+        Perror(statp, "read failed", errno);
+        res_nclose(statp);
+        /*
+         * A long running process might get its TCP
+         * connection reset if the remote server was
+         * restarted.  Requery the server instead of
+         * trying a new one.  When there is only one
+         * server, this means that a query might work
+         * instead of failing.  We only allow one reset
+         * per query to prevent looping.
+         */
+        if (*terrno == ECONNRESET && !connreset) {
+            connreset = 1;
+            res_nclose(statp);
+            goto same_ns;
+        }
+        res_nclose(statp);
+        return (0);
+    }
+    uint16_t resplen = ntohs(*reinterpret_cast<const uint16_t*>(ans));
+    if (resplen > anssiz) {
+        LOG(DEBUG) << __func__ << ": response truncated";
+        truncating = 1;
+        len = anssiz;
+    } else
+        len = resplen;
+    if (len < HFIXEDSZ) {
+        /*
+         * Undersized message.
+         */
+        LOG(DEBUG) << __func__ << ": undersized: " << len;
+        *terrno = EMSGSIZE;
+        res_nclose(statp);
+        return (0);
+    }
+    cp = ans;
+    while (len != 0 && (n = read(statp->_vcsock, (char*) cp, (size_t) len)) > 0) {
+        cp += n;
+        len -= n;
+    }
+    if (n <= 0) {
+        *terrno = errno;
+        Perror(statp, "read(vc)", errno);
+        res_nclose(statp);
+        return (0);
+    }
+
+    if (truncating) {
+        /*
+         * Flush rest of answer so connection stays in synch.
+         */
+        anhp->tc = 1;
+        len = resplen - anssiz;
+        while (len != 0) {
+            char junk[PACKETSZ];
+
+            n = read(statp->_vcsock, junk, (len > sizeof junk) ? sizeof junk : len);
+            if (n > 0)
+                len -= n;
+            else
+                break;
+        }
+    }
+    /*
+     * If the calling application has bailed out of
+     * a previous call and failed to arrange to have
+     * the circuit closed or the server has got
+     * itself confused, then drop the packet and
+     * wait for the correct one.
+     */
+    if (hp->id != anhp->id) {
+        LOG(DEBUG) << __func__ << ": ld answer (unexpected):";
+        res_pquery(ans, (resplen > anssiz) ? anssiz : resplen);
+        goto read_len;
+    }
+
+    /*
+     * All is well, or the error is fatal.  Signal that the
+     * next nameserver ought not be tried.
+     */
+    if (resplen > 0) {
+        struct timespec done = evNowTime();
+        *delay = _res_stats_calculate_rtt(&done, &now);
+        *rcode = anhp->rcode;
+    }
+    return (resplen);
+}
+
+/* return -1 on error (errno set), 0 on success */
+static int connect_with_timeout(int sock, const struct sockaddr* nsap, socklen_t salen,
+                                const struct timespec timeout) {
+    int res, origflags;
+
+    origflags = fcntl(sock, F_GETFL, 0);
+    fcntl(sock, F_SETFL, origflags | O_NONBLOCK);
+
+    res = connect(sock, nsap, salen);
+    if (res < 0 && errno != EINPROGRESS) {
+        res = -1;
+        goto done;
+    }
+    if (res != 0) {
+        struct timespec now = evNowTime();
+        struct timespec finish = evAddTime(now, timeout);
+        LOG(INFO) << __func__ << ": " << sock << " send_vc";
+        res = retrying_poll(sock, POLLIN | POLLOUT, &finish);
+        if (res <= 0) {
+            res = -1;
+        }
+    }
+done:
+    fcntl(sock, F_SETFL, origflags);
+    LOG(INFO) << __func__ << ": " << sock << " connect_with_const timeout returning " << res;
+    return res;
+}
+
+static int retrying_poll(const int sock, const short events, const struct timespec* finish) {
+    struct timespec now, timeout;
+
+retry:
+    LOG(INFO) << __func__ << ": " << sock << " retrying_poll";
+
+    now = evNowTime();
+    if (evCmpTime(*finish, now) > 0)
+        timeout = evSubTime(*finish, now);
+    else
+        timeout = evConsTime(0L, 0L);
+    struct pollfd fds = {.fd = sock, .events = events};
+    int n = ppoll(&fds, 1, &timeout, /*sigmask=*/NULL);
+    if (n == 0) {
+        LOG(INFO) << __func__ << ": " << sock << "retrying_poll timeout";
+        errno = ETIMEDOUT;
+        return 0;
+    }
+    if (n < 0) {
+        if (errno == EINTR) goto retry;
+        PLOG(INFO) << __func__ << ": " << sock << " retrying_poll failed";
+        return n;
+    }
+    if (fds.revents & (POLLIN | POLLOUT | POLLERR)) {
+        int error;
+        socklen_t len = sizeof(error);
+        if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) {
+            errno = error;
+            PLOG(INFO) << __func__ << ": " << sock << " retrying_poll getsockopt failed";
+            return -1;
+        }
+    }
+    LOG(INFO) << __func__ << ": " << sock << " retrying_poll returning " << n;
+    return n;
+}
+
+static int send_dg(res_state statp, res_params* params, const u_char* buf, int buflen, u_char* ans,
+                   int anssiz, int* terrno, int ns, int* v_circuit, int* gotsomewhere, time_t* at,
+                   int* rcode, int* delay) {
+    *at = time(NULL);
+    *delay = 0;
+    const HEADER* hp = (const HEADER*) (const void*) buf;
+    HEADER* anhp = (HEADER*) (void*) ans;
+    const struct sockaddr* nsap;
+    int nsaplen;
+    struct timespec now, timeout, finish, done;
+    struct sockaddr_storage from;
+    socklen_t fromlen;
+    int resplen, n, s;
+
+    nsap = get_nsaddr(statp, (size_t) ns);
+    nsaplen = get_salen(nsap);
+    if (statp->_u._ext.nssocks[ns] == -1) {
+        statp->_u._ext.nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+        if (statp->_u._ext.nssocks[ns] < 0) {
+            switch (errno) {
+                case EPROTONOSUPPORT:
+                case EPFNOSUPPORT:
+                case EAFNOSUPPORT:
+                    Perror(statp, "socket(dg)", errno);
+                    return (0);
+                default:
+                    *terrno = errno;
+                    Perror(statp, "socket(dg)", errno);
+                    return (-1);
+            }
+        }
+
+        fchown(statp->_u._ext.nssocks[ns], AID_DNS, -1);
+        if (statp->_mark != MARK_UNSET) {
+            if (setsockopt(statp->_u._ext.nssocks[ns], SOL_SOCKET, SO_MARK, &(statp->_mark),
+                           sizeof(statp->_mark)) < 0) {
+                res_nclose(statp);
+                return -1;
+            }
+        }
+#ifndef CANNOT_CONNECT_DGRAM
+        /*
+         * On a 4.3BSD+ machine (client and server,
+         * actually), sending to a nameserver datagram
+         * port with no nameserver will cause an
+         * ICMP port unreachable message to be returned.
+         * If our datagram socket is "connected" to the
+         * server, we get an ECONNREFUSED error on the next
+         * socket operation, and select returns if the
+         * error message is received.  We can thus detect
+         * the absence of a nameserver without timing out.
+         */
+        if (random_bind(statp->_u._ext.nssocks[ns], nsap->sa_family) < 0) {
+            Aerror(statp, "bind(dg)", errno, nsap, nsaplen);
+            res_nclose(statp);
+            return (0);
+        }
+        if (connect(statp->_u._ext.nssocks[ns], nsap, (socklen_t) nsaplen) < 0) {
+            Aerror(statp, "connect(dg)", errno, nsap, nsaplen);
+            res_nclose(statp);
+            return (0);
+        }
+#endif /* !CANNOT_CONNECT_DGRAM */
+        LOG(DEBUG) << __func__ << ": new DG socket";
+    }
+    s = statp->_u._ext.nssocks[ns];
+#ifndef CANNOT_CONNECT_DGRAM
+    if (send(s, (const char*) buf, (size_t) buflen, 0) != buflen) {
+        Perror(statp, "send", errno);
+        res_nclose(statp);
+        return 0;
+    }
+#else  /* !CANNOT_CONNECT_DGRAM */
+    if (sendto(s, (const char*) buf, buflen, 0, nsap, nsaplen) != buflen) {
+        Aerror(statp, "sendto", errno, nsap, nsaplen);
+        res_nclose(statp);
+        return 0;
+    }
+#endif /* !CANNOT_CONNECT_DGRAM */
+
+    // Wait for reply.
+    timeout = get_timeout(statp, params, ns);
+    now = evNowTime();
+    finish = evAddTime(now, timeout);
+retry:
+    n = retrying_poll(s, POLLIN, &finish);
+
+    if (n == 0) {
+        *rcode = RCODE_TIMEOUT;
+        LOG(DEBUG) << __func__ << ": timeout";
+        *gotsomewhere = 1;
+        return 0;
+    }
+    if (n < 0) {
+        Perror(statp, "poll", errno);
+        res_nclose(statp);
+        return 0;
+    }
+    errno = 0;
+    fromlen = sizeof(from);
+    resplen = recvfrom(s, (char*) ans, (size_t) anssiz, 0, (struct sockaddr*) (void*) &from,
+                       &fromlen);
+    if (resplen <= 0) {
+        Perror(statp, "recvfrom", errno);
+        res_nclose(statp);
+        return 0;
+    }
+    *gotsomewhere = 1;
+    if (resplen < HFIXEDSZ) {
+        /*
+         * Undersized message.
+         */
+        LOG(DEBUG) << __func__ << ": undersized: " << resplen;
+        *terrno = EMSGSIZE;
+        res_nclose(statp);
+        return 0;
+    }
+    if (hp->id != anhp->id) {
+        /*
+         * response from old query, ignore it.
+         * XXX - potential security hazard could
+         *	 be detected here.
+         */
+        LOG(DEBUG) << __func__ << ": old answer:";
+        res_pquery(ans, (resplen > anssiz) ? anssiz : resplen);
+        goto retry;
+    }
+    if (!(statp->options & RES_INSECURE1) &&
+        !res_ourserver_p(statp, (struct sockaddr*) (void*) &from)) {
+        /*
+         * response from wrong server? ignore it.
+         * XXX - potential security hazard could
+         *	 be detected here.
+         */
+        LOG(DEBUG) << __func__ << ": not our server:";
+        res_pquery(ans, (resplen > anssiz) ? anssiz : resplen);
+        goto retry;
+    }
+    if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) {
+        /*
+         * Do not retry if the server do not understand EDNS0.
+         * The case has to be captured here, as FORMERR packet do not
+         * carry query section, hence res_queriesmatch() returns 0.
+         */
+        LOG(DEBUG) << __func__ << ": server rejected query with EDNS0:";
+        res_pquery(ans, (resplen > anssiz) ? anssiz : resplen);
+        /* record the error */
+        statp->_flags |= RES_F_EDNS0ERR;
+        res_nclose(statp);
+        return 0;
+    }
+    if (!(statp->options & RES_INSECURE2) &&
+        !res_queriesmatch(buf, buf + buflen, ans, ans + anssiz)) {
+        /*
+         * response contains wrong query? ignore it.
+         * XXX - potential security hazard could
+         *	 be detected here.
+         */
+        LOG(DEBUG) << __func__ << ": wrong query name:";
+        res_pquery(ans, (resplen > anssiz) ? anssiz : resplen);
+        goto retry;
+    }
+    done = evNowTime();
+    *delay = _res_stats_calculate_rtt(&done, &now);
+    if (anhp->rcode == SERVFAIL || anhp->rcode == NOTIMP || anhp->rcode == REFUSED) {
+        LOG(DEBUG) << __func__ << ": server rejected query:";
+        res_pquery(ans, (resplen > anssiz) ? anssiz : resplen);
+        res_nclose(statp);
+        *rcode = anhp->rcode;
+        return 0;
+    }
+    if (!(statp->options & RES_IGNTC) && anhp->tc) {
+        /*
+         * To get the rest of answer,
+         * use TCP with same server.
+         */
+        LOG(DEBUG) << __func__ << ": truncated answer";
+        *v_circuit = 1;
+        res_nclose(statp);
+        return 1;
+    }
+    /*
+     * All is well, or the error is fatal.  Signal that the
+     * next nameserver ought not be tried.
+     */
+    if (resplen > 0) {
+        *rcode = anhp->rcode;
+    }
+    return resplen;
+}
+
+static void Aerror(const res_state statp, const char* string, int error,
+                   const struct sockaddr* address, int alen) {
+    const int save = errno;
+    char hbuf[NI_MAXHOST];
+    char sbuf[NI_MAXSERV];
+    constexpr int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
+
+    if ((statp->options & RES_DEBUG) != 0U) {
+        if (getnameinfo(address, (socklen_t) alen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
+                        niflags)) {
+            strncpy(hbuf, "?", sizeof(hbuf) - 1);
+            hbuf[sizeof(hbuf) - 1] = '\0';
+            strncpy(sbuf, "?", sizeof(sbuf) - 1);
+            sbuf[sizeof(sbuf) - 1] = '\0';
+        }
+        LOG(DEBUG) << __func__ << ": " << string << " ([" << hbuf << "]." << sbuf
+                   << "): " << strerror(error);
+    }
+    errno = save;
+}
+
+static void Perror(const res_state statp, const char* string, int error) {
+    if ((statp->options & RES_DEBUG) != 0U) {
+        LOG(DEBUG) << __func__ << ": " << string << ": " << strerror(error);
+    }
+}
+
+static int sock_eq(struct sockaddr* a, struct sockaddr* b) {
+    struct sockaddr_in *a4, *b4;
+    struct sockaddr_in6 *a6, *b6;
+
+    if (a->sa_family != b->sa_family) return 0;
+    switch (a->sa_family) {
+        case AF_INET:
+            a4 = (struct sockaddr_in*) (void*) a;
+            b4 = (struct sockaddr_in*) (void*) b;
+            return a4->sin_port == b4->sin_port && a4->sin_addr.s_addr == b4->sin_addr.s_addr;
+        case AF_INET6:
+            a6 = (struct sockaddr_in6*) (void*) a;
+            b6 = (struct sockaddr_in6*) (void*) b;
+            return a6->sin6_port == b6->sin6_port &&
+#ifdef HAVE_SIN6_SCOPE_ID
+                   a6->sin6_scope_id == b6->sin6_scope_id &&
+#endif
+                   IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr);
+        default:
+            return 0;
+    }
+}
+
+PrivateDnsModes convertEnumType(PrivateDnsMode privateDnsmode) {
+    switch (privateDnsmode) {
+        case PrivateDnsMode::OFF:
+            return PrivateDnsModes::PDM_OFF;
+        case PrivateDnsMode::OPPORTUNISTIC:
+            return PrivateDnsModes::PDM_OPPORTUNISTIC;
+        case PrivateDnsMode::STRICT:
+            return PrivateDnsModes::PDM_STRICT;
+    }
+    return PrivateDnsModes::PDM_UNKNOWN;
+}
+
+static int res_tls_send(res_state statp, const Slice query, const Slice answer, int* rcode,
+                        bool* fallback) {
+    int resplen = 0;
+    const unsigned netId = statp->netid;
+
+    PrivateDnsStatus privateDnsStatus = gPrivateDnsConfiguration.getStatus(netId);
+    statp->event->set_private_dns_modes(convertEnumType(privateDnsStatus.mode));
+
+    if (privateDnsStatus.mode == PrivateDnsMode::OFF) {
+        *fallback = true;
+        return -1;
+    }
+
+    if (privateDnsStatus.validatedServers.empty()) {
+        if (privateDnsStatus.mode == PrivateDnsMode::OPPORTUNISTIC) {
+            *fallback = true;
+            return -1;
+        } else {
+            // Sleep and iterate some small number of times checking for the
+            // arrival of resolved and validated server IP addresses, instead
+            // of returning an immediate error.
+            // This is needed because as soon as a network becomes the default network, apps will
+            // send DNS queries on that network. If no servers have yet validated, and we do not
+            // block those queries, they would immediately fail, causing application-visible errors.
+            // Note that this can happen even before the network validates, since an unvalidated
+            // network can become the default network if no validated networks are available.
+            //
+            // TODO: see if there is a better way to address this problem, such as buffering the
+            // queries in a queue or only blocking queries for the first few seconds after a default
+            // network change.
+            for (int i = 0; i < 42; i++) {
+                std::this_thread::sleep_for(std::chrono::milliseconds(100));
+                if (!gPrivateDnsConfiguration.getStatus(netId).validatedServers.empty()) {
+                    privateDnsStatus = gPrivateDnsConfiguration.getStatus(netId);
+                    break;
+                }
+            }
+            if (privateDnsStatus.validatedServers.empty()) {
+                return -1;
+            }
+        }
+    }
+
+    LOG(INFO) << __func__ << ": performing query over TLS";
+
+    const auto response = sDnsTlsDispatcher.query(privateDnsStatus.validatedServers, statp, query,
+                                                  answer, &resplen);
+
+    LOG(INFO) << __func__ << ": TLS query result: " << static_cast<int>(response);
+
+    if (privateDnsStatus.mode == PrivateDnsMode::OPPORTUNISTIC) {
+        // In opportunistic mode, handle falling back to cleartext in some
+        // cases (DNS shouldn't fail if a validated opportunistic mode server
+        // becomes unreachable for some reason).
+        switch (response) {
+            case DnsTlsTransport::Response::success:
+                *rcode = reinterpret_cast<HEADER*>(answer.base())->rcode;
+                return resplen;
+            case DnsTlsTransport::Response::network_error:
+                // No need to set the error timeout here since it will fallback to UDP.
+            case DnsTlsTransport::Response::internal_error:
+                // Note: this will cause cleartext queries to be emitted, with
+                // all of the EDNS0 goodness enabled. Fingers crossed.  :-/
+                *fallback = true;
+                [[fallthrough]];
+            default:
+                return -1;
+        }
+    } else {
+        // Strict mode
+        switch (response) {
+            case DnsTlsTransport::Response::success:
+                *rcode = reinterpret_cast<HEADER*>(answer.base())->rcode;
+                return resplen;
+            case DnsTlsTransport::Response::network_error:
+                // This case happens when the query stored in DnsTlsTransport is expired since
+                // either 1) the query has been tried for 3 times but no response or 2) fail to
+                // establish the connection with the server.
+                *rcode = RCODE_TIMEOUT;
+                [[fallthrough]];
+            default:
+                return -1;
+        }
+    }
+}
+
+int resolv_res_nsend(const android_net_context* netContext, const uint8_t* msg, int msgLen,
+                     uint8_t* ans, int ansLen, int* rcode, uint32_t flags,
+                     NetworkDnsEventReported* event) {
+    assert(event != nullptr);
+    res_state res = res_get_state();
+    res_setnetcontext(res, netContext, event);
+    _resolv_populate_res_for_net(res);
+    *rcode = NOERROR;
+    return res_nsend(res, msg, msgLen, ans, ansLen, rcode, flags);
+}
diff --git a/resolv/res_send.h b/resolv/res_send.h
new file mode 100644
index 0000000..fb80160
--- /dev/null
+++ b/resolv/res_send.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "netd_resolv/resolv.h"  // struct android_net_context
+#include "stats.pb.h"
+
+// Query dns with raw msg
+int resolv_res_nsend(const android_net_context* netContext, const uint8_t* msg, int msgLen,
+                     uint8_t* ans, int ansLen, int* rcode, uint32_t flags,
+                     android::net::NetworkDnsEventReported* event);
diff --git a/resolv/res_state.cpp b/resolv/res_state.cpp
new file mode 100644
index 0000000..26febff
--- /dev/null
+++ b/resolv/res_state.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define LOG_TAG "res_state"
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h> /* for gettid() */
+
+#include <android-base/logging.h>
+
+#include "resolv_cache.h"
+#include "resolv_private.h"
+
+typedef struct {
+    // TODO: Have one __res_state per network so we don't have to repopulate frequently.
+    struct __res_state _nres[1];
+    struct res_static _rstatic[1];
+} _res_thread;
+
+static _res_thread* res_thread_alloc(void) {
+    _res_thread* rt = (_res_thread*) calloc(1, sizeof(*rt));
+
+    if (rt) {
+        memset(rt->_rstatic, 0, sizeof rt->_rstatic);
+    }
+    return rt;
+}
+
+static void res_static_done(struct res_static* rs) {
+    /* fortunately, there is nothing to do here, since the
+     * points in h_addr_ptrs and host_aliases should all
+     * point to 'hostbuf'
+     */
+    if (rs->hostf) { /* should not happen in theory, but just be safe */
+        fclose(rs->hostf);
+        rs->hostf = NULL;
+    }
+    free(rs->servent.s_aliases);
+}
+
+static void res_thread_free(void* _rt) {
+    _res_thread* rt = (_res_thread*) _rt;
+
+    LOG(VERBOSE) << __func__ << ": rt=" << rt << " for thread=" << gettid();
+
+    res_static_done(rt->_rstatic);
+    res_ndestroy(rt->_nres);
+    free(rt);
+}
+
+static pthread_key_t _res_key;
+
+__attribute__((constructor)) static void __res_key_init() {
+    pthread_key_create(&_res_key, res_thread_free);
+}
+
+static _res_thread* res_thread_get(void) {
+    _res_thread* rt = (_res_thread*) pthread_getspecific(_res_key);
+    if (rt != NULL) {
+        return rt;
+    }
+
+    /* It is the first time this function is called in this thread,
+     * we need to create a new thread-specific DNS resolver state. */
+    rt = res_thread_alloc();
+    if (rt == NULL) {
+        return NULL;
+    }
+    pthread_setspecific(_res_key, rt);
+
+    /* Reset the state, note that res_ninit() can now properly reset
+     * an existing state without leaking memory.
+     */
+    LOG(VERBOSE) << __func__ << ": tid=" << gettid() << ", rt=" << rt
+                 << " setting DNS state (options=" << rt->_nres->options << ")";
+    if (res_ninit(rt->_nres) < 0) {
+        /* This should not happen */
+        LOG(VERBOSE) << __func__ << ": tid=" << gettid() << " rt=" << rt
+                     << ", res_ninit() returned < 0";
+        res_thread_free(rt);
+        pthread_setspecific(_res_key, NULL);
+        return NULL;
+    }
+    return rt;
+}
+
+struct __res_state _nres;
+
+res_state res_get_state(void) {
+    _res_thread* rt = res_thread_get();
+
+    return rt ? rt->_nres : NULL;
+}
+
+res_static* res_get_static(void) {
+    _res_thread* rt = res_thread_get();
+
+    return rt ? rt->_rstatic : NULL;
+}
diff --git a/resolv/res_state_ext.h b/resolv/res_state_ext.h
new file mode 100644
index 0000000..6ed3398
--- /dev/null
+++ b/resolv/res_state_ext.h
@@ -0,0 +1,22 @@
+/*	$NetBSD: res_private.h,v 1.1.1.1 2004/05/20 17:18:54 christos Exp $	*/
+
+#ifndef NETD_RES_STATE_EXT_H
+#define NETD_RES_STATE_EXT_H
+
+#include "resolv_private.h"
+
+// TODO: consider inlining into res_state
+struct res_state_ext {
+    sockaddr_union nsaddrs[MAXNS];
+    struct sort_list {
+        int af;
+        union {
+            struct in_addr ina;
+            struct in6_addr in6a;
+        } addr, mask;
+    } sort_list[MAXRESOLVSORT];
+    char nsuffix[64];
+    char nsuffix2[64];
+};
+
+#endif  // NETD_RES_STATE_EXT_H
diff --git a/resolv/res_stats.cpp b/resolv/res_stats.cpp
new file mode 100644
index 0000000..ed6f084
--- /dev/null
+++ b/resolv/res_stats.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "res_stats"
+
+#include <arpa/nameser.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <android-base/logging.h>
+
+#include "netd_resolv/stats.h"
+
+
+// Calculate the round-trip-time from start time t0 and end time t1.
+int _res_stats_calculate_rtt(const timespec* t1, const timespec* t0) {
+    // Divide ns by one million to get ms, multiply s by thousand to get ms (obvious)
+    long ms0 = t0->tv_sec * 1000 + t0->tv_nsec / 1000000;
+    long ms1 = t1->tv_sec * 1000 + t1->tv_nsec / 1000000;
+    return (int) (ms1 - ms0);
+}
+
+// Create a sample for calculating server reachability statistics.
+void _res_stats_set_sample(res_sample* sample, time_t now, int rcode, int rtt) {
+    LOG(INFO) << __func__ << ": rcode = " << rcode << ", sec = " << rtt;
+    sample->at = now;
+    sample->rcode = rcode;
+    sample->rtt = rtt;
+}
+
+/* Clears all stored samples for the given server. */
+void _res_stats_clear_samples(res_stats* stats) {
+    stats->sample_count = stats->sample_next = 0;
+}
+
+/* Aggregates the reachability statistics for the given server based on on the stored samples. */
+void android_net_res_stats_aggregate(res_stats* stats, int* successes, int* errors, int* timeouts,
+                                     int* internal_errors, int* rtt_avg, time_t* last_sample_time) {
+    int s = 0;   // successes
+    int e = 0;   // errors
+    int t = 0;   // timouts
+    int ie = 0;  // internal errors
+    long rtt_sum = 0;
+    time_t last = 0;
+    int rtt_count = 0;
+    for (int i = 0; i < stats->sample_count; ++i) {
+        // Treat everything as an error that the code in send_dg() already considers a
+        // rejection by the server, i.e. SERVFAIL, NOTIMP and REFUSED. Assume that NXDOMAIN
+        // and NOTAUTH can actually occur for user queries. NOERROR with empty answer section
+        // is not treated as an error here either. FORMERR seems to sometimes be returned by
+        // some versions of BIND in response to DNSSEC or EDNS0. Whether to treat such responses
+        // as an indication of a broken server is unclear, though. For now treat such responses,
+        // as well as unknown codes as errors.
+        switch (stats->samples[i].rcode) {
+            case NOERROR:
+            case NOTAUTH:
+            case NXDOMAIN:
+                ++s;
+                rtt_sum += stats->samples[i].rtt;
+                ++rtt_count;
+                break;
+            case RCODE_TIMEOUT:
+                ++t;
+                break;
+            case RCODE_INTERNAL_ERROR:
+                ++ie;
+                break;
+            case SERVFAIL:
+            case NOTIMP:
+            case REFUSED:
+            default:
+                ++e;
+                break;
+        }
+    }
+    *successes = s;
+    *errors = e;
+    *timeouts = t;
+    *internal_errors = ie;
+    /* If there was at least one successful sample, calculate average RTT. */
+    if (rtt_count) {
+        *rtt_avg = rtt_sum / rtt_count;
+    } else {
+        *rtt_avg = -1;
+    }
+    /* If we had at least one sample, populate last sample time. */
+    if (stats->sample_count > 0) {
+        if (stats->sample_next > 0) {
+            last = stats->samples[stats->sample_next - 1].at;
+        } else {
+            last = stats->samples[stats->sample_count - 1].at;
+        }
+    }
+    *last_sample_time = last;
+}
+
+// Returns true if the server is considered usable, i.e. if the success rate is not lower than the
+// threshold for the stored stored samples. If not enough samples are stored, the server is
+// considered usable.
+static bool res_stats_usable_server(const res_params* params, res_stats* stats) {
+    int successes = -1;
+    int errors = -1;
+    int timeouts = -1;
+    int internal_errors = -1;
+    int rtt_avg = -1;
+    time_t last_sample_time = 0;
+    android_net_res_stats_aggregate(stats, &successes, &errors, &timeouts, &internal_errors,
+                                    &rtt_avg, &last_sample_time);
+    if (successes >= 0 && errors >= 0 && timeouts >= 0) {
+        int total = successes + errors + timeouts;
+        LOG(INFO) << __func__ << ": NS stats: S " << successes << " + E " << errors << " + T "
+                  << timeouts << " + I " << internal_errors << " = " << total
+                  << ", rtt = " << rtt_avg << ", min_samples = " << unsigned(params->min_samples);
+        if (total >= params->min_samples && (errors > 0 || timeouts > 0)) {
+            int success_rate = successes * 100 / total;
+            LOG(INFO) << __func__ << ": success rate " << success_rate;
+            if (success_rate < params->success_threshold) {
+                time_t now = time(NULL);
+                if (now - last_sample_time > params->sample_validity) {
+                    // Note: It might be worth considering to expire old servers after their expiry
+                    // date has been reached, however the code for returning the ring buffer to its
+                    // previous non-circular state would induce additional complexity.
+                    LOG(INFO) << __func__ << ": samples stale, retrying server";
+                    _res_stats_clear_samples(stats);
+                } else {
+                    LOG(INFO) << __func__ << ": too many resolution errors, ignoring server";
+                    return 0;
+                }
+            }
+        }
+    }
+    return 1;
+}
+
+int android_net_res_stats_get_usable_servers(const res_params* params, res_stats stats[],
+                                             int nscount, bool usable_servers[]) {
+    unsigned usable_servers_found = 0;
+    for (int ns = 0; ns < nscount; ns++) {
+        bool usable = res_stats_usable_server(params, &stats[ns]);
+        if (usable) {
+            ++usable_servers_found;
+        }
+        usable_servers[ns] = usable;
+    }
+    // If there are no usable servers, consider all of them usable.
+    // TODO: Explore other possibilities, such as enabling only the best N servers, etc.
+    if (usable_servers_found == 0) {
+        for (int ns = 0; ns < nscount; ns++) {
+            usable_servers[ns] = true;
+        }
+    }
+    return (usable_servers_found == 0) ? nscount : usable_servers_found;
+}
diff --git a/resolv/resolv_cache.h b/resolv/resolv_cache.h
new file mode 100644
index 0000000..df21fb3
--- /dev/null
+++ b/resolv/resolv_cache.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "netd_resolv/resolv.h"
+
+#include <stddef.h>
+
+#include <unordered_map>
+#include <vector>
+
+struct __res_state;
+
+constexpr int DNSEVENT_SUBSAMPLING_MAP_DEFAULT_KEY = -1;
+
+/* sets the name server addresses to the provided res_state structure. The
+ * name servers are retrieved from the cache which is associated
+ * with the network to which the res_state structure is associated */
+void _resolv_populate_res_for_net(struct __res_state* statp);
+
+std::vector<unsigned> resolv_list_caches();
+
+std::vector<std::string> resolv_cache_dump_subsampling_map(unsigned netid);
+uint32_t resolv_cache_get_subsampling_denom(unsigned netid, int return_code);
+
+typedef enum {
+    RESOLV_CACHE_UNSUPPORTED, /* the cache can't handle that kind of queries */
+                              /* or the answer buffer is too small */
+    RESOLV_CACHE_NOTFOUND,    /* the cache doesn't know about this query */
+    RESOLV_CACHE_FOUND,       /* the cache found the answer */
+    RESOLV_CACHE_SKIP         /* Don't do anything on cache */
+} ResolvCacheStatus;
+
+ResolvCacheStatus _resolv_cache_lookup(unsigned netid, const void* query, int querylen,
+                                       void* answer, int answersize, int* answerlen,
+                                       uint32_t flags);
+
+/* add a (query,answer) to the cache, only call if _resolv_cache_lookup
+ * did return RESOLV_CACHE_NOTFOUND
+ */
+void _resolv_cache_add(unsigned netid, const void* query, int querylen, const void* answer,
+                       int answerlen);
+
+/* Notify the cache a request failed */
+void _resolv_cache_query_failed(unsigned netid, const void* query, int querylen, uint32_t flags);
+
+// Sets name servers for a given network.
+int resolv_set_nameservers_for_net(unsigned netid, const char** servers, int numservers,
+                                   const char* domains, const res_params* params);
+
+// Creates the cache associated with the given network.
+int resolv_create_cache_for_net(unsigned netid);
+
+// Deletes the cache associated with the given network.
+void resolv_delete_cache_for_net(unsigned netid);
diff --git a/resolv/resolv_private.h b/resolv/resolv_private.h
new file mode 100644
index 0000000..3ecb6c1
--- /dev/null
+++ b/resolv/resolv_private.h
@@ -0,0 +1,255 @@
+/*	$NetBSD: resolv.h,v 1.31 2005/12/26 19:01:47 perry Exp $	*/
+
+/*
+ * Copyright (c) 1983, 1987, 1989
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ *	@(#)resolv.h	8.1 (Berkeley) 6/2/93
+ *	Id: resolv.h,v 1.7.2.11.4.2 2004/06/25 00:41:05 marka Exp
+ */
+
+#ifndef NETD_RESOLV_PRIVATE_H
+#define NETD_RESOLV_PRIVATE_H
+
+#include <android-base/logging.h>
+#include <net/if.h>
+#include <resolv.h>
+#include <time.h>
+#include <string>
+
+#include "netd_resolv/params.h"
+#include "netd_resolv/resolv.h"
+#include "netd_resolv/stats.h"
+#include "resolv_static.h"
+#include "stats.pb.h"
+
+// Linux defines MAXHOSTNAMELEN as 64, while the domain name limit in
+// RFC 1034 and RFC 1035 is 255 octets.
+#ifdef MAXHOSTNAMELEN
+#undef MAXHOSTNAMELEN
+#endif
+#define MAXHOSTNAMELEN 256
+
+/*
+ * Global defines and variables for resolver stub.
+ */
+#define MAXDFLSRCH 3       /* # default domain levels to try */
+#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
+
+#define RES_TIMEOUT 5000 /* min. milliseconds between retries */
+#define MAXRESOLVSORT 10  /* number of net to sort on */
+#define RES_MAXNDOTS 15   /* should reflect bit field size */
+#define RES_DFLRETRY 2    /* Default #/tries. */
+#define RES_MAXTIME 65535 /* Infinity, in milliseconds. */
+
+struct res_state_ext;
+
+struct __res_state {
+    unsigned netid;                        /* NetId: cache key and socket mark */
+    u_long options;                        /* option flags - see below. */
+    int nscount;                           /* number of name srvers */
+    struct sockaddr_in nsaddr_list[MAXNS]; /* address of name server */
+#define nsaddr nsaddr_list[0]              /* for backward compatibility */
+    u_short id;                            /* current message id */
+    char* dnsrch[MAXDNSRCH + 1];           /* components of domain to search */
+    char defdname[256];                    /* default domain (deprecated) */
+    unsigned ndots : 4;                    /* threshold for initial abs. query */
+    unsigned nsort : 4;                    /* number of elements in sort_list[] */
+    char unused[3];
+    struct {
+        struct in_addr addr;
+        uint32_t mask;
+    } sort_list[MAXRESOLVSORT];
+    unsigned _mark;       /* If non-0 SET_MARK to _mark on all request sockets */
+    int _vcsock;          /* PRIVATE: for res_send VC i/o */
+    u_int _flags;         /* PRIVATE: see below */
+    u_int _pad;           /* make _u 64 bit aligned */
+    union {
+        /* On an 32-bit arch this means 512b total. */
+        char pad[72 - 4 * sizeof(int) - 2 * sizeof(void*)];
+        struct {
+            uint16_t nscount;
+            uint16_t nstimes[MAXNS]; /* ms. */
+            int nssocks[MAXNS];
+            struct res_state_ext* ext; /* extention for IPv6 */
+        } _ext;
+    } _u;
+    struct res_static rstatic[1];
+    bool use_local_nameserver; /* DNS-over-TLS bypass */
+    android::net::NetworkDnsEventReported* event;
+};
+
+typedef struct __res_state* res_state;
+
+/* Retrieve a local copy of the stats for the given netid. The buffer must have space for
+ * MAXNS __resolver_stats. Returns the revision id of the resolvers used.
+ */
+int resolv_cache_get_resolver_stats(unsigned netid, res_params* params, res_stats stats[MAXNS]);
+
+/* Add a sample to the shared struct for the given netid and server, provided that the
+ * revision_id of the stored servers has not changed.
+ */
+void _resolv_cache_add_resolver_stats_sample(unsigned netid, int revision_id, int ns,
+                                             const res_sample* sample, int max_samples);
+
+// Calculate the round-trip-time from start time t0 and end time t1.
+int _res_stats_calculate_rtt(const timespec* t1, const timespec* t0);
+
+// Create a sample for calculating server reachability statistics.
+void _res_stats_set_sample(res_sample* sample, time_t now, int rcode, int rtt);
+
+/* End of stats related definitions */
+
+// Flags for res_state->_flags
+#define RES_F_VC 0x00000001        // socket is TCP
+#define RES_F_EDNS0ERR 0x00000004  // EDNS0 caused errors
+
+/*
+ * Resolver options (keep these in synch with res_debug.c, please)
+ */
+#define RES_INIT 0x00000001           /* address initialized */
+#define RES_DEBUG 0x00000002          /* print debug messages */
+#define RES_AAONLY 0x00000004         /* authoritative answers only (!IMPL)*/
+#define RES_USEVC 0x00000008          /* use virtual circuit */
+#define RES_PRIMARY 0x00000010        /* query primary server only (!IMPL) */
+#define RES_IGNTC 0x00000020          /* ignore trucation errors */
+#define RES_RECURSE 0x00000040        /* recursion desired */
+#define RES_DEFNAMES 0x00000080       /* use default domain name */
+#define RES_STAYOPEN 0x00000100       /* Keep TCP socket open */
+#define RES_DNSRCH 0x00000200         /* search up local domain tree */
+#define RES_INSECURE1 0x00000400      /* type 1 security disabled */
+#define RES_INSECURE2 0x00000800      /* type 2 security disabled */
+#define RES_USE_INET6 0x00002000      /* use/map IPv6 in gethostbyname() */
+#define RES_ROTATE 0x00004000         /* rotate ns list after each query */
+#define RES_NOCHECKNAME 0x00008000    /* do not check names for sanity. */
+#define RES_KEEPTSIG 0x00010000       /* do not strip TSIG records */
+#define RES_BLAST 0x00020000          /* blast all recursive servers */
+#define RES_NOTLDQUERY 0x00100000     /* don't unqualified name as a tld */
+#define RES_USE_DNSSEC 0x00200000     /* use DNSSEC using OK bit in OPT */
+/* #define RES_DEBUG2	0x00400000 */ /* nslookup internal */
+/* KAME extensions: use higher bit to avoid conflict with ISC use */
+#define RES_USE_DNAME 0x10000000  /* use DNAME */
+#define RES_USE_EDNS0 0x40000000  /* use EDNS0 if configured */
+#define RES_NO_NIBBLE2 0x80000000 /* disable alternate nibble lookup */
+
+#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH | RES_NO_NIBBLE2)
+
+
+/*
+ * Error code extending h_errno codes defined in bionic/libc/include/netdb.h.
+ *
+ * This error code, including legacy h_errno, is returned from res_nquery(), res_nsearch(),
+ * res_nquerydomain(), res_queryN(), res_searchN() and res_querydomainN() for DNS metrics.
+ *
+ * TODO: Consider mapping legacy and extended h_errno into a unified resolver error code mapping.
+ */
+#define NETD_RESOLV_H_ERRNO_EXT_TIMEOUT RCODE_TIMEOUT
+
+extern const char* const _res_opcodes[];
+
+/* Things involving an internal (static) resolver context. */
+struct __res_state* res_get_state(void);
+
+int res_hnok(const char*);
+int res_ownok(const char*);
+int res_mailok(const char*);
+int res_dnok(const char*);
+int dn_skipname(const u_char*, const u_char*);
+void putlong(uint32_t, u_char*);
+void putshort(uint16_t, u_char*);
+
+// Thread-unsafe functions returning pointers to static buffers :-(
+// TODO: switch all res_debug to std::string
+const char* p_class(int);
+const char* p_type(int);
+const char* p_rcode(int);
+const char* p_section(int, int);
+
+int res_nameinquery(const char*, int, int, const u_char*, const u_char*);
+int res_queriesmatch(const u_char*, const u_char*, const u_char*, const u_char*);
+/* Things involving a resolver context. */
+int res_ninit(res_state);
+void res_pquery(const u_char*, int);
+
+int res_nquery(res_state, const char*, int, int, u_char*, int, int*);
+int res_nsearch(res_state, const char*, int, int, u_char*, int, int*);
+int res_nquerydomain(res_state, const char*, const char*, int, int, u_char*, int, int*);
+int res_nmkquery(res_state, int, const char*, int, int, const u_char*, int, const u_char*, u_char*,
+                 int);
+int res_nsend(res_state, const u_char*, int, u_char*, int, int*, uint32_t);
+void res_nclose(res_state);
+int res_nopt(res_state, int, u_char*, int, int);
+int res_vinit(res_state, int);
+void res_ndestroy(res_state);
+void res_setservers(res_state, const sockaddr_union*, int);
+int res_getservers(res_state, sockaddr_union*, int);
+
+struct android_net_context; /* forward */
+void res_setnetcontext(res_state, const struct android_net_context*,
+                       android::net::NetworkDnsEventReported* event);
+
+int getaddrinfo_numeric(const char* hostname, const char* servname, addrinfo hints,
+                        addrinfo** result);
+
+// Helper function for converting h_errno to the error codes visible to netd
+int herrnoToAiErrno(int herrno);
+
+// switch resolver log severity
+android::base::LogSeverity logSeverityStrToEnum(const std::string& logSeverityStr);
+
+template <typename Dest>
+Dest saturate_cast(int64_t x) {
+    using DestLimits = std::numeric_limits<Dest>;
+    if (x > DestLimits::max()) return DestLimits::max();
+    if (x < DestLimits::min()) return DestLimits::min();
+    return static_cast<Dest>(x);
+}
+
+android::net::NsType getQueryType(const uint8_t* msg, size_t msgLen);
+
+android::net::IpVersion ipFamilyToIPVersion(int ipFamily);
+
+#endif  // NETD_RESOLV_PRIVATE_H
diff --git a/resolv/resolv_static.h b/resolv/resolv_static.h
new file mode 100644
index 0000000..b250892
--- /dev/null
+++ b/resolv/resolv_static.h
@@ -0,0 +1,33 @@
+#ifndef NETD_RESOLV_STATIC_H
+#define NETD_RESOLV_STATIC_H
+
+#include <netdb.h>
+#include <stdio.h>
+
+/* this structure contains all the variables that were declared
+ * 'static' in the original NetBSD resolver code.
+ *
+ * this caused vast amounts of crashes and memory corruptions
+ * when the resolver was being used by multiple threads.
+ *
+ * (note: the OpenBSD/FreeBSD resolver has similar 'issues')
+ */
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+struct res_static {
+    char* h_addr_ptrs[MAXADDRS + 1];
+    char* host_aliases[MAXALIASES];
+    char hostbuf[8 * 1024];
+    u_int32_t host_addr[16 / sizeof(u_int32_t)]; /* IPv4 or IPv6 */
+    FILE* hostf;
+    int stayopen;
+    const char* servent_ptr;
+    struct servent servent;
+    struct hostent host;
+};
+
+res_static* res_get_static();
+
+#endif  // NETD_RESOLV_STATIC_H
diff --git a/resolv/resolver_test.cpp b/resolv/resolver_test.cpp
new file mode 100644
index 0000000..b135b16
--- /dev/null
+++ b/resolv/resolver_test.cpp
@@ -0,0 +1,3489 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless requied by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#define LOG_TAG "resolv_integration_test"
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <poll.h> /* poll */
+#include <resolv.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <chrono>
+#include <iterator>
+#include <numeric>
+#include <thread>
+
+#include <android-base/parseint.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <android/multinetwork.h>  // ResNsendFlags
+#include <cutils/sockets.h>
+#include <gmock/gmock-matchers.h>
+#include <gtest/gtest.h>
+#include <openssl/base64.h>
+#include <private/android_filesystem_config.h>
+#include <utils/Log.h>
+
+#include "NetdClient.h"
+#include "netid_client.h"  // NETID_UNSET
+#include "netd_resolv/params.h"  // MAX_NS
+
+#include "dns_responder/dns_responder.h"
+#include "dns_responder/dns_responder_client.h"
+#include "dns_responder/dns_tls_frontend.h"
+
+#include "NetdConstants.h"
+#include "ResolverStats.h"
+
+#include "android/net/IDnsResolver.h"
+#include "binder/IServiceManager.h"
+#include "netdutils/ResponseCode.h"
+#include "netdutils/SocketOption.h"
+
+// TODO: make this dynamic and stop depending on implementation details.
+constexpr int TEST_NETID = 30;
+// Valid VPN netId range is 100 ~ 65535
+constexpr int TEST_VPN_NETID = 65502;
+constexpr int MAXPACKET = (8 * 1024);
+
+// Semi-public Bionic hook used by the NDK (frameworks/base/native/android/net.c)
+// Tested here for convenience.
+extern "C" int android_getaddrinfofornet(const char* hostname, const char* servname,
+                                         const addrinfo* hints, unsigned netid, unsigned mark,
+                                         struct addrinfo** result);
+
+using android::base::ParseInt;
+using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::net::ResolverStats;
+using android::netdutils::enableSockopt;
+using android::netdutils::ResponseCode;
+
+// TODO: move into libnetdutils?
+namespace {
+ScopedAddrinfo safe_getaddrinfo(const char* node, const char* service,
+                                const struct addrinfo* hints) {
+    addrinfo* result = nullptr;
+    if (getaddrinfo(node, service, hints, &result) != 0) {
+        result = nullptr;  // Should already be the case, but...
+    }
+    return ScopedAddrinfo(result);
+}
+}  // namespace
+
+class ResolverTest : public ::testing::Test {
+  protected:
+    struct DnsRecord {
+        std::string host_name;  // host name
+        ns_type type;           // record type
+        std::string addr;       // ipv4/v6 address
+    };
+
+    void SetUp() { mDnsClient.SetUp(); }
+    void TearDown() {
+        mDnsClient.TearDown();
+    }
+
+    bool GetResolverInfo(std::vector<std::string>* servers, std::vector<std::string>* domains,
+                         std::vector<std::string>* tlsServers, res_params* params,
+                         std::vector<ResolverStats>* stats,
+                         int* wait_for_pending_req_timeout_count) {
+        using android::net::IDnsResolver;
+        std::vector<int32_t> params32;
+        std::vector<int32_t> stats32;
+        std::vector<int32_t> wait_for_pending_req_timeout_count32{0};
+        auto rv = mDnsClient.resolvService()->getResolverInfo(
+                TEST_NETID, servers, domains, tlsServers, &params32, &stats32,
+                &wait_for_pending_req_timeout_count32);
+
+        if (!rv.isOk() ||
+            params32.size() != static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT)) {
+            return false;
+        }
+        *params = res_params{
+                .sample_validity = static_cast<uint16_t>(
+                        params32[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY]),
+                .success_threshold = static_cast<uint8_t>(
+                        params32[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD]),
+                .min_samples =
+                        static_cast<uint8_t>(params32[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES]),
+                .max_samples =
+                        static_cast<uint8_t>(params32[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES]),
+                .base_timeout_msec = params32[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
+                .retry_count = params32[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT],
+        };
+        *wait_for_pending_req_timeout_count = wait_for_pending_req_timeout_count32[0];
+        return ResolverStats::decodeAll(stats32, stats);
+    }
+
+    static std::string ToString(const hostent* he) {
+        if (he == nullptr) return "<null>";
+        char buffer[INET6_ADDRSTRLEN];
+        if (!inet_ntop(he->h_addrtype, he->h_addr_list[0], buffer, sizeof(buffer))) {
+            return "<invalid>";
+        }
+        return buffer;
+    }
+
+    static std::string ToString(const addrinfo* ai) {
+        if (!ai)
+            return "<null>";
+        for (const auto* aip = ai ; aip != nullptr ; aip = aip->ai_next) {
+            char host[NI_MAXHOST];
+            int rv = getnameinfo(aip->ai_addr, aip->ai_addrlen, host, sizeof(host), nullptr, 0,
+                    NI_NUMERICHOST);
+            if (rv != 0)
+                return gai_strerror(rv);
+            return host;
+        }
+        return "<invalid>";
+    }
+
+    static std::string ToString(const ScopedAddrinfo& ai) { return ToString(ai.get()); }
+
+    static std::vector<std::string> ToStrings(const addrinfo* ai) {
+        std::vector<std::string> hosts;
+        if (!ai) {
+            hosts.push_back("<null>");
+            return hosts;
+        }
+        for (const auto* aip = ai; aip != nullptr; aip = aip->ai_next) {
+            char host[NI_MAXHOST];
+            int rv = getnameinfo(aip->ai_addr, aip->ai_addrlen, host, sizeof(host), nullptr, 0,
+                                 NI_NUMERICHOST);
+            if (rv != 0) {
+                hosts.clear();
+                hosts.push_back(gai_strerror(rv));
+                return hosts;
+            } else {
+                hosts.push_back(host);
+            }
+        }
+        if (hosts.empty()) hosts.push_back("<invalid>");
+        return hosts;
+    }
+
+    static std::vector<std::string> ToStrings(const ScopedAddrinfo& ai) {
+        return ToStrings(ai.get());
+    }
+
+    size_t GetNumQueries(const test::DNSResponder& dns, const char* name) const {
+        auto queries = dns.queries();
+        size_t found = 0;
+        for (const auto& p : queries) {
+            if (p.first == name) {
+                ++found;
+            }
+        }
+        return found;
+    }
+
+    size_t GetNumQueriesForType(const test::DNSResponder& dns, ns_type type,
+                                const char* name) const {
+        auto queries = dns.queries();
+        size_t found = 0;
+        for (const auto& p : queries) {
+            if (p.second == type && p.first == name) {
+                ++found;
+            }
+        }
+        return found;
+    }
+
+    bool WaitForPrefix64Detected(int netId, int timeoutMs) {
+        constexpr int intervalMs = 2;
+        const int limit = timeoutMs / intervalMs;
+        for (int count = 0; count <= limit; ++count) {
+            std::string prefix;
+            auto rv = mDnsClient.resolvService()->getPrefix64(netId, &prefix);
+            if (rv.isOk()) {
+                return true;
+            }
+            usleep(intervalMs * 1000);
+        }
+        return false;
+    }
+
+    void RunGetAddrInfoStressTest_Binder(unsigned num_hosts, unsigned num_threads,
+            unsigned num_queries) {
+        std::vector<std::string> domains = { "example.com" };
+        std::vector<std::unique_ptr<test::DNSResponder>> dns;
+        std::vector<std::string> servers;
+        std::vector<DnsResponderClient::DnsResponderClient::Mapping> mappings;
+        ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(num_hosts, domains, &mappings));
+        ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(MAXNS, mappings, &dns, &servers));
+
+        ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains, kDefaultParams));
+
+        auto t0 = std::chrono::steady_clock::now();
+        std::vector<std::thread> threads(num_threads);
+        for (std::thread& thread : threads) {
+            thread = std::thread([&mappings, num_queries]() {
+                for (unsigned i = 0 ; i < num_queries ; ++i) {
+                    uint32_t ofs = arc4random_uniform(mappings.size());
+                    auto& mapping = mappings[ofs];
+                    addrinfo* result = nullptr;
+                    int rv = getaddrinfo(mapping.host.c_str(), nullptr, nullptr, &result);
+                    EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
+                    if (rv == 0) {
+                        std::string result_str = ToString(result);
+                        EXPECT_TRUE(result_str == mapping.ip4 || result_str == mapping.ip6)
+                            << "result='" << result_str << "', ip4='" << mapping.ip4
+                            << "', ip6='" << mapping.ip6;
+                    }
+                    if (result) {
+                        freeaddrinfo(result);
+                        result = nullptr;
+                    }
+                }
+            });
+        }
+
+        for (std::thread& thread : threads) {
+            thread.join();
+        }
+        auto t1 = std::chrono::steady_clock::now();
+        ALOGI("%u hosts, %u threads, %u queries, %Es", num_hosts, num_threads, num_queries,
+                std::chrono::duration<double>(t1 - t0).count());
+
+        std::vector<std::string> res_servers;
+        std::vector<std::string> res_domains;
+        std::vector<std::string> res_tls_servers;
+        res_params res_params;
+        std::vector<ResolverStats> res_stats;
+        int wait_for_pending_req_timeout_count;
+        ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
+                                    &res_stats, &wait_for_pending_req_timeout_count));
+        EXPECT_EQ(0, wait_for_pending_req_timeout_count);
+    }
+
+    void StartDns(test::DNSResponder& dns, const std::vector<DnsRecord>& records) {
+        for (const auto& r : records) {
+            dns.addMapping(r.host_name, r.type, r.addr);
+        }
+
+        ASSERT_TRUE(dns.startServer());
+        dns.clearQueries();
+    }
+
+    DnsResponderClient mDnsClient;
+
+    static constexpr char kLocalHost[] = "localhost";
+    static constexpr char kLocalHostAddr[] = "127.0.0.1";
+    static constexpr char kIp6LocalHost[] = "ip6-localhost";
+    static constexpr char kIp6LocalHostAddr[] = "::1";
+    static constexpr char kHelloExampleCom[] = "hello.example.com.";
+};
+
+TEST_F(ResolverTest, GetHostByName) {
+    constexpr char nonexistent_host_name[] = "nonexistent.example.com.";
+
+    test::DNSResponder dns;
+    StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.3"}});
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    const hostent* result;
+    result = gethostbyname("nonexistent");
+    EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, nonexistent_host_name));
+    ASSERT_TRUE(result == nullptr);
+    ASSERT_EQ(HOST_NOT_FOUND, h_errno);
+
+    dns.clearQueries();
+    result = gethostbyname("hello");
+    EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
+    ASSERT_FALSE(result == nullptr);
+    ASSERT_EQ(4, result->h_length);
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ("1.2.3.3", ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+}
+
+TEST_F(ResolverTest, GetHostByName_cnames) {
+    constexpr char host_name[] = "host.example.com.";
+    size_t cnamecount = 0;
+    test::DNSResponder dns;
+
+    const std::vector<DnsRecord> records = {
+            {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
+            {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
+            {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
+            {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
+            {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
+            {"e.example.com.", ns_type::ns_t_cname, host_name},
+            {host_name, ns_type::ns_t_a, "1.2.3.3"},
+            {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
+    };
+    StartDns(dns, records);
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    // using gethostbyname2() to resolve ipv4 hello.example.com. to 1.2.3.3
+    // Ensure the v4 address and cnames are correct
+    const hostent* result;
+    result = gethostbyname2("hello", AF_INET);
+    ASSERT_FALSE(result == nullptr);
+
+    for (int i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
+        std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
+        EXPECT_EQ(result->h_aliases[i], domain_name);
+        cnamecount++;
+    }
+    // The size of "Non-cname type" record in DNS records is 2
+    ASSERT_EQ(cnamecount, records.size() - 2);
+    ASSERT_EQ(4, result->h_length);
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ("1.2.3.3", ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+    EXPECT_EQ(1U, dns.queries().size()) << dns.dumpQueries();
+
+    // using gethostbyname2() to resolve ipv6 hello.example.com. to 2001:db8::42
+    // Ensure the v6 address and cnames are correct
+    cnamecount = 0;
+    dns.clearQueries();
+    result = gethostbyname2("hello", AF_INET6);
+    for (unsigned i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
+        std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
+        EXPECT_EQ(result->h_aliases[i], domain_name);
+        cnamecount++;
+    }
+    // The size of "Non-cname type" DNS record in records is 2
+    ASSERT_EQ(cnamecount, records.size() - 2);
+    ASSERT_FALSE(result == nullptr);
+    ASSERT_EQ(16, result->h_length);
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ("2001:db8::42", ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+}
+
+TEST_F(ResolverTest, GetHostByName_cnamesInfiniteLoop) {
+    test::DNSResponder dns;
+    const std::vector<DnsRecord> records = {
+            {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
+            {"a.example.com.", ns_type::ns_t_cname, kHelloExampleCom},
+    };
+    StartDns(dns, records);
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    const hostent* result;
+    result = gethostbyname2("hello", AF_INET);
+    ASSERT_TRUE(result == nullptr);
+
+    dns.clearQueries();
+    result = gethostbyname2("hello", AF_INET6);
+    ASSERT_TRUE(result == nullptr);
+}
+
+TEST_F(ResolverTest, GetHostByName_localhost) {
+    constexpr char name_camelcase[] = "LocalHost";
+    constexpr char name_ip6_dot[] = "ip6-localhost.";
+    constexpr char name_ip6_fqdn[] = "ip6-localhost.example.com.";
+
+    // Add a dummy nameserver which shouldn't receive any queries
+    test::DNSResponder dns;
+    StartDns(dns, {});
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    // Expect no DNS queries; localhost is resolved via /etc/hosts
+    const hostent* result = gethostbyname(kLocalHost);
+    EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
+    ASSERT_FALSE(result == nullptr);
+    ASSERT_EQ(4, result->h_length);
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ(kLocalHostAddr, ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+
+    // Ensure the hosts file resolver ignores case of hostnames
+    result = gethostbyname(name_camelcase);
+    EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
+    ASSERT_FALSE(result == nullptr);
+    ASSERT_EQ(4, result->h_length);
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ(kLocalHostAddr, ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+
+    // The hosts file also contains ip6-localhost, but gethostbyname() won't
+    // return it unless the RES_USE_INET6 option is set. This would be easy to
+    // change, but there's no point in changing the legacy behavior; new code
+    // should be calling getaddrinfo() anyway.
+    // So we check the legacy behavior, which results in amusing A-record
+    // lookups for ip6-localhost, with and without search domains appended.
+    dns.clearQueries();
+    result = gethostbyname(kIp6LocalHost);
+    EXPECT_EQ(2U, dns.queries().size()) << dns.dumpQueries();
+    EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_dot)) << dns.dumpQueries();
+    EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_fqdn)) << dns.dumpQueries();
+    ASSERT_TRUE(result == nullptr);
+
+    // Finally, use gethostbyname2() to resolve ip6-localhost to ::1 from
+    // the hosts file.
+    dns.clearQueries();
+    result = gethostbyname2(kIp6LocalHost, AF_INET6);
+    EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
+    ASSERT_FALSE(result == nullptr);
+    ASSERT_EQ(16, result->h_length);
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+}
+
+TEST_F(ResolverTest, GetHostByName_numeric) {
+    // Add a dummy nameserver which shouldn't receive any queries
+    test::DNSResponder dns;
+    StartDns(dns, {});
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    // Numeric v4 address: expect no DNS queries
+    constexpr char numeric_v4[] = "192.168.0.1";
+    const hostent* result = gethostbyname(numeric_v4);
+    EXPECT_EQ(0U, dns.queries().size());
+    ASSERT_FALSE(result == nullptr);
+    ASSERT_EQ(4, result->h_length);  // v4
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ(numeric_v4, ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+
+    // gethostbyname() recognizes a v6 address, and fails with no DNS queries
+    constexpr char numeric_v6[] = "2001:db8::42";
+    dns.clearQueries();
+    result = gethostbyname(numeric_v6);
+    EXPECT_EQ(0U, dns.queries().size());
+    EXPECT_TRUE(result == nullptr);
+
+    // Numeric v6 address with gethostbyname2(): succeeds with no DNS queries
+    dns.clearQueries();
+    result = gethostbyname2(numeric_v6, AF_INET6);
+    EXPECT_EQ(0U, dns.queries().size());
+    ASSERT_FALSE(result == nullptr);
+    ASSERT_EQ(16, result->h_length);  // v6
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ(numeric_v6, ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+
+    // Numeric v6 address with scope work with getaddrinfo(),
+    // but gethostbyname2() does not understand them; it issues two dns
+    // queries, then fails. This hardly ever happens, there's no point
+    // in fixing this. This test simply verifies the current (bogus)
+    // behavior to avoid further regressions (like crashes, or leaks).
+    constexpr char numeric_v6_scope[] = "fe80::1%lo";
+    dns.clearQueries();
+    result = gethostbyname2(numeric_v6_scope, AF_INET6);
+    EXPECT_EQ(2U, dns.queries().size());  // OUCH!
+    ASSERT_TRUE(result == nullptr);
+}
+
+TEST_F(ResolverTest, BinderSerialization) {
+    using android::net::IDnsResolver;
+    std::vector<int> params_offsets = {
+            IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY,
+            IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD,
+            IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES,
+            IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES,
+            IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC,
+            IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT,
+    };
+    const int size = static_cast<int>(params_offsets.size());
+    EXPECT_EQ(size, IDnsResolver::RESOLVER_PARAMS_COUNT);
+    std::sort(params_offsets.begin(), params_offsets.end());
+    for (int i = 0; i < size; ++i) {
+        EXPECT_EQ(params_offsets[i], i);
+    }
+}
+
+TEST_F(ResolverTest, GetHostByName_Binder) {
+    using android::net::IDnsResolver;
+
+    std::vector<std::string> domains = { "example.com" };
+    std::vector<std::unique_ptr<test::DNSResponder>> dns;
+    std::vector<std::string> servers;
+    std::vector<DnsResponderClient::Mapping> mappings;
+    ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
+    ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(4, mappings, &dns, &servers));
+    ASSERT_EQ(1U, mappings.size());
+    const DnsResponderClient::Mapping& mapping = mappings[0];
+
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains, kDefaultParams));
+
+    const hostent* result = gethostbyname(mapping.host.c_str());
+    const size_t total_queries =
+            std::accumulate(dns.begin(), dns.end(), 0, [this, &mapping](size_t total, auto& d) {
+                return total + GetNumQueriesForType(*d, ns_type::ns_t_a, mapping.entry.c_str());
+            });
+
+    EXPECT_LE(1U, total_queries);
+    ASSERT_FALSE(result == nullptr);
+    ASSERT_EQ(4, result->h_length);
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ(mapping.ip4, ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+
+    std::vector<std::string> res_servers;
+    std::vector<std::string> res_domains;
+    std::vector<std::string> res_tls_servers;
+    res_params res_params;
+    std::vector<ResolverStats> res_stats;
+    int wait_for_pending_req_timeout_count;
+    ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
+                                &res_stats, &wait_for_pending_req_timeout_count));
+    EXPECT_EQ(servers.size(), res_servers.size());
+    EXPECT_EQ(domains.size(), res_domains.size());
+    EXPECT_EQ(0U, res_tls_servers.size());
+    ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
+    EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
+              res_params.sample_validity);
+    EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
+              res_params.success_threshold);
+    EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
+    EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
+    EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
+              res_params.base_timeout_msec);
+    EXPECT_EQ(servers.size(), res_stats.size());
+
+    EXPECT_THAT(res_servers, testing::UnorderedElementsAreArray(servers));
+    EXPECT_THAT(res_domains, testing::UnorderedElementsAreArray(domains));
+}
+
+TEST_F(ResolverTest, GetAddrInfo) {
+    constexpr char listen_addr[] = "127.0.0.4";
+    constexpr char listen_addr2[] = "127.0.0.5";
+    constexpr char host_name[] = "howdy.example.com.";
+
+    const std::vector<DnsRecord> records = {
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
+    };
+    test::DNSResponder dns(listen_addr);
+    test::DNSResponder dns2(listen_addr2);
+    StartDns(dns, records);
+    StartDns(dns2, records);
+
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr}));
+    dns.clearQueries();
+    dns2.clearQueries();
+
+    ScopedAddrinfo result = safe_getaddrinfo("howdy", nullptr, nullptr);
+    EXPECT_TRUE(result != nullptr);
+    size_t found = GetNumQueries(dns, host_name);
+    EXPECT_LE(1U, found);
+    // Could be A or AAAA
+    std::string result_str = ToString(result);
+    EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
+        << ", result_str='" << result_str << "'";
+
+    // Verify that the name is cached.
+    size_t old_found = found;
+    result = safe_getaddrinfo("howdy", nullptr, nullptr);
+    EXPECT_TRUE(result != nullptr);
+    found = GetNumQueries(dns, host_name);
+    EXPECT_LE(1U, found);
+    EXPECT_EQ(old_found, found);
+    result_str = ToString(result);
+    EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
+        << result_str;
+
+    // Change the DNS resolver, ensure that queries are still cached.
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
+    dns.clearQueries();
+    dns2.clearQueries();
+
+    result = safe_getaddrinfo("howdy", nullptr, nullptr);
+    EXPECT_TRUE(result != nullptr);
+    found = GetNumQueries(dns, host_name);
+    size_t found2 = GetNumQueries(dns2, host_name);
+    EXPECT_EQ(0U, found);
+    EXPECT_LE(0U, found2);
+
+    // Could be A or AAAA
+    result_str = ToString(result);
+    EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
+        << ", result_str='" << result_str << "'";
+}
+
+TEST_F(ResolverTest, GetAddrInfoV4) {
+    test::DNSResponder dns;
+    StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    const addrinfo hints = {.ai_family = AF_INET};
+    ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
+    EXPECT_EQ("1.2.3.5", ToString(result));
+}
+
+TEST_F(ResolverTest, GetAddrInfo_localhost) {
+    // Add a dummy nameserver which shouldn't receive any queries
+    test::DNSResponder dns;
+    StartDns(dns, {});
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    ScopedAddrinfo result = safe_getaddrinfo(kLocalHost, nullptr, nullptr);
+    EXPECT_TRUE(result != nullptr);
+    // Expect no DNS queries; localhost is resolved via /etc/hosts
+    EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
+    EXPECT_EQ(kLocalHostAddr, ToString(result));
+
+    result = safe_getaddrinfo(kIp6LocalHost, nullptr, nullptr);
+    EXPECT_TRUE(result != nullptr);
+    // Expect no DNS queries; ip6-localhost is resolved via /etc/hosts
+    EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
+    EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
+}
+
+// Verify if the resolver correctly handle multiple queries simultaneously
+// step 1: set dns server#1 into deferred responding mode.
+// step 2: thread#1 query "hello.example.com." --> resolver send query to server#1.
+// step 3: thread#2 query "hello.example.com." --> resolver hold the request and wait for
+//           response of previous pending query sent by thread#1.
+// step 4: thread#3 query "konbanha.example.com." --> resolver send query to server#3. Server
+//           respond to resolver immediately.
+// step 5: check if server#1 get 1 query by thread#1, server#2 get 0 query, server#3 get 1 query.
+// step 6: resume dns server#1 to respond dns query in step#2.
+// step 7: thread#1 and #2 should get returned from DNS query after step#6. Also, check the
+//           number of queries in server#2 is 0 to ensure thread#2 does not wake up unexpectedly
+//           before signaled by thread#1.
+TEST_F(ResolverTest, GetAddrInfoV4_deferred_resp) {
+    const char* listen_addr1 = "127.0.0.9";
+    const char* listen_addr2 = "127.0.0.10";
+    const char* listen_addr3 = "127.0.0.11";
+    const char* listen_srv = "53";
+    const char* host_name_deferred = "hello.example.com.";
+    const char* host_name_normal = "konbanha.example.com.";
+    test::DNSResponder dns1(listen_addr1, listen_srv, 250, ns_rcode::ns_r_servfail);
+    test::DNSResponder dns2(listen_addr2, listen_srv, 250, ns_rcode::ns_r_servfail);
+    test::DNSResponder dns3(listen_addr3, listen_srv, 250, ns_rcode::ns_r_servfail);
+    dns1.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
+    dns2.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
+    dns3.addMapping(host_name_normal, ns_type::ns_t_a, "1.2.3.5");
+    ASSERT_TRUE(dns1.startServer());
+    ASSERT_TRUE(dns2.startServer());
+    ASSERT_TRUE(dns3.startServer());
+    const std::vector<std::string> servers_for_t1 = {listen_addr1};
+    const std::vector<std::string> servers_for_t2 = {listen_addr2};
+    const std::vector<std::string> servers_for_t3 = {listen_addr3};
+    addrinfo hints = {.ai_family = AF_INET};
+    const std::vector<int> params = {300, 25, 8, 8, 5000};
+    bool t3_task_done = false;
+
+    dns1.setDeferredResp(true);
+    std::thread t1([&, this]() {
+        ASSERT_TRUE(
+                mDnsClient.SetResolversForNetwork(servers_for_t1, kDefaultSearchDomains, params));
+        ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
+        // t3's dns query should got returned first
+        EXPECT_TRUE(t3_task_done);
+        EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
+        EXPECT_TRUE(result != nullptr);
+        EXPECT_EQ("1.2.3.4", ToString(result));
+    });
+
+    // ensuring t1 and t2 handler functions are processed in order
+    usleep(100 * 1000);
+    std::thread t2([&, this]() {
+        ASSERT_TRUE(
+                mDnsClient.SetResolversForNetwork(servers_for_t2, kDefaultSearchDomains, params));
+        ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
+        EXPECT_TRUE(t3_task_done);
+        EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
+        EXPECT_TRUE(result != nullptr);
+        EXPECT_EQ("1.2.3.4", ToString(result));
+
+        std::vector<std::string> res_servers;
+        std::vector<std::string> res_domains;
+        std::vector<std::string> res_tls_servers;
+        res_params res_params;
+        std::vector<ResolverStats> res_stats;
+        int wait_for_pending_req_timeout_count;
+        ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
+                                    &res_stats, &wait_for_pending_req_timeout_count));
+        EXPECT_EQ(0, wait_for_pending_req_timeout_count);
+    });
+
+    // ensuring t2 and t3 handler functions are processed in order
+    usleep(100 * 1000);
+    std::thread t3([&, this]() {
+        ASSERT_TRUE(
+                mDnsClient.SetResolversForNetwork(servers_for_t3, kDefaultSearchDomains, params));
+        ScopedAddrinfo result = safe_getaddrinfo(host_name_normal, nullptr, &hints);
+        EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
+        EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
+        EXPECT_EQ(1U, GetNumQueries(dns3, host_name_normal));
+        EXPECT_TRUE(result != nullptr);
+        EXPECT_EQ("1.2.3.5", ToString(result));
+
+        t3_task_done = true;
+        dns1.setDeferredResp(false);
+    });
+    t3.join();
+    t1.join();
+    t2.join();
+}
+
+TEST_F(ResolverTest, GetAddrInfo_cnames) {
+    constexpr char host_name[] = "host.example.com.";
+    test::DNSResponder dns;
+    const std::vector<DnsRecord> records = {
+            {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
+            {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
+            {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
+            {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
+            {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
+            {"e.example.com.", ns_type::ns_t_cname, host_name},
+            {host_name, ns_type::ns_t_a, "1.2.3.3"},
+            {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
+    };
+    StartDns(dns, records);
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    addrinfo hints = {.ai_family = AF_INET};
+    ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_EQ("1.2.3.3", ToString(result));
+
+    dns.clearQueries();
+    hints = {.ai_family = AF_INET6};
+    result = safe_getaddrinfo("hello", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_EQ("2001:db8::42", ToString(result));
+}
+
+TEST_F(ResolverTest, GetAddrInfo_cnamesNoIpAddress) {
+    test::DNSResponder dns;
+    const std::vector<DnsRecord> records = {
+            {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
+    };
+    StartDns(dns, records);
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    addrinfo hints = {.ai_family = AF_INET};
+    ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
+    EXPECT_TRUE(result == nullptr);
+
+    dns.clearQueries();
+    hints = {.ai_family = AF_INET6};
+    result = safe_getaddrinfo("hello", nullptr, &hints);
+    EXPECT_TRUE(result == nullptr);
+}
+
+TEST_F(ResolverTest, GetAddrInfo_cnamesIllegalRdata) {
+    test::DNSResponder dns;
+    const std::vector<DnsRecord> records = {
+            {kHelloExampleCom, ns_type::ns_t_cname, ".!#?"},
+    };
+    StartDns(dns, records);
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    addrinfo hints = {.ai_family = AF_INET};
+    ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
+    EXPECT_TRUE(result == nullptr);
+
+    dns.clearQueries();
+    hints = {.ai_family = AF_INET6};
+    result = safe_getaddrinfo("hello", nullptr, &hints);
+    EXPECT_TRUE(result == nullptr);
+}
+
+TEST_F(ResolverTest, MultidomainResolution) {
+    constexpr char host_name[] = "nihao.example2.com.";
+    std::vector<std::string> searchDomains = { "example1.com", "example2.com", "example3.com" };
+
+    test::DNSResponder dns("127.0.0.6");
+    StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork({"127.0.0.6"}, searchDomains));
+
+    const hostent* result = gethostbyname("nihao");
+
+    EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
+    ASSERT_FALSE(result == nullptr);
+    ASSERT_EQ(4, result->h_length);
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ("1.2.3.3", ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+}
+
+TEST_F(ResolverTest, GetAddrInfoV6_numeric) {
+    constexpr char host_name[] = "ohayou.example.com.";
+    constexpr char numeric_addr[] = "fe80::1%lo";
+
+    test::DNSResponder dns;
+    dns.setResponseProbability(0.0);
+    StartDns(dns, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    addrinfo hints = {.ai_family = AF_INET6};
+    ScopedAddrinfo result = safe_getaddrinfo(numeric_addr, nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_EQ(numeric_addr, ToString(result));
+    EXPECT_TRUE(dns.queries().empty());  // Ensure no DNS queries were sent out
+
+    // Now try a non-numeric hostname query with the AI_NUMERICHOST flag set.
+    // We should fail without sending out a DNS query.
+    hints.ai_flags |= AI_NUMERICHOST;
+    result = safe_getaddrinfo(host_name, nullptr, &hints);
+    EXPECT_TRUE(result == nullptr);
+    EXPECT_TRUE(dns.queries().empty());  // Ensure no DNS queries were sent out
+}
+
+TEST_F(ResolverTest, GetAddrInfoV6_failing) {
+    constexpr char listen_addr0[] = "127.0.0.7";
+    constexpr char listen_addr1[] = "127.0.0.8";
+    const char* host_name = "ohayou.example.com.";
+
+    test::DNSResponder dns0(listen_addr0);
+    test::DNSResponder dns1(listen_addr1);
+    dns0.setResponseProbability(0.0);
+    StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
+    StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
+
+    std::vector<std::string> servers = { listen_addr0, listen_addr1 };
+    // <sample validity in s> <success threshold in percent> <min samples> <max samples>
+    int sample_count = 8;
+    const std::vector<int> params = { 300, 25, sample_count, sample_count };
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains, params));
+
+    // Repeatedly perform resolutions for non-existing domains until MAXNSSAMPLES resolutions have
+    // reached the dns0, which is set to fail. No more requests should then arrive at that server
+    // for the next sample_lifetime seconds.
+    // TODO: This approach is implementation-dependent, change once metrics reporting is available.
+    const addrinfo hints = {.ai_family = AF_INET6};
+    for (int i = 0; i < sample_count; ++i) {
+        std::string domain = StringPrintf("nonexistent%d", i);
+        ScopedAddrinfo result = safe_getaddrinfo(domain.c_str(), nullptr, &hints);
+    }
+    // Due to 100% errors for all possible samples, the server should be ignored from now on and
+    // only the second one used for all following queries, until NSSAMPLE_VALIDITY is reached.
+    dns0.clearQueries();
+    dns1.clearQueries();
+    ScopedAddrinfo result = safe_getaddrinfo("ohayou", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_EQ(0U, GetNumQueries(dns0, host_name));
+    EXPECT_EQ(1U, GetNumQueries(dns1, host_name));
+}
+
+TEST_F(ResolverTest, GetAddrInfoV6_nonresponsive) {
+    constexpr char listen_addr0[] = "127.0.0.7";
+    constexpr char listen_addr1[] = "127.0.0.8";
+    constexpr char listen_srv[] = "53";
+    constexpr char host_name1[] = "ohayou.example.com.";
+    constexpr char host_name2[] = "ciao.example.com.";
+    const std::vector<DnsRecord> records0 = {
+            {host_name1, ns_type::ns_t_aaaa, "2001:db8::5"},
+            {host_name2, ns_type::ns_t_aaaa, "2001:db8::5"},
+    };
+    const std::vector<DnsRecord> records1 = {
+            {host_name1, ns_type::ns_t_aaaa, "2001:db8::6"},
+            {host_name2, ns_type::ns_t_aaaa, "2001:db8::6"},
+    };
+
+    // dns0 does not respond with 100% probability, while
+    // dns1 responds normally, at least initially.
+    test::DNSResponder dns0(listen_addr0, listen_srv, 250, static_cast<ns_rcode>(-1));
+    test::DNSResponder dns1(listen_addr1, listen_srv, 250, static_cast<ns_rcode>(-1));
+    dns0.setResponseProbability(0.0);
+    StartDns(dns0, records0);
+    StartDns(dns1, records1);
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}));
+
+    const addrinfo hints = {.ai_family = AF_INET6};
+
+    // dns0 will ignore the request, and we'll fallback to dns1 after the first
+    // retry.
+    ScopedAddrinfo result = safe_getaddrinfo(host_name1, nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_EQ(1U, GetNumQueries(dns0, host_name1));
+    EXPECT_EQ(1U, GetNumQueries(dns1, host_name1));
+
+    // Now make dns1 also ignore 100% requests... The resolve should alternate
+    // retries between the nameservers and fail after 4 attempts.
+    dns1.setResponseProbability(0.0);
+    addrinfo* result2 = nullptr;
+    EXPECT_EQ(EAI_NODATA, getaddrinfo(host_name2, nullptr, &hints, &result2));
+    EXPECT_EQ(nullptr, result2);
+    EXPECT_EQ(4U, GetNumQueries(dns0, host_name2));
+    EXPECT_EQ(4U, GetNumQueries(dns1, host_name2));
+}
+
+TEST_F(ResolverTest, GetAddrInfoV6_concurrent) {
+    constexpr char listen_addr0[] = "127.0.0.9";
+    constexpr char listen_addr1[] = "127.0.0.10";
+    constexpr char listen_addr2[] = "127.0.0.11";
+    constexpr char host_name[] = "konbanha.example.com.";
+
+    test::DNSResponder dns0(listen_addr0);
+    test::DNSResponder dns1(listen_addr1);
+    test::DNSResponder dns2(listen_addr2);
+    StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
+    StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
+    StartDns(dns2, {{host_name, ns_type::ns_t_aaaa, "2001:db8::7"}});
+
+    const std::vector<std::string> servers = { listen_addr0, listen_addr1, listen_addr2 };
+    std::vector<std::thread> threads(10);
+    for (std::thread& thread : threads) {
+       thread = std::thread([this, &servers]() {
+            unsigned delay = arc4random_uniform(1*1000*1000); // <= 1s
+            usleep(delay);
+            std::vector<std::string> serverSubset;
+            for (const auto& server : servers) {
+                if (arc4random_uniform(2)) {
+                    serverSubset.push_back(server);
+                }
+            }
+            if (serverSubset.empty()) serverSubset = servers;
+            ASSERT_TRUE(mDnsClient.SetResolversForNetwork(serverSubset));
+            const addrinfo hints = {.ai_family = AF_INET6};
+            addrinfo* result = nullptr;
+            int rv = getaddrinfo("konbanha", nullptr, &hints, &result);
+            EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
+            if (result) {
+                freeaddrinfo(result);
+                result = nullptr;
+            }
+        });
+    }
+    for (std::thread& thread : threads) {
+        thread.join();
+    }
+
+    std::vector<std::string> res_servers;
+    std::vector<std::string> res_domains;
+    std::vector<std::string> res_tls_servers;
+    res_params res_params;
+    std::vector<ResolverStats> res_stats;
+    int wait_for_pending_req_timeout_count;
+    ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
+                                &res_stats, &wait_for_pending_req_timeout_count));
+    EXPECT_EQ(0, wait_for_pending_req_timeout_count);
+}
+
+TEST_F(ResolverTest, GetAddrInfoStressTest_Binder_100) {
+    const unsigned num_hosts = 100;
+    const unsigned num_threads = 100;
+    const unsigned num_queries = 100;
+    ASSERT_NO_FATAL_FAILURE(RunGetAddrInfoStressTest_Binder(num_hosts, num_threads, num_queries));
+}
+
+TEST_F(ResolverTest, GetAddrInfoStressTest_Binder_100000) {
+    const unsigned num_hosts = 100000;
+    const unsigned num_threads = 100;
+    const unsigned num_queries = 100;
+    ASSERT_NO_FATAL_FAILURE(RunGetAddrInfoStressTest_Binder(num_hosts, num_threads, num_queries));
+}
+
+TEST_F(ResolverTest, EmptySetup) {
+    using android::net::IDnsResolver;
+    std::vector<std::string> servers;
+    std::vector<std::string> domains;
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
+    std::vector<std::string> res_servers;
+    std::vector<std::string> res_domains;
+    std::vector<std::string> res_tls_servers;
+    res_params res_params;
+    std::vector<ResolverStats> res_stats;
+    int wait_for_pending_req_timeout_count;
+    ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
+                                &res_stats, &wait_for_pending_req_timeout_count));
+    EXPECT_EQ(0U, res_servers.size());
+    EXPECT_EQ(0U, res_domains.size());
+    EXPECT_EQ(0U, res_tls_servers.size());
+    ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
+    EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
+              res_params.sample_validity);
+    EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
+              res_params.success_threshold);
+    EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
+    EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
+    EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
+              res_params.base_timeout_msec);
+    EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT], res_params.retry_count);
+}
+
+TEST_F(ResolverTest, SearchPathChange) {
+    constexpr char listen_addr[] = "127.0.0.13";
+    constexpr char host_name1[] = "test13.domain1.org.";
+    constexpr char host_name2[] = "test13.domain2.org.";
+    std::vector<std::string> servers = { listen_addr };
+    std::vector<std::string> domains = { "domain1.org" };
+
+    const std::vector<DnsRecord> records = {
+            {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
+            {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
+    };
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
+
+    const addrinfo hints = {.ai_family = AF_INET6};
+    ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_EQ(1U, dns.queries().size());
+    EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
+    EXPECT_EQ("2001:db8::13", ToString(result));
+
+    // Test that changing the domain search path on its own works.
+    domains = { "domain2.org" };
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
+    dns.clearQueries();
+
+    result = safe_getaddrinfo("test13", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_EQ(1U, dns.queries().size());
+    EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
+    EXPECT_EQ("2001:db8::1:13", ToString(result));
+}
+
+static std::string base64Encode(const std::vector<uint8_t>& input) {
+    size_t out_len;
+    EXPECT_EQ(1, EVP_EncodedLength(&out_len, input.size()));
+    // out_len includes the trailing NULL.
+    uint8_t output_bytes[out_len];
+    EXPECT_EQ(out_len - 1, EVP_EncodeBlock(output_bytes, input.data(), input.size()));
+    return std::string(reinterpret_cast<char*>(output_bytes));
+}
+
+// If we move this function to dns_responder_client, it will complicate the dependency need of
+// dns_tls_frontend.h.
+static void setupTlsServers(const std::vector<std::string>& servers,
+                            std::vector<std::unique_ptr<test::DnsTlsFrontend>>* tls,
+                            std::vector<std::string>* fingerprints) {
+    constexpr char listen_udp[] = "53";
+    constexpr char listen_tls[] = "853";
+
+    for (const auto& server : servers) {
+        auto t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
+        t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
+        t->startServer();
+        fingerprints->push_back(base64Encode(t->fingerprint()));
+        tls->push_back(std::move(t));
+    }
+}
+
+TEST_F(ResolverTest, MaxServerPrune_Binder) {
+    std::vector<std::string> domains;
+    std::vector<std::unique_ptr<test::DNSResponder>> dns;
+    std::vector<std::unique_ptr<test::DnsTlsFrontend>> tls;
+    std::vector<std::string> servers;
+    std::vector<std::string> fingerprints;
+    std::vector<DnsResponderClient::Mapping> mappings;
+
+    for (unsigned i = 0; i < MAXDNSRCH + 1; i++) {
+        domains.push_back(StringPrintf("example%u.com", i));
+    }
+    ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
+    ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(MAXNS + 1, mappings, &dns, &servers));
+    ASSERT_NO_FATAL_FAILURE(setupTlsServers(servers, &tls, &fingerprints));
+
+    ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, domains, kDefaultParams, "", fingerprints));
+
+    // If the private DNS validation hasn't completed yet before backend DNS servers stop,
+    // TLS servers will get stuck in handleOneRequest(), which causes this test stuck in
+    // ~DnsTlsFrontend() because the TLS server loop threads can't be terminated.
+    // So, wait for private DNS validation done before stopping backend DNS servers.
+    for (int i = 0; i < MAXNS; i++) {
+        ALOGI("Waiting for private DNS validation on %s.", tls[i]->listen_address().c_str());
+        EXPECT_TRUE(tls[i]->waitForQueries(1, 5000));
+        ALOGI("private DNS validation on %s done.", tls[i]->listen_address().c_str());
+    }
+
+    std::vector<std::string> res_servers;
+    std::vector<std::string> res_domains;
+    std::vector<std::string> res_tls_servers;
+    res_params res_params;
+    std::vector<ResolverStats> res_stats;
+    int wait_for_pending_req_timeout_count;
+    ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
+                                &res_stats, &wait_for_pending_req_timeout_count));
+
+    // Check the size of the stats and its contents.
+    EXPECT_EQ(static_cast<size_t>(MAXNS), res_servers.size());
+    EXPECT_EQ(static_cast<size_t>(MAXNS), res_tls_servers.size());
+    EXPECT_EQ(static_cast<size_t>(MAXDNSRCH), res_domains.size());
+    EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_servers.begin()));
+    EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_tls_servers.begin()));
+    EXPECT_TRUE(std::equal(domains.begin(), domains.begin() + MAXDNSRCH, res_domains.begin()));
+}
+
+TEST_F(ResolverTest, ResolverStats) {
+    constexpr char listen_addr1[] = "127.0.0.4";
+    constexpr char listen_addr2[] = "127.0.0.5";
+    constexpr char listen_addr3[] = "127.0.0.6";
+
+    // Set server 1 timeout.
+    test::DNSResponder dns1(listen_addr1, "53", 250, static_cast<ns_rcode>(-1));
+    dns1.setResponseProbability(0.0);
+    ASSERT_TRUE(dns1.startServer());
+
+    // Set server 2 responding server failure.
+    test::DNSResponder dns2(listen_addr2);
+    dns2.setResponseProbability(0.0);
+    ASSERT_TRUE(dns2.startServer());
+
+    // Set server 3 workable.
+    test::DNSResponder dns3(listen_addr3);
+    dns3.addMapping(kHelloExampleCom, ns_type::ns_t_a, "1.2.3.4");
+    ASSERT_TRUE(dns3.startServer());
+
+    std::vector<std::string> servers = {listen_addr1, listen_addr2, listen_addr3};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    dns3.clearQueries();
+    const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
+    ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
+    size_t found = GetNumQueries(dns3, kHelloExampleCom);
+    EXPECT_LE(1U, found);
+    std::string result_str = ToString(result);
+    EXPECT_TRUE(result_str == "1.2.3.4") << ", result_str='" << result_str << "'";
+
+    std::vector<std::string> res_servers;
+    std::vector<std::string> res_domains;
+    std::vector<std::string> res_tls_servers;
+    res_params res_params;
+    std::vector<ResolverStats> res_stats;
+    int wait_for_pending_req_timeout_count;
+    ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
+                                &res_stats, &wait_for_pending_req_timeout_count));
+
+    EXPECT_EQ(1, res_stats[0].timeouts);
+    EXPECT_EQ(1, res_stats[1].errors);
+    EXPECT_EQ(1, res_stats[2].successes);
+}
+
+// Test what happens if the specified TLS server is nonexistent.
+TEST_F(ResolverTest, GetHostByName_TlsMissing) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char host_name[] = "tlsmissing.example.com.";
+
+    test::DNSResponder dns;
+    StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
+    std::vector<std::string> servers = { listen_addr };
+
+    // There's nothing listening on this address, so validation will either fail or
+    /// hang.  Either way, queries will continue to flow to the DNSResponder.
+    ASSERT_TRUE(
+            mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "", {}));
+
+    const hostent* result;
+
+    result = gethostbyname("tlsmissing");
+    ASSERT_FALSE(result == nullptr);
+    EXPECT_EQ("1.2.3.3", ToString(result));
+
+    // Clear TLS bit.
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+}
+
+// Test what happens if the specified TLS server replies with garbage.
+TEST_F(ResolverTest, GetHostByName_TlsBroken) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char host_name1[] = "tlsbroken1.example.com.";
+    constexpr char host_name2[] = "tlsbroken2.example.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name1, ns_type::ns_t_a, "1.2.3.1"},
+            {host_name2, ns_type::ns_t_a, "1.2.3.2"},
+    };
+
+    test::DNSResponder dns;
+    StartDns(dns, records);
+    std::vector<std::string> servers = { listen_addr };
+
+    // Bind the specified private DNS socket but don't respond to any client sockets yet.
+    int s = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
+    ASSERT_TRUE(s >= 0);
+    struct sockaddr_in tlsServer = {
+        .sin_family = AF_INET,
+        .sin_port = htons(853),
+    };
+    ASSERT_TRUE(inet_pton(AF_INET, listen_addr, &tlsServer.sin_addr));
+    ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEPORT).ok());
+    ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEADDR).ok());
+    ASSERT_FALSE(bind(s, reinterpret_cast<struct sockaddr*>(&tlsServer), sizeof(tlsServer)));
+    ASSERT_FALSE(listen(s, 1));
+
+    // Trigger TLS validation.
+    ASSERT_TRUE(
+            mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "", {}));
+
+    struct sockaddr_storage cliaddr;
+    socklen_t sin_size = sizeof(cliaddr);
+    int new_fd = accept4(s, reinterpret_cast<struct sockaddr *>(&cliaddr), &sin_size, SOCK_CLOEXEC);
+    ASSERT_TRUE(new_fd > 0);
+
+    // We've received the new file descriptor but not written to it or closed, so the
+    // validation is still pending.  Queries should still flow correctly because the
+    // server is not used until validation succeeds.
+    const hostent* result;
+    result = gethostbyname("tlsbroken1");
+    ASSERT_FALSE(result == nullptr);
+    EXPECT_EQ("1.2.3.1", ToString(result));
+
+    // Now we cause the validation to fail.
+    std::string garbage = "definitely not a valid TLS ServerHello";
+    write(new_fd, garbage.data(), garbage.size());
+    close(new_fd);
+
+    // Validation failure shouldn't interfere with lookups, because lookups won't be sent
+    // to the TLS server unless validation succeeds.
+    result = gethostbyname("tlsbroken2");
+    ASSERT_FALSE(result == nullptr);
+    EXPECT_EQ("1.2.3.2", ToString(result));
+
+    // Clear TLS bit.
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+    close(s);
+}
+
+TEST_F(ResolverTest, GetHostByName_Tls) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_udp[] = "53";
+    constexpr char listen_tls[] = "853";
+    constexpr char host_name1[] = "tls1.example.com.";
+    constexpr char host_name2[] = "tls2.example.com.";
+    constexpr char host_name3[] = "tls3.example.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name1, ns_type::ns_t_a, "1.2.3.1"},
+            {host_name2, ns_type::ns_t_a, "1.2.3.2"},
+            {host_name3, ns_type::ns_t_a, "1.2.3.3"},
+    };
+
+    test::DNSResponder dns;
+    StartDns(dns, records);
+    std::vector<std::string> servers = { listen_addr };
+
+    test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
+    ASSERT_TRUE(tls.startServer());
+    ASSERT_TRUE(
+            mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "", {}));
+
+    const hostent* result;
+
+    // Wait for validation to complete.
+    EXPECT_TRUE(tls.waitForQueries(1, 5000));
+
+    result = gethostbyname("tls1");
+    ASSERT_FALSE(result == nullptr);
+    EXPECT_EQ("1.2.3.1", ToString(result));
+
+    // Wait for query to get counted.
+    EXPECT_TRUE(tls.waitForQueries(2, 5000));
+
+    // Stop the TLS server.  Since we're in opportunistic mode, queries will
+    // fall back to the locally-assigned (clear text) nameservers.
+    tls.stopServer();
+
+    dns.clearQueries();
+    result = gethostbyname("tls2");
+    EXPECT_FALSE(result == nullptr);
+    EXPECT_EQ("1.2.3.2", ToString(result));
+    const auto queries = dns.queries();
+    EXPECT_EQ(1U, queries.size());
+    EXPECT_EQ("tls2.example.com.", queries[0].first);
+    EXPECT_EQ(ns_t_a, queries[0].second);
+
+    // Reset the resolvers without enabling TLS.  Queries should still be routed
+    // to the UDP endpoint.
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+    result = gethostbyname("tls3");
+    ASSERT_FALSE(result == nullptr);
+    EXPECT_EQ("1.2.3.3", ToString(result));
+}
+
+TEST_F(ResolverTest, GetHostByName_TlsFingerprint) {
+    // Certificate fingerprints are no longer supported by the module.
+    SKIP_IF_RESOLVER_VERSION_NEWER_THAN(mDnsClient.resolvService(), 2);
+
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_udp[] = "53";
+    constexpr char listen_tls[] = "853";
+    test::DNSResponder dns;
+    ASSERT_TRUE(dns.startServer());
+    for (int chain_length = 1; chain_length <= 3; ++chain_length) {
+        std::string host_name = StringPrintf("tlsfingerprint%d.example.com.", chain_length);
+        dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.1");
+        std::vector<std::string> servers = { listen_addr };
+
+        test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
+        tls.set_chain_length(chain_length);
+        ASSERT_TRUE(tls.startServer());
+        ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
+                                                   "", {base64Encode(tls.fingerprint())}));
+
+        const hostent* result;
+
+        // Wait for validation to complete.
+        EXPECT_TRUE(tls.waitForQueries(1, 5000));
+
+        result = gethostbyname(StringPrintf("tlsfingerprint%d", chain_length).c_str());
+        EXPECT_FALSE(result == nullptr);
+        if (result) {
+            EXPECT_EQ("1.2.3.1", ToString(result));
+
+            // Wait for query to get counted.
+            EXPECT_TRUE(tls.waitForQueries(2, 5000));
+        }
+
+        // Clear TLS bit to ensure revalidation.
+        ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+        tls.stopServer();
+    }
+}
+
+TEST_F(ResolverTest, GetHostByName_BadTlsFingerprint) {
+    // Certificate fingerprints are no longer supported by the module.
+    SKIP_IF_RESOLVER_VERSION_NEWER_THAN(mDnsClient.resolvService(), 2);
+
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_udp[] = "53";
+    constexpr char listen_tls[] = "853";
+    constexpr char host_name[] = "badtlsfingerprint.example.com.";
+
+    test::DNSResponder dns;
+    StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
+    std::vector<std::string> servers = { listen_addr };
+
+    test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
+    ASSERT_TRUE(tls.startServer());
+    std::vector<uint8_t> bad_fingerprint = tls.fingerprint();
+    bad_fingerprint[5] += 1;  // Corrupt the fingerprint.
+    ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "",
+                                               {base64Encode(bad_fingerprint)}));
+
+    // The initial validation should fail at the fingerprint check before
+    // issuing a query.
+    EXPECT_FALSE(tls.waitForQueries(1, 500));
+
+    // A fingerprint was provided and failed to match, so the query should fail.
+    EXPECT_EQ(nullptr, gethostbyname("badtlsfingerprint"));
+
+    // Clear TLS bit.
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+}
+
+// Test that we can pass two different fingerprints, and connection succeeds as long as
+// at least one of them matches the server.
+TEST_F(ResolverTest, GetHostByName_TwoTlsFingerprints) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_udp[] = "53";
+    constexpr char listen_tls[] = "853";
+    constexpr char host_name[] = "twotlsfingerprints.example.com.";
+
+    test::DNSResponder dns;
+    StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
+    std::vector<std::string> servers = { listen_addr };
+
+    test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
+    ASSERT_TRUE(tls.startServer());
+    std::vector<uint8_t> bad_fingerprint = tls.fingerprint();
+    bad_fingerprint[5] += 1;  // Corrupt the fingerprint.
+    ASSERT_TRUE(mDnsClient.SetResolversWithTls(
+            servers, kDefaultSearchDomains, kDefaultParams, "",
+            {base64Encode(bad_fingerprint), base64Encode(tls.fingerprint())}));
+
+    const hostent* result;
+
+    // Wait for validation to complete.
+    EXPECT_TRUE(tls.waitForQueries(1, 5000));
+
+    result = gethostbyname("twotlsfingerprints");
+    ASSERT_FALSE(result == nullptr);
+    EXPECT_EQ("1.2.3.1", ToString(result));
+
+    // Wait for query to get counted.
+    EXPECT_TRUE(tls.waitForQueries(2, 5000));
+
+    // Clear TLS bit.
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+}
+
+TEST_F(ResolverTest, GetHostByName_TlsFingerprintGoesBad) {
+    // Certificate fingerprints are no longer supported by the module.
+    SKIP_IF_RESOLVER_VERSION_NEWER_THAN(mDnsClient.resolvService(), 2);
+
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_udp[] = "53";
+    constexpr char listen_tls[] = "853";
+    constexpr char host_name1[] = "tlsfingerprintgoesbad1.example.com.";
+    constexpr char host_name2[] = "tlsfingerprintgoesbad2.example.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name1, ns_type::ns_t_a, "1.2.3.1"},
+            {host_name2, ns_type::ns_t_a, "1.2.3.2"},
+    };
+
+    test::DNSResponder dns;
+    StartDns(dns, records);
+    std::vector<std::string> servers = { listen_addr };
+
+    test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
+    ASSERT_TRUE(tls.startServer());
+    ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "",
+                                               {base64Encode(tls.fingerprint())}));
+
+    const hostent* result;
+
+    // Wait for validation to complete.
+    EXPECT_TRUE(tls.waitForQueries(1, 5000));
+
+    result = gethostbyname("tlsfingerprintgoesbad1");
+    ASSERT_FALSE(result == nullptr);
+    EXPECT_EQ("1.2.3.1", ToString(result));
+
+    // Wait for query to get counted.
+    EXPECT_TRUE(tls.waitForQueries(2, 5000));
+
+    // Restart the TLS server.  This will generate a new certificate whose fingerprint
+    // no longer matches the stored fingerprint.
+    tls.stopServer();
+    tls.startServer();
+
+    result = gethostbyname("tlsfingerprintgoesbad2");
+    ASSERT_TRUE(result == nullptr);
+    EXPECT_EQ(HOST_NOT_FOUND, h_errno);
+
+    // Clear TLS bit.
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+}
+
+TEST_F(ResolverTest, GetHostByName_TlsFailover) {
+    constexpr char listen_addr1[] = "127.0.0.3";
+    constexpr char listen_addr2[] = "127.0.0.4";
+    constexpr char listen_udp[] = "53";
+    constexpr char listen_tls[] = "853";
+    constexpr char host_name1[] = "tlsfailover1.example.com.";
+    constexpr char host_name2[] = "tlsfailover2.example.com.";
+    const std::vector<DnsRecord> records1 = {
+            {host_name1, ns_type::ns_t_a, "1.2.3.1"},
+            {host_name2, ns_type::ns_t_a, "1.2.3.2"},
+    };
+    const std::vector<DnsRecord> records2 = {
+            {host_name1, ns_type::ns_t_a, "1.2.3.3"},
+            {host_name2, ns_type::ns_t_a, "1.2.3.4"},
+    };
+
+    test::DNSResponder dns1(listen_addr1);
+    test::DNSResponder dns2(listen_addr2);
+    StartDns(dns1, records1);
+    StartDns(dns2, records2);
+
+    std::vector<std::string> servers = { listen_addr1, listen_addr2 };
+
+    test::DnsTlsFrontend tls1(listen_addr1, listen_tls, listen_addr1, listen_udp);
+    test::DnsTlsFrontend tls2(listen_addr2, listen_tls, listen_addr2, listen_udp);
+    ASSERT_TRUE(tls1.startServer());
+    ASSERT_TRUE(tls2.startServer());
+    ASSERT_TRUE(mDnsClient.SetResolversWithTls(
+            servers, kDefaultSearchDomains, kDefaultParams, "",
+            {base64Encode(tls1.fingerprint()), base64Encode(tls2.fingerprint())}));
+
+    const hostent* result;
+
+    // Wait for validation to complete.
+    EXPECT_TRUE(tls1.waitForQueries(1, 5000));
+    EXPECT_TRUE(tls2.waitForQueries(1, 5000));
+
+    result = gethostbyname("tlsfailover1");
+    ASSERT_FALSE(result == nullptr);
+    EXPECT_EQ("1.2.3.1", ToString(result));
+
+    // Wait for query to get counted.
+    EXPECT_TRUE(tls1.waitForQueries(2, 5000));
+    // No new queries should have reached tls2.
+    EXPECT_EQ(1, tls2.queries());
+
+    // Stop tls1.  Subsequent queries should attempt to reach tls1, fail, and retry to tls2.
+    tls1.stopServer();
+
+    result = gethostbyname("tlsfailover2");
+    EXPECT_EQ("1.2.3.4", ToString(result));
+
+    // Wait for query to get counted.
+    EXPECT_TRUE(tls2.waitForQueries(2, 5000));
+
+    // No additional queries should have reached the insecure servers.
+    EXPECT_EQ(2U, dns1.queries().size());
+    EXPECT_EQ(2U, dns2.queries().size());
+
+    // Clear TLS bit.
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+}
+
+TEST_F(ResolverTest, GetHostByName_BadTlsName) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_udp[] = "53";
+    constexpr char listen_tls[] = "853";
+    constexpr char host_name[] = "badtlsname.example.com.";
+
+    test::DNSResponder dns;
+    StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
+    std::vector<std::string> servers = { listen_addr };
+
+    test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
+    ASSERT_TRUE(tls.startServer());
+    ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
+                                               "www.example.com", {}));
+
+    // The TLS server's certificate doesn't chain to a known CA, and a nonempty name was specified,
+    // so the client should fail the TLS handshake before ever issuing a query.
+    EXPECT_FALSE(tls.waitForQueries(1, 500));
+
+    // The query should fail hard, because a name was specified.
+    EXPECT_EQ(nullptr, gethostbyname("badtlsname"));
+
+    // Clear TLS bit.
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+}
+
+TEST_F(ResolverTest, GetAddrInfo_Tls) {
+    constexpr char listen_addr[] = "127.0.0.3";
+    constexpr char listen_udp[] = "53";
+    constexpr char listen_tls[] = "853";
+    constexpr char host_name[] = "addrinfotls.example.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
+    };
+
+    test::DNSResponder dns;
+    StartDns(dns, records);
+    std::vector<std::string> servers = { listen_addr };
+
+    test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
+    ASSERT_TRUE(tls.startServer());
+    ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "",
+                                               {base64Encode(tls.fingerprint())}));
+
+    // Wait for validation to complete.
+    EXPECT_TRUE(tls.waitForQueries(1, 5000));
+
+    dns.clearQueries();
+    ScopedAddrinfo result = safe_getaddrinfo("addrinfotls", nullptr, nullptr);
+    EXPECT_TRUE(result != nullptr);
+    size_t found = GetNumQueries(dns, host_name);
+    EXPECT_LE(1U, found);
+    // Could be A or AAAA
+    std::string result_str = ToString(result);
+    EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
+        << ", result_str='" << result_str << "'";
+    // Wait for both A and AAAA queries to get counted.
+    EXPECT_TRUE(tls.waitForQueries(3, 5000));
+
+    // Clear TLS bit.
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+}
+
+TEST_F(ResolverTest, TlsBypass) {
+    // Certificate fingerprints are no longer supported by the module.
+    SKIP_IF_RESOLVER_VERSION_NEWER_THAN(mDnsClient.resolvService(), 2);
+
+    const char OFF[] = "off";
+    const char OPPORTUNISTIC[] = "opportunistic";
+    const char STRICT[] = "strict";
+
+    const char GETHOSTBYNAME[] = "gethostbyname";
+    const char GETADDRINFO[] = "getaddrinfo";
+    const char GETADDRINFOFORNET[] = "getaddrinfofornet";
+
+    const unsigned BYPASS_NETID = NETID_USE_LOCAL_NAMESERVERS | TEST_NETID;
+
+    const std::vector<uint8_t> NOOP_FINGERPRINT(SHA256_SIZE, 0U);
+
+    const char ADDR4[] = "192.0.2.1";
+    const char ADDR6[] = "2001:db8::1";
+
+    const char cleartext_addr[] = "127.0.0.53";
+    const char cleartext_port[] = "53";
+    const char tls_port[] = "853";
+    const std::vector<std::string> servers = { cleartext_addr };
+
+    test::DNSResponder dns(cleartext_addr);
+    ASSERT_TRUE(dns.startServer());
+
+    test::DnsTlsFrontend tls(cleartext_addr, tls_port, cleartext_addr, cleartext_port);
+
+    struct TestConfig {
+        const std::string mode;
+        const bool withWorkingTLS;
+        const std::string method;
+
+        std::string asHostName() const {
+            return StringPrintf("%s.%s.%s.",
+                                mode.c_str(),
+                                withWorkingTLS ? "tlsOn" : "tlsOff",
+                                method.c_str());
+        }
+    } testConfigs[]{
+        {OFF,           false, GETHOSTBYNAME},
+        {OPPORTUNISTIC, false, GETHOSTBYNAME},
+        {STRICT,        false, GETHOSTBYNAME},
+        {OFF,           true,  GETHOSTBYNAME},
+        {OPPORTUNISTIC, true,  GETHOSTBYNAME},
+        {STRICT,        true,  GETHOSTBYNAME},
+        {OFF,           false, GETADDRINFO},
+        {OPPORTUNISTIC, false, GETADDRINFO},
+        {STRICT,        false, GETADDRINFO},
+        {OFF,           true,  GETADDRINFO},
+        {OPPORTUNISTIC, true,  GETADDRINFO},
+        {STRICT,        true,  GETADDRINFO},
+        {OFF,           false, GETADDRINFOFORNET},
+        {OPPORTUNISTIC, false, GETADDRINFOFORNET},
+        {STRICT,        false, GETADDRINFOFORNET},
+        {OFF,           true,  GETADDRINFOFORNET},
+        {OPPORTUNISTIC, true,  GETADDRINFOFORNET},
+        {STRICT,        true,  GETADDRINFOFORNET},
+    };
+
+    for (const auto& config : testConfigs) {
+        const std::string testHostName = config.asHostName();
+        SCOPED_TRACE(testHostName);
+
+        // Don't tempt test bugs due to caching.
+        const char* host_name = testHostName.c_str();
+        dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
+        dns.addMapping(host_name, ns_type::ns_t_aaaa, ADDR6);
+
+        if (config.withWorkingTLS) ASSERT_TRUE(tls.startServer());
+
+        if (config.mode == OFF) {
+            ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains,
+                                                          kDefaultParams));
+        } else if (config.mode == OPPORTUNISTIC) {
+            ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
+                                                       kDefaultParams, "", {}));
+            // Wait for validation to complete.
+            if (config.withWorkingTLS) EXPECT_TRUE(tls.waitForQueries(1, 5000));
+        } else if (config.mode == STRICT) {
+            // We use the existence of fingerprints to trigger strict mode,
+            // rather than hostname validation.
+            const auto& fingerprint =
+                    (config.withWorkingTLS) ? tls.fingerprint() : NOOP_FINGERPRINT;
+            ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
+                                                       kDefaultParams, "",
+                                                       {base64Encode(fingerprint)}));
+            // Wait for validation to complete.
+            if (config.withWorkingTLS) EXPECT_TRUE(tls.waitForQueries(1, 5000));
+        } else {
+            FAIL() << "Unsupported Private DNS mode: " << config.mode;
+        }
+
+        const int tlsQueriesBefore = tls.queries();
+
+        const hostent* h_result = nullptr;
+        ScopedAddrinfo ai_result;
+
+        if (config.method == GETHOSTBYNAME) {
+            ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
+            h_result = gethostbyname(host_name);
+
+            EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
+            ASSERT_FALSE(h_result == nullptr);
+            ASSERT_EQ(4, h_result->h_length);
+            ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
+            EXPECT_EQ(ADDR4, ToString(h_result));
+            EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
+        } else if (config.method == GETADDRINFO) {
+            ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
+            ai_result = safe_getaddrinfo(host_name, nullptr, nullptr);
+            EXPECT_TRUE(ai_result != nullptr);
+
+            EXPECT_LE(1U, GetNumQueries(dns, host_name));
+            // Could be A or AAAA
+            const std::string result_str = ToString(ai_result);
+            EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
+                << ", result_str='" << result_str << "'";
+        } else if (config.method == GETADDRINFOFORNET) {
+            addrinfo* raw_ai_result = nullptr;
+            EXPECT_EQ(0, android_getaddrinfofornet(host_name, /*servname=*/nullptr,
+                                                   /*hints=*/nullptr, BYPASS_NETID, MARK_UNSET,
+                                                   &raw_ai_result));
+            ai_result.reset(raw_ai_result);
+
+            EXPECT_LE(1U, GetNumQueries(dns, host_name));
+            // Could be A or AAAA
+            const std::string result_str = ToString(ai_result);
+            EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
+                << ", result_str='" << result_str << "'";
+        } else {
+            FAIL() << "Unsupported query method: " << config.method;
+        }
+
+        const int tlsQueriesAfter = tls.queries();
+        EXPECT_EQ(0, tlsQueriesAfter - tlsQueriesBefore);
+
+        // Clear per-process resolv netid.
+        ASSERT_EQ(0, setNetworkForResolv(NETID_UNSET));
+        tls.stopServer();
+        dns.clearQueries();
+    }
+}
+
+TEST_F(ResolverTest, StrictMode_NoTlsServers) {
+    // Certificate fingerprints are no longer supported by the module.
+    SKIP_IF_RESOLVER_VERSION_NEWER_THAN(mDnsClient.resolvService(), 2);
+
+    const std::vector<uint8_t> NOOP_FINGERPRINT(SHA256_SIZE, 0U);
+    constexpr char cleartext_addr[] = "127.0.0.53";
+    const std::vector<std::string> servers = { cleartext_addr };
+    constexpr char host_name[] = "strictmode.notlsips.example.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
+    };
+
+    test::DNSResponder dns(cleartext_addr);
+    StartDns(dns, records);
+
+    ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, {},
+                                               "", {base64Encode(NOOP_FINGERPRINT)}));
+
+    addrinfo* ai_result = nullptr;
+    EXPECT_NE(0, getaddrinfo(host_name, nullptr, nullptr, &ai_result));
+    EXPECT_EQ(0U, GetNumQueries(dns, host_name));
+}
+
+namespace {
+
+int getAsyncResponse(int fd, int* rcode, uint8_t* buf, int bufLen) {
+    struct pollfd wait_fd[1];
+    wait_fd[0].fd = fd;
+    wait_fd[0].events = POLLIN;
+    short revents;
+    int ret;
+
+    ret = poll(wait_fd, 1, -1);
+    revents = wait_fd[0].revents;
+    if (revents & POLLIN) {
+        int n = resNetworkResult(fd, rcode, buf, bufLen);
+        // Verify that resNetworkResult() closed the fd
+        char dummy;
+        EXPECT_EQ(-1, read(fd, &dummy, sizeof dummy));
+        EXPECT_EQ(EBADF, errno);
+        return n;
+    }
+    return -1;
+}
+
+std::string toString(uint8_t* buf, int bufLen, int ipType) {
+    ns_msg handle;
+    int ancount, n = 0;
+    ns_rr rr;
+
+    if (ns_initparse((const uint8_t*) buf, bufLen, &handle) >= 0) {
+        ancount = ns_msg_count(handle, ns_s_an);
+        if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
+            const uint8_t* rdata = ns_rr_rdata(rr);
+            char buffer[INET6_ADDRSTRLEN];
+            if (inet_ntop(ipType, (const char*) rdata, buffer, sizeof(buffer))) {
+                return buffer;
+            }
+        }
+    }
+    return "";
+}
+
+int dns_open_proxy() {
+    int s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+    if (s == -1) {
+        return -1;
+    }
+    const int one = 1;
+    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+
+    static const struct sockaddr_un proxy_addr = {
+            .sun_family = AF_UNIX,
+            .sun_path = "/dev/socket/dnsproxyd",
+    };
+
+    if (TEMP_FAILURE_RETRY(connect(s, (const struct sockaddr*) &proxy_addr, sizeof(proxy_addr))) !=
+        0) {
+        close(s);
+        return -1;
+    }
+
+    return s;
+}
+
+void expectAnswersValid(int fd, int ipType, const std::string& expectedAnswer) {
+    int rcode = -1;
+    uint8_t buf[MAXPACKET] = {};
+
+    int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
+    EXPECT_GT(res, 0);
+    EXPECT_EQ(expectedAnswer, toString(buf, res, ipType));
+}
+
+void expectAnswersNotValid(int fd, int expectedErrno) {
+    int rcode = -1;
+    uint8_t buf[MAXPACKET] = {};
+
+    int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
+    EXPECT_EQ(expectedErrno, res);
+}
+
+}  // namespace
+
+TEST_F(ResolverTest, Async_NormalQueryV4V6) {
+    constexpr char listen_addr[] = "127.0.0.4";
+    constexpr char host_name[] = "howdy.example.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
+    int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
+    EXPECT_TRUE(fd1 != -1);
+    EXPECT_TRUE(fd2 != -1);
+
+    uint8_t buf[MAXPACKET] = {};
+    int rcode;
+    int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
+    EXPECT_GT(res, 0);
+    EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
+
+    res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
+    EXPECT_GT(res, 0);
+    EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
+
+    EXPECT_EQ(2U, GetNumQueries(dns, host_name));
+
+    // Re-query verify cache works
+    fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
+    fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
+
+    EXPECT_TRUE(fd1 != -1);
+    EXPECT_TRUE(fd2 != -1);
+
+    res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
+    EXPECT_GT(res, 0);
+    EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
+
+    res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
+    EXPECT_GT(res, 0);
+    EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
+
+    EXPECT_EQ(2U, GetNumQueries(dns, host_name));
+}
+
+TEST_F(ResolverTest, Async_BadQuery) {
+    constexpr char listen_addr[] = "127.0.0.4";
+    constexpr char host_name[] = "howdy.example.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    static struct {
+        int fd;
+        const char* dname;
+        const int queryType;
+        const int expectRcode;
+    } kTestData[] = {
+            {-1, "", ns_t_aaaa, 0},
+            {-1, "as65ass46", ns_t_aaaa, 0},
+            {-1, "454564564564", ns_t_aaaa, 0},
+            {-1, "h645235", ns_t_a, 0},
+            {-1, "www.google.com", ns_t_a, 0},
+    };
+
+    for (auto& td : kTestData) {
+        SCOPED_TRACE(td.dname);
+        td.fd = resNetworkQuery(TEST_NETID, td.dname, ns_c_in, td.queryType, 0);
+        EXPECT_TRUE(td.fd != -1);
+    }
+
+    // dns_responder return empty resp(packet only contains query part) with no error currently
+    for (const auto& td : kTestData) {
+        uint8_t buf[MAXPACKET] = {};
+        int rcode;
+        SCOPED_TRACE(td.dname);
+        int res = getAsyncResponse(td.fd, &rcode, buf, MAXPACKET);
+        EXPECT_GT(res, 0);
+        EXPECT_EQ(rcode, td.expectRcode);
+    }
+}
+
+TEST_F(ResolverTest, Async_EmptyAnswer) {
+    constexpr char listen_addr[] = "127.0.0.4";
+    constexpr char host_name[] = "howdy.example.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // TODO: Disable retry to make this test explicit.
+    auto& cv = dns.getCv();
+    auto& cvMutex = dns.getCvMutex();
+    int fd1;
+    // Wait on the condition variable to ensure that the DNS server has handled our first query.
+    {
+        std::unique_lock lk(cvMutex);
+        fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
+        EXPECT_TRUE(fd1 != -1);
+        EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lk, std::chrono::seconds(1)));
+    }
+
+    dns.setResponseProbability(0.0);
+
+    int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
+    EXPECT_TRUE(fd2 != -1);
+
+    int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
+    EXPECT_TRUE(fd3 != -1);
+
+    uint8_t buf[MAXPACKET] = {};
+    int rcode;
+
+    // expect no response
+    int res = getAsyncResponse(fd3, &rcode, buf, MAXPACKET);
+    EXPECT_EQ(-ETIMEDOUT, res);
+
+    // expect no response
+    memset(buf, 0, MAXPACKET);
+    res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
+    EXPECT_EQ(-ETIMEDOUT, res);
+
+    dns.setResponseProbability(1.0);
+
+    int fd4 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
+    EXPECT_TRUE(fd4 != -1);
+
+    memset(buf, 0, MAXPACKET);
+    res = getAsyncResponse(fd4, &rcode, buf, MAXPACKET);
+    EXPECT_GT(res, 0);
+    EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
+
+    memset(buf, 0, MAXPACKET);
+    res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
+    EXPECT_GT(res, 0);
+    EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
+}
+
+TEST_F(ResolverTest, Async_MalformedQuery) {
+    constexpr char listen_addr[] = "127.0.0.4";
+    constexpr char host_name[] = "howdy.example.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    int fd = dns_open_proxy();
+    EXPECT_TRUE(fd > 0);
+
+    const std::string badMsg = "16-52512#";
+    static const struct {
+        const std::string cmd;
+        const int expectErr;
+    } kTestData[] = {
+            // Too few arguments
+            {"resnsend " + badMsg + '\0', -EINVAL},
+            // Bad netId
+            {"resnsend badnetId 0 " + badMsg + '\0', -EINVAL},
+            // Bad raw data
+            {"resnsend " + std::to_string(TEST_NETID) + " 0 " + badMsg + '\0', -EILSEQ},
+    };
+
+    for (unsigned int i = 0; i < std::size(kTestData); i++) {
+        auto& td = kTestData[i];
+        SCOPED_TRACE(td.cmd);
+        ssize_t rc = TEMP_FAILURE_RETRY(write(fd, td.cmd.c_str(), td.cmd.size()));
+        EXPECT_EQ(rc, static_cast<ssize_t>(td.cmd.size()));
+
+        int32_t tmp;
+        rc = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
+        EXPECT_TRUE(rc > 0);
+        EXPECT_EQ(static_cast<int>(ntohl(tmp)), td.expectErr);
+    }
+    // Normal query with answer buffer
+    // This is raw data of query "howdy.example.com" type 1 class 1
+    std::string query = "81sBAAABAAAAAAAABWhvd2R5B2V4YW1wbGUDY29tAAABAAE=";
+    std::string cmd = "resnsend " + std::to_string(TEST_NETID) + " 0 " + query + '\0';
+    ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
+    EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
+
+    uint8_t smallBuf[1] = {};
+    int rcode;
+    rc = getAsyncResponse(fd, &rcode, smallBuf, 1);
+    EXPECT_EQ(-EMSGSIZE, rc);
+
+    // Do the normal test with large buffer again
+    fd = dns_open_proxy();
+    EXPECT_TRUE(fd > 0);
+    rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
+    EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
+    uint8_t buf[MAXPACKET] = {};
+    rc = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
+    EXPECT_EQ("1.2.3.4", toString(buf, rc, AF_INET));
+}
+
+TEST_F(ResolverTest, Async_CacheFlags) {
+    constexpr char listen_addr[] = "127.0.0.4";
+    constexpr char host_name[] = "howdy.example.com.";
+    constexpr char another_host_name[] = "howdy.example2.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
+            {another_host_name, ns_type::ns_t_a, "1.2.3.5"},
+            {another_host_name, ns_type::ns_t_aaaa, "::1.2.3.5"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // ANDROID_RESOLV_NO_CACHE_STORE
+    int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
+                              ANDROID_RESOLV_NO_CACHE_STORE);
+    EXPECT_TRUE(fd1 != -1);
+    int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
+                              ANDROID_RESOLV_NO_CACHE_STORE);
+    EXPECT_TRUE(fd2 != -1);
+    int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
+                              ANDROID_RESOLV_NO_CACHE_STORE);
+    EXPECT_TRUE(fd3 != -1);
+
+    expectAnswersValid(fd3, AF_INET, "1.2.3.4");
+    expectAnswersValid(fd2, AF_INET, "1.2.3.4");
+    expectAnswersValid(fd1, AF_INET, "1.2.3.4");
+
+    // No cache exists, expect 3 queries
+    EXPECT_EQ(3U, GetNumQueries(dns, host_name));
+
+    // Re-query and cache
+    fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
+
+    EXPECT_TRUE(fd1 != -1);
+
+    expectAnswersValid(fd1, AF_INET, "1.2.3.4");
+
+    // Now we have cache, expect 4 queries
+    EXPECT_EQ(4U, GetNumQueries(dns, host_name));
+
+    // ANDROID_RESOLV_NO_CACHE_LOOKUP
+    fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
+                          ANDROID_RESOLV_NO_CACHE_LOOKUP);
+    fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
+                          ANDROID_RESOLV_NO_CACHE_LOOKUP);
+
+    EXPECT_TRUE(fd1 != -1);
+    EXPECT_TRUE(fd2 != -1);
+
+    expectAnswersValid(fd2, AF_INET, "1.2.3.4");
+    expectAnswersValid(fd1, AF_INET, "1.2.3.4");
+
+    // Skip cache, expect 6 queries
+    EXPECT_EQ(6U, GetNumQueries(dns, host_name));
+
+    // Re-query verify cache works
+    fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
+                          ANDROID_RESOLV_NO_CACHE_STORE);
+    EXPECT_TRUE(fd1 != -1);
+    expectAnswersValid(fd1, AF_INET, "1.2.3.4");
+
+    // Cache hits,  expect still 6 queries
+    EXPECT_EQ(6U, GetNumQueries(dns, host_name));
+
+    // Start to verify if ANDROID_RESOLV_NO_CACHE_LOOKUP does write response into cache
+    dns.clearQueries();
+
+    fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
+                          ANDROID_RESOLV_NO_CACHE_LOOKUP);
+    fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
+                          ANDROID_RESOLV_NO_CACHE_LOOKUP);
+
+    EXPECT_TRUE(fd1 != -1);
+    EXPECT_TRUE(fd2 != -1);
+
+    expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
+    expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
+
+    // Skip cache, expect 2 queries
+    EXPECT_EQ(2U, GetNumQueries(dns, host_name));
+
+    // Re-query without flags
+    fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
+    fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
+
+    EXPECT_TRUE(fd1 != -1);
+    EXPECT_TRUE(fd2 != -1);
+
+    expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
+    expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
+
+    // Cache hits, expect still 2 queries
+    EXPECT_EQ(2U, GetNumQueries(dns, host_name));
+
+    // Test both ANDROID_RESOLV_NO_CACHE_STORE and ANDROID_RESOLV_NO_CACHE_LOOKUP are set
+    dns.clearQueries();
+
+    // Make sure that the cache of "howdy.example2.com" exists.
+    fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, 0);
+    EXPECT_TRUE(fd1 != -1);
+    expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
+    EXPECT_EQ(1U, GetNumQueries(dns, another_host_name));
+
+    // Re-query with testFlags
+    const int testFlag = ANDROID_RESOLV_NO_CACHE_STORE | ANDROID_RESOLV_NO_CACHE_LOOKUP;
+    fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, testFlag);
+    EXPECT_TRUE(fd1 != -1);
+    expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
+    // Expect cache lookup is skipped.
+    EXPECT_EQ(2U, GetNumQueries(dns, another_host_name));
+
+    // Do another query with testFlags
+    fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, testFlag);
+    EXPECT_TRUE(fd1 != -1);
+    expectAnswersValid(fd1, AF_INET, "1.2.3.5");
+    // Expect cache lookup is skipped.
+    EXPECT_EQ(3U, GetNumQueries(dns, another_host_name));
+
+    // Re-query with no flags
+    fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, 0);
+    EXPECT_TRUE(fd1 != -1);
+    expectAnswersValid(fd1, AF_INET, "1.2.3.5");
+    // Expect no cache hit because cache storing is also skipped in previous query.
+    EXPECT_EQ(4U, GetNumQueries(dns, another_host_name));
+}
+
+TEST_F(ResolverTest, Async_NoRetryFlag) {
+    constexpr char listen_addr0[] = "127.0.0.4";
+    constexpr char listen_addr1[] = "127.0.0.6";
+    constexpr char host_name[] = "howdy.example.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
+    };
+
+    test::DNSResponder dns0(listen_addr0);
+    test::DNSResponder dns1(listen_addr1);
+    StartDns(dns0, records);
+    StartDns(dns1, records);
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}));
+
+    dns0.clearQueries();
+    dns1.clearQueries();
+
+    dns0.setResponseProbability(0.0);
+    dns1.setResponseProbability(0.0);
+
+    int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
+                              ANDROID_RESOLV_NO_RETRY);
+    EXPECT_TRUE(fd1 != -1);
+
+    int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
+                              ANDROID_RESOLV_NO_RETRY);
+    EXPECT_TRUE(fd2 != -1);
+
+    // expect no response
+    expectAnswersNotValid(fd1, -ETIMEDOUT);
+    expectAnswersNotValid(fd2, -ETIMEDOUT);
+
+    // No retry case, expect total 2 queries. The server is selected randomly.
+    EXPECT_EQ(2U, GetNumQueries(dns0, host_name) + GetNumQueries(dns1, host_name));
+
+    dns0.clearQueries();
+    dns1.clearQueries();
+
+    fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
+    EXPECT_TRUE(fd1 != -1);
+
+    fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
+    EXPECT_TRUE(fd2 != -1);
+
+    // expect no response
+    expectAnswersNotValid(fd1, -ETIMEDOUT);
+    expectAnswersNotValid(fd2, -ETIMEDOUT);
+
+    // Retry case, expect 4 queries
+    EXPECT_EQ(4U, GetNumQueries(dns0, host_name));
+    EXPECT_EQ(4U, GetNumQueries(dns1, host_name));
+}
+
+TEST_F(ResolverTest, Async_VerifyQueryID) {
+    constexpr char listen_addr[] = "127.0.0.4";
+    constexpr char host_name[] = "howdy.example.com.";
+    const std::vector<DnsRecord> records = {
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    const uint8_t queryBuf1[] = {
+            /* Header */
+            0x55, 0x66, /* Transaction ID */
+            0x01, 0x00, /* Flags */
+            0x00, 0x01, /* Questions */
+            0x00, 0x00, /* Answer RRs */
+            0x00, 0x00, /* Authority RRs */
+            0x00, 0x00, /* Additional RRs */
+            /* Queries */
+            0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+            0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
+            0x00, 0x01,                   /* Type */
+            0x00, 0x01                    /* Class */
+    };
+
+    int fd = resNetworkSend(TEST_NETID, queryBuf1, sizeof(queryBuf1), 0);
+    EXPECT_TRUE(fd != -1);
+
+    uint8_t buf[MAXPACKET] = {};
+    int rcode;
+
+    int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
+    EXPECT_GT(res, 0);
+    EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
+
+    auto hp = reinterpret_cast<HEADER*>(buf);
+    EXPECT_EQ(21862U, htons(hp->id));
+
+    EXPECT_EQ(1U, GetNumQueries(dns, host_name));
+
+    const uint8_t queryBuf2[] = {
+            /* Header */
+            0x00, 0x53, /* Transaction ID */
+            0x01, 0x00, /* Flags */
+            0x00, 0x01, /* Questions */
+            0x00, 0x00, /* Answer RRs */
+            0x00, 0x00, /* Authority RRs */
+            0x00, 0x00, /* Additional RRs */
+            /* Queries */
+            0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+            0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
+            0x00, 0x01,                   /* Type */
+            0x00, 0x01                    /* Class */
+    };
+
+    // Re-query verify cache works and query id is correct
+    fd = resNetworkSend(TEST_NETID, queryBuf2, sizeof(queryBuf2), 0);
+
+    EXPECT_TRUE(fd != -1);
+
+    res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
+    EXPECT_GT(res, 0);
+    EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
+
+    EXPECT_EQ(0x0053U, htons(hp->id));
+
+    EXPECT_EQ(1U, GetNumQueries(dns, host_name));
+}
+
+// This test checks that the resolver should not generate the request containing OPT RR when using
+// cleartext DNS. If we query the DNS server not supporting EDNS0 and it reponds with
+// FORMERR_ON_EDNS, we will fallback to no EDNS0 and try again. If the server does no response, we
+// won't retry so that we get no answer.
+TEST_F(ResolverTest, BrokenEdns) {
+    // Certificate fingerprints are no longer supported by the module.
+    SKIP_IF_RESOLVER_VERSION_NEWER_THAN(mDnsClient.resolvService(), 2);
+
+    typedef test::DNSResponder::Edns Edns;
+    enum ExpectResult { EXPECT_FAILURE, EXPECT_SUCCESS };
+
+    const char OFF[] = "off";
+    const char OPPORTUNISTIC_UDP[] = "opportunistic_udp";
+    const char OPPORTUNISTIC_TLS[] = "opportunistic_tls";
+    const char STRICT[] = "strict";
+    const char GETHOSTBYNAME[] = "gethostbyname";
+    const char GETADDRINFO[] = "getaddrinfo";
+    const std::vector<uint8_t> NOOP_FINGERPRINT(SHA256_SIZE, 0U);
+    const char ADDR4[] = "192.0.2.1";
+    const char CLEARTEXT_ADDR[] = "127.0.0.53";
+    const char CLEARTEXT_PORT[] = "53";
+    const char TLS_PORT[] = "853";
+    const std::vector<std::string> servers = { CLEARTEXT_ADDR };
+
+    test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, 250, ns_rcode::ns_r_servfail);
+    ASSERT_TRUE(dns.startServer());
+
+    test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
+
+    static const struct TestConfig {
+        std::string mode;
+        std::string method;
+        Edns edns;
+        ExpectResult expectResult;
+
+        std::string asHostName() const {
+            const char* ednsString;
+            switch (edns) {
+                case Edns::ON:
+                    ednsString = "ednsOn";
+                    break;
+                case Edns::FORMERR_ON_EDNS:
+                    ednsString = "ednsFormerr";
+                    break;
+                case Edns::DROP:
+                    ednsString = "ednsDrop";
+                    break;
+                default:
+                    ednsString = "";
+                    break;
+            }
+            return StringPrintf("%s.%s.%s.", mode.c_str(), method.c_str(), ednsString);
+        }
+    } testConfigs[] = {
+            // In OPPORTUNISTIC_TLS, we get no answer if the DNS server supports TLS but not EDNS0.
+            // Could such server exist? if so, we might need to fallback to query cleartext DNS.
+            // Another thing is that {OPPORTUNISTIC_TLS, Edns::DROP} and {STRICT, Edns::DROP} are
+            // commented out since TLS timeout is not configurable.
+            // TODO: Uncomment them after TLS timeout is configurable.
+            {OFF,               GETHOSTBYNAME, Edns::ON,      EXPECT_SUCCESS},
+            {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::ON,      EXPECT_SUCCESS},
+            {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::ON,      EXPECT_SUCCESS},
+            {STRICT,            GETHOSTBYNAME, Edns::ON,      EXPECT_SUCCESS},
+            {OFF,               GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
+            {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
+            {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
+            {STRICT,            GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
+            {OFF,               GETHOSTBYNAME, Edns::DROP,    EXPECT_SUCCESS},
+            {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::DROP,    EXPECT_SUCCESS},
+            //{OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::DROP,    EXPECT_FAILURE},
+            //{STRICT,            GETHOSTBYNAME, Edns::DROP,    EXPECT_FAILURE},
+            {OFF,               GETADDRINFO,   Edns::ON,      EXPECT_SUCCESS},
+            {OPPORTUNISTIC_UDP, GETADDRINFO,   Edns::ON,      EXPECT_SUCCESS},
+            {OPPORTUNISTIC_TLS, GETADDRINFO,   Edns::ON,      EXPECT_SUCCESS},
+            {STRICT,            GETADDRINFO,   Edns::ON,      EXPECT_SUCCESS},
+            {OFF,               GETADDRINFO,   Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
+            {OPPORTUNISTIC_UDP, GETADDRINFO,   Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
+            {OPPORTUNISTIC_TLS, GETADDRINFO,   Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
+            {STRICT,            GETADDRINFO,   Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
+            {OFF,               GETADDRINFO,   Edns::DROP,    EXPECT_SUCCESS},
+            {OPPORTUNISTIC_UDP, GETADDRINFO,   Edns::DROP,    EXPECT_SUCCESS},
+            //{OPPORTUNISTIC_TLS, GETADDRINFO,   Edns::DROP,   EXPECT_FAILURE},
+            //{STRICT,            GETADDRINFO,   Edns::DROP,   EXPECT_FAILURE},
+    };
+
+    for (const auto& config : testConfigs) {
+        const std::string testHostName = config.asHostName();
+        SCOPED_TRACE(testHostName);
+
+        const char* host_name = testHostName.c_str();
+        dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
+        dns.setEdns(config.edns);
+
+        if (config.mode == OFF) {
+            ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+        } else if (config.mode == OPPORTUNISTIC_UDP) {
+            ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
+                                                       kDefaultParams, "", {}));
+        } else if (config.mode == OPPORTUNISTIC_TLS) {
+            ASSERT_TRUE(tls.startServer());
+            ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
+                                                       kDefaultParams, "", {}));
+            // Wait for validation to complete.
+            EXPECT_TRUE(tls.waitForQueries(1, 5000));
+        } else if (config.mode == STRICT) {
+            ASSERT_TRUE(tls.startServer());
+            ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
+                                                       kDefaultParams, "",
+                                                       {base64Encode(tls.fingerprint())}));
+            // Wait for validation to complete.
+            EXPECT_TRUE(tls.waitForQueries(1, 5000));
+        }
+
+        if (config.method == GETHOSTBYNAME) {
+            const hostent* h_result = gethostbyname(host_name);
+            if (config.expectResult == EXPECT_SUCCESS) {
+                EXPECT_LE(1U, GetNumQueries(dns, host_name));
+                ASSERT_TRUE(h_result != nullptr);
+                ASSERT_EQ(4, h_result->h_length);
+                ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
+                EXPECT_EQ(ADDR4, ToString(h_result));
+                EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
+            } else {
+                EXPECT_EQ(0U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
+                ASSERT_TRUE(h_result == nullptr);
+                ASSERT_EQ(HOST_NOT_FOUND, h_errno);
+            }
+        } else if (config.method == GETADDRINFO) {
+            ScopedAddrinfo ai_result;
+            addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
+            ai_result = safe_getaddrinfo(host_name, nullptr, &hints);
+            if (config.expectResult == EXPECT_SUCCESS) {
+                EXPECT_TRUE(ai_result != nullptr);
+                EXPECT_EQ(1U, GetNumQueries(dns, host_name));
+                const std::string result_str = ToString(ai_result);
+                EXPECT_EQ(ADDR4, result_str);
+            } else {
+                EXPECT_TRUE(ai_result == nullptr);
+                EXPECT_EQ(0U, GetNumQueries(dns, host_name));
+            }
+        } else {
+            FAIL() << "Unsupported query method: " << config.method;
+        }
+
+        tls.stopServer();
+        dns.clearQueries();
+    }
+}
+
+// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
+// Resolver should have a reasonable number of retries instead of spinning forever. We don't have
+// an efficient way to know if resolver is stuck in an infinite loop. However, test case will be
+// failed due to timeout.
+TEST_F(ResolverTest, UnstableTls) {
+    const char CLEARTEXT_ADDR[] = "127.0.0.53";
+    const char CLEARTEXT_PORT[] = "53";
+    const char TLS_PORT[] = "853";
+    const char* host_name1 = "nonexistent1.example.com.";
+    const char* host_name2 = "nonexistent2.example.com.";
+    const std::vector<std::string> servers = {CLEARTEXT_ADDR};
+
+    test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, 250, ns_rcode::ns_r_servfail);
+    ASSERT_TRUE(dns.startServer());
+    dns.setEdns(test::DNSResponder::Edns::FORMERR_ON_EDNS);
+    test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
+    ASSERT_TRUE(tls.startServer());
+    ASSERT_TRUE(
+            mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "", {}));
+    // Wait for validation complete.
+    EXPECT_TRUE(tls.waitForQueries(1, 5000));
+    // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
+    tls.stopServer();
+
+    const hostent* h_result = gethostbyname(host_name1);
+    EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
+    ASSERT_TRUE(h_result == nullptr);
+    ASSERT_EQ(HOST_NOT_FOUND, h_errno);
+
+    addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
+    ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
+    EXPECT_TRUE(ai_result == nullptr);
+    EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
+}
+
+// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
+// Moreover, server responds RCODE=FORMERR even on non-EDNS query.
+TEST_F(ResolverTest, BogusDnsServer) {
+    const char CLEARTEXT_ADDR[] = "127.0.0.53";
+    const char CLEARTEXT_PORT[] = "53";
+    const char TLS_PORT[] = "853";
+    const char* host_name1 = "nonexistent1.example.com.";
+    const char* host_name2 = "nonexistent2.example.com.";
+    const std::vector<std::string> servers = {CLEARTEXT_ADDR};
+
+    test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, 250, ns_rcode::ns_r_servfail);
+    ASSERT_TRUE(dns.startServer());
+    test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
+    ASSERT_TRUE(tls.startServer());
+    ASSERT_TRUE(
+            mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "", {}));
+    // Wait for validation complete.
+    EXPECT_TRUE(tls.waitForQueries(1, 5000));
+    // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
+    tls.stopServer();
+    dns.setEdns(test::DNSResponder::Edns::FORMERR_UNCOND);
+
+    const hostent* h_result = gethostbyname(host_name1);
+    EXPECT_EQ(0U, GetNumQueries(dns, host_name1));
+    ASSERT_TRUE(h_result == nullptr);
+    ASSERT_EQ(HOST_NOT_FOUND, h_errno);
+
+    addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
+    ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
+    EXPECT_TRUE(ai_result == nullptr);
+    EXPECT_EQ(0U, GetNumQueries(dns, host_name2));
+}
+
+TEST_F(ResolverTest, GetAddrInfo_Dns64Synthesize) {
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char host_name[] = "v4only.example.com.";
+    const std::vector<DnsRecord> records = {
+            {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+
+    std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // hints are necessary in order to let netd know which type of addresses the caller is
+    // interested in.
+    const addrinfo hints = {.ai_family = AF_UNSPEC};
+    ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    // TODO: BUG: there should only be two queries, one AAAA (which returns no records) and one A
+    // (which returns 1.2.3.4). But there is an extra AAAA.
+    EXPECT_EQ(3U, GetNumQueries(dns, host_name));
+
+    std::string result_str = ToString(result);
+    EXPECT_EQ(result_str, "64:ff9b::102:304");
+
+    // Stopping NAT64 prefix discovery disables synthesis.
+    EXPECT_TRUE(mDnsClient.resolvService()->stopPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_FALSE(WaitForPrefix64Detected(TEST_NETID, 300));
+
+    dns.clearQueries();
+
+    result = safe_getaddrinfo("v4only", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    // TODO: BUG: there should only be one query, an AAAA (which returns no records), because the
+    // A is already cached. But there is an extra AAAA.
+    EXPECT_EQ(2U, GetNumQueries(dns, host_name));
+
+    result_str = ToString(result);
+    EXPECT_EQ(result_str, "1.2.3.4");
+}
+
+TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecified) {
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char host_name[] = "v4only.example.com.";
+    const std::vector<DnsRecord> records = {
+            {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // Ensure to synthesize AAAA if AF_INET6 is specified, and not to synthesize AAAA
+    // in AF_INET case.
+    addrinfo hints;
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_INET6;
+    ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    std::string result_str = ToString(result);
+    EXPECT_EQ(result_str, "64:ff9b::102:304");
+
+    hints.ai_family = AF_INET;
+    result = safe_getaddrinfo("v4only", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_LE(2U, GetNumQueries(dns, host_name));
+    result_str = ToString(result);
+    EXPECT_EQ(result_str, "1.2.3.4");
+}
+
+TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedV6) {
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char host_name[] = "v4v6.example.com.";
+    const std::vector<DnsRecord> records = {
+            {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    const addrinfo hints = {.ai_family = AF_UNSPEC};
+    ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_LE(2U, GetNumQueries(dns, host_name));
+
+    // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
+    const std::vector<std::string> result_strs = ToStrings(result);
+    for (const auto& str : result_strs) {
+        EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
+                << ", result_str='" << str << "'";
+    }
+}
+
+TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedNoV6) {
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char host_name[] = "v4v6.example.com.";
+    const std::vector<DnsRecord> records = {
+            {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    const addrinfo hints = {.ai_family = AF_UNSPEC};
+    ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_LE(2U, GetNumQueries(dns, host_name));
+
+    // In AF_UNSPEC case, synthesize AAAA if there's no AAAA answer.
+    std::string result_str = ToString(result);
+    EXPECT_EQ(result_str, "64:ff9b::102:304");
+}
+
+TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecialUseIPv4Addresses) {
+    constexpr char THIS_NETWORK[] = "this_network";
+    constexpr char LOOPBACK[] = "loopback";
+    constexpr char LINK_LOCAL[] = "link_local";
+    constexpr char MULTICAST[] = "multicast";
+    constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
+
+    constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
+    constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
+    constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
+    constexpr char ADDR_MULTICAST[] = "224.0.0.1";
+    constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
+
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    static const struct TestConfig {
+        std::string name;
+        std::string addr;
+
+        std::string asHostName() const { return StringPrintf("%s.example.com.", name.c_str()); }
+    } testConfigs[]{
+        {THIS_NETWORK,      ADDR_THIS_NETWORK},
+        {LOOPBACK,          ADDR_LOOPBACK},
+        {LINK_LOCAL,        ADDR_LINK_LOCAL},
+        {MULTICAST,         ADDR_MULTICAST},
+        {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
+    };
+
+    for (const auto& config : testConfigs) {
+        const std::string testHostName = config.asHostName();
+        SCOPED_TRACE(testHostName);
+
+        const char* host_name = testHostName.c_str();
+        dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
+
+        addrinfo hints;
+        memset(&hints, 0, sizeof(hints));
+        hints.ai_family = AF_INET6;
+        ScopedAddrinfo result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
+        // In AF_INET6 case, don't return IPv4 answers
+        EXPECT_TRUE(result == nullptr);
+        EXPECT_LE(2U, GetNumQueries(dns, host_name));
+        dns.clearQueries();
+
+        memset(&hints, 0, sizeof(hints));
+        hints.ai_family = AF_UNSPEC;
+        result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
+        EXPECT_TRUE(result != nullptr);
+        // Expect IPv6 query only. IPv4 answer has been cached in previous query.
+        EXPECT_LE(1U, GetNumQueries(dns, host_name));
+        // In AF_UNSPEC case, don't synthesize special use IPv4 address.
+        std::string result_str = ToString(result);
+        EXPECT_EQ(result_str, config.addr.c_str());
+        dns.clearQueries();
+    }
+}
+
+TEST_F(ResolverTest, GetAddrInfo_Dns64QueryWithNullArgumentHints) {
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char host_name[] = "v4only.example.com.";
+    constexpr char host_name2[] = "v4v6.example.com.";
+    const std::vector<DnsRecord> records = {
+            {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name2, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name2, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // Assign argument hints of getaddrinfo() as null is equivalent to set ai_family AF_UNSPEC.
+    // In AF_UNSPEC case, synthesize AAAA if there has A answer only.
+    ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, nullptr);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_LE(2U, GetNumQueries(dns, host_name));
+    std::string result_str = ToString(result);
+    EXPECT_EQ(result_str, "64:ff9b::102:304");
+    dns.clearQueries();
+
+    // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
+    result = safe_getaddrinfo("v4v6", nullptr, nullptr);
+    EXPECT_TRUE(result != nullptr);
+    EXPECT_LE(2U, GetNumQueries(dns, host_name2));
+    std::vector<std::string> result_strs = ToStrings(result);
+    for (const auto& str : result_strs) {
+        EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
+                << ", result_str='" << str << "'";
+    }
+}
+
+TEST_F(ResolverTest, GetAddrInfo_Dns64QueryNullArgumentNode) {
+    constexpr char ADDR_ANYADDR_V4[] = "0.0.0.0";
+    constexpr char ADDR_ANYADDR_V6[] = "::";
+    constexpr char ADDR_LOCALHOST_V4[] = "127.0.0.1";
+    constexpr char ADDR_LOCALHOST_V6[] = "::1";
+
+    constexpr char PORT_NAME_HTTP[] = "http";
+    constexpr char PORT_NUMBER_HTTP[] = "80";
+
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // If node is null, return address is listed by libc/getaddrinfo.c as follows.
+    // - passive socket -> anyaddr (0.0.0.0 or ::)
+    // - non-passive socket -> localhost (127.0.0.1 or ::1)
+    static const struct TestConfig {
+        int flag;
+        std::string addr_v4;
+        std::string addr_v6;
+
+        std::string asParameters() const {
+            return StringPrintf("flag=%d, addr_v4=%s, addr_v6=%s", flag, addr_v4.c_str(),
+                                addr_v6.c_str());
+        }
+    } testConfigs[]{
+        {0 /* non-passive */, ADDR_LOCALHOST_V4, ADDR_LOCALHOST_V6},
+        {AI_PASSIVE,          ADDR_ANYADDR_V4,   ADDR_ANYADDR_V6}
+    };
+
+    for (const auto& config : testConfigs) {
+        SCOPED_TRACE(config.asParameters());
+
+        addrinfo hints = {
+                .ai_family = AF_UNSPEC,  // any address family
+                .ai_socktype = 0,        // any type
+                .ai_protocol = 0,        // any protocol
+                .ai_flags = config.flag,
+        };
+
+        // Assign hostname as null and service as port name.
+        ScopedAddrinfo result = safe_getaddrinfo(nullptr, PORT_NAME_HTTP, &hints);
+        ASSERT_TRUE(result != nullptr);
+
+        // Can't be synthesized because it should not get into Netd.
+        std::vector<std::string> result_strs = ToStrings(result);
+        for (const auto& str : result_strs) {
+            EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
+                    << ", result_str='" << str << "'";
+        }
+
+        // Assign hostname as null and service as numeric port number.
+        hints.ai_flags = config.flag | AI_NUMERICSERV;
+        result = safe_getaddrinfo(nullptr, PORT_NUMBER_HTTP, &hints);
+        ASSERT_TRUE(result != nullptr);
+
+        // Can't be synthesized because it should not get into Netd.
+        result_strs = ToStrings(result);
+        for (const auto& str : result_strs) {
+            EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
+                    << ", result_str='" << str << "'";
+        }
+    }
+}
+
+TEST_F(ResolverTest, GetHostByAddr_ReverseDnsQueryWithHavingNat64Prefix) {
+    struct hostent* result = nullptr;
+    struct in_addr v4addr;
+    struct in6_addr v6addr;
+
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char ptr_name[] = "v4v6.example.com.";
+    // PTR record for IPv4 address 1.2.3.4
+    constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
+    // PTR record for IPv6 address 2001:db8::102:304
+    constexpr char ptr_addr_v6[] =
+            "4.0.3.0.2.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.";
+    const std::vector<DnsRecord> records = {
+            {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
+            {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
+            {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // Reverse IPv4 DNS query. Prefix should have no effect on it.
+    inet_pton(AF_INET, "1.2.3.4", &v4addr);
+    result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
+    ASSERT_TRUE(result != nullptr);
+    std::string result_str = result->h_name ? result->h_name : "null";
+    EXPECT_EQ(result_str, "v4v6.example.com");
+
+    // Reverse IPv6 DNS query. Prefix should have no effect on it.
+    inet_pton(AF_INET6, "2001:db8::102:304", &v6addr);
+    result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
+    ASSERT_TRUE(result != nullptr);
+    result_str = result->h_name ? result->h_name : "null";
+    EXPECT_EQ(result_str, "v4v6.example.com");
+}
+
+TEST_F(ResolverTest, GetHostByAddr_ReverseDns64Query) {
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char ptr_name[] = "v4only.example.com.";
+    // PTR record for IPv4 address 1.2.3.4
+    constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
+    // PTR record for IPv6 address 64:ff9b::1.2.3.4
+    constexpr char ptr_addr_v6_nomapping[] =
+            "4.0.3.0.2.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa.";
+    constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
+    // PTR record for IPv6 address 64:ff9b::5.6.7.8
+    constexpr char ptr_addr_v6_synthesis[] =
+            "8.0.7.0.6.0.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa.";
+    const std::vector<DnsRecord> records = {
+            {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
+            {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
+            {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    // "ptr_addr_v6_nomapping" is not mapped in DNS server
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // Synthesized PTR record doesn't exist on DNS server
+    // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
+    // After querying synthesized address failed, expect that prefix is removed from IPv6
+    // synthesized address and do reverse IPv4 query instead.
+    struct in6_addr v6addr;
+    inet_pton(AF_INET6, "64:ff9b::1.2.3.4", &v6addr);
+    struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
+    ASSERT_TRUE(result != nullptr);
+    EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping));  // PTR record not exist
+    EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4));            // PTR record exist
+    std::string result_str = result->h_name ? result->h_name : "null";
+    EXPECT_EQ(result_str, "v4only.example.com");
+    // Check that return address has been mapped from IPv4 to IPv6 address because Netd
+    // removes NAT64 prefix and does IPv4 DNS reverse lookup in this case. Then, Netd
+    // fakes the return IPv4 address as original queried IPv6 address.
+    result_str = ToString(result);
+    EXPECT_EQ(result_str, "64:ff9b::102:304");
+    dns.clearQueries();
+
+    // Synthesized PTR record exists on DNS server
+    // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
+    // Expect to Netd pass through synthesized address for DNS queries.
+    inet_pton(AF_INET6, "64:ff9b::5.6.7.8", &v6addr);
+    result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
+    ASSERT_TRUE(result != nullptr);
+    EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
+    result_str = result->h_name ? result->h_name : "null";
+    EXPECT_EQ(result_str, "v6synthesis.example.com");
+}
+
+TEST_F(ResolverTest, GetHostByAddr_ReverseDns64QueryFromHostFile) {
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char host_name[] = "localhost";
+    // The address is synthesized by prefix64:localhost.
+    constexpr char host_addr[] = "64:ff9b::7f00:1";
+    constexpr char listen_addr[] = "::1";
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // Using synthesized "localhost" address to be a trick for resolving host name
+    // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
+    // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
+    struct in6_addr v6addr;
+    inet_pton(AF_INET6, host_addr, &v6addr);
+    struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
+    ASSERT_TRUE(result != nullptr);
+    // Expect no DNS queries; localhost is resolved via /etc/hosts.
+    EXPECT_EQ(0U, GetNumQueries(dns, host_name));
+
+    ASSERT_EQ(sizeof(in6_addr), (unsigned) result->h_length);
+    ASSERT_EQ(AF_INET6, result->h_addrtype);
+    std::string result_str = ToString(result);
+    EXPECT_EQ(result_str, host_addr);
+    result_str = result->h_name ? result->h_name : "null";
+    EXPECT_EQ(result_str, host_name);
+}
+
+TEST_F(ResolverTest, GetNameInfo_ReverseDnsQueryWithHavingNat64Prefix) {
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char ptr_name[] = "v4v6.example.com.";
+    // PTR record for IPv4 address 1.2.3.4
+    constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
+    // PTR record for IPv6 address 2001:db8::102:304
+    constexpr char ptr_addr_v6[] =
+            "4.0.3.0.2.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.";
+    const std::vector<DnsRecord> records = {
+            {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
+            {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
+            {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    static const struct TestConfig {
+        int flag;
+        int family;
+        std::string addr;
+        std::string host;
+
+        std::string asParameters() const {
+            return StringPrintf("flag=%d, family=%d, addr=%s, host=%s", flag, family, addr.c_str(),
+                                host.c_str());
+        }
+    } testConfigs[]{
+        {NI_NAMEREQD,    AF_INET,  "1.2.3.4",           "v4v6.example.com"},
+        {NI_NUMERICHOST, AF_INET,  "1.2.3.4",           "1.2.3.4"},
+        {0,              AF_INET,  "1.2.3.4",           "v4v6.example.com"},
+        {0,              AF_INET,  "5.6.7.8",           "5.6.7.8"},           // unmapped
+        {NI_NAMEREQD,    AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
+        {NI_NUMERICHOST, AF_INET6, "2001:db8::102:304", "2001:db8::102:304"},
+        {0,              AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
+        {0,              AF_INET6, "2001:db8::506:708", "2001:db8::506:708"}, // unmapped
+    };
+
+    // Reverse IPv4/IPv6 DNS query. Prefix should have no effect on it.
+    for (const auto& config : testConfigs) {
+        SCOPED_TRACE(config.asParameters());
+
+        int rv;
+        char host[NI_MAXHOST];
+        struct sockaddr_in sin;
+        struct sockaddr_in6 sin6;
+        if (config.family == AF_INET) {
+            memset(&sin, 0, sizeof(sin));
+            sin.sin_family = AF_INET;
+            inet_pton(AF_INET, config.addr.c_str(), &sin.sin_addr);
+            rv = getnameinfo((const struct sockaddr*) &sin, sizeof(sin), host, sizeof(host),
+                             nullptr, 0, config.flag);
+            if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4));
+        } else if (config.family == AF_INET6) {
+            memset(&sin6, 0, sizeof(sin6));
+            sin6.sin6_family = AF_INET6;
+            inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
+            rv = getnameinfo((const struct sockaddr*) &sin6, sizeof(sin6), host, sizeof(host),
+                             nullptr, 0, config.flag);
+            if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6));
+        }
+        ASSERT_EQ(0, rv);
+        std::string result_str = host;
+        EXPECT_EQ(result_str, config.host);
+        dns.clearQueries();
+    }
+}
+
+TEST_F(ResolverTest, GetNameInfo_ReverseDns64Query) {
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char ptr_name[] = "v4only.example.com.";
+    // PTR record for IPv4 address 1.2.3.4
+    constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
+    // PTR record for IPv6 address 64:ff9b::1.2.3.4
+    constexpr char ptr_addr_v6_nomapping[] =
+            "4.0.3.0.2.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa.";
+    constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
+    // PTR record for IPv6 address 64:ff9b::5.6.7.8
+    constexpr char ptr_addr_v6_synthesis[] =
+            "8.0.7.0.6.0.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa.";
+    const std::vector<DnsRecord> records = {
+            {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
+            {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
+            {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    static const struct TestConfig {
+        bool hasSynthesizedPtrRecord;
+        int flag;
+        std::string addr;
+        std::string host;
+
+        std::string asParameters() const {
+            return StringPrintf("hasSynthesizedPtrRecord=%d, flag=%d, addr=%s, host=%s",
+                                hasSynthesizedPtrRecord, flag, addr.c_str(), host.c_str());
+        }
+    } testConfigs[]{
+        {false, NI_NAMEREQD,    "64:ff9b::102:304", "v4only.example.com"},
+        {false, NI_NUMERICHOST, "64:ff9b::102:304", "64:ff9b::102:304"},
+        {false, 0,              "64:ff9b::102:304", "v4only.example.com"},
+        {true,  NI_NAMEREQD,    "64:ff9b::506:708", "v6synthesis.example.com"},
+        {true,  NI_NUMERICHOST, "64:ff9b::506:708", "64:ff9b::506:708"},
+        {true,  0,              "64:ff9b::506:708", "v6synthesis.example.com"}
+    };
+
+    // hasSynthesizedPtrRecord = false
+    //   Synthesized PTR record doesn't exist on DNS server
+    //   Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
+    //   After querying synthesized address failed, expect that prefix is removed from IPv6
+    //   synthesized address and do reverse IPv4 query instead.
+    //
+    // hasSynthesizedPtrRecord = true
+    //   Synthesized PTR record exists on DNS server
+    //   Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
+    //   Expect to just pass through synthesized address for DNS queries.
+    for (const auto& config : testConfigs) {
+        SCOPED_TRACE(config.asParameters());
+
+        char host[NI_MAXHOST];
+        struct sockaddr_in6 sin6;
+        memset(&sin6, 0, sizeof(sin6));
+        sin6.sin6_family = AF_INET6;
+        inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
+        int rv = getnameinfo((const struct sockaddr*) &sin6, sizeof(sin6), host, sizeof(host),
+                             nullptr, 0, config.flag);
+        ASSERT_EQ(0, rv);
+        if (config.flag == NI_NAMEREQD) {
+            if (config.hasSynthesizedPtrRecord) {
+                EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
+            } else {
+                EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping));  // PTR record not exist.
+                EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4));            // PTR record exist.
+            }
+        }
+        std::string result_str = host;
+        EXPECT_EQ(result_str, config.host);
+        dns.clearQueries();
+    }
+}
+
+TEST_F(ResolverTest, GetNameInfo_ReverseDns64QueryFromHostFile) {
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char host_name[] = "localhost";
+    // The address is synthesized by prefix64:localhost.
+    constexpr char host_addr[] = "64:ff9b::7f00:1";
+    constexpr char listen_addr[] = "::1";
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // Using synthesized "localhost" address to be a trick for resolving host name
+    // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
+    // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
+    char host[NI_MAXHOST];
+    struct sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
+    inet_pton(AF_INET6, host_addr, &sin6.sin6_addr);
+    int rv = getnameinfo((const struct sockaddr*) &sin6, sizeof(sin6), host, sizeof(host), nullptr,
+                         0, NI_NAMEREQD);
+    ASSERT_EQ(0, rv);
+    // Expect no DNS queries; localhost is resolved via /etc/hosts.
+    EXPECT_EQ(0U, GetNumQueries(dns, host_name));
+
+    std::string result_str = host;
+    EXPECT_EQ(result_str, host_name);
+}
+
+TEST_F(ResolverTest, GetHostByName2_Dns64Synthesize) {
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char host_name[] = "ipv4only.example.com.";
+    const std::vector<DnsRecord> records = {
+            {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // Query an IPv4-only hostname. Expect that gets a synthesized address.
+    struct hostent* result = gethostbyname2("ipv4only", AF_INET6);
+    ASSERT_TRUE(result != nullptr);
+    EXPECT_LE(1U, GetNumQueries(dns, host_name));
+    std::string result_str = ToString(result);
+    EXPECT_EQ(result_str, "64:ff9b::102:304");
+}
+
+TEST_F(ResolverTest, GetHostByName2_DnsQueryWithHavingNat64Prefix) {
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    constexpr char host_name[] = "v4v6.example.com.";
+    constexpr char listen_addr[] = "::1";
+    const std::vector<DnsRecord> records = {
+            {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
+            {host_name, ns_type::ns_t_a, "1.2.3.4"},
+            {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
+    };
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, records);
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // IPv4 DNS query. Prefix should have no effect on it.
+    struct hostent* result = gethostbyname2("v4v6", AF_INET);
+    ASSERT_TRUE(result != nullptr);
+    EXPECT_LE(1U, GetNumQueries(dns, host_name));
+    std::string result_str = ToString(result);
+    EXPECT_EQ(result_str, "1.2.3.4");
+    dns.clearQueries();
+
+    // IPv6 DNS query. Prefix should have no effect on it.
+    result = gethostbyname2("v4v6", AF_INET6);
+    ASSERT_TRUE(result != nullptr);
+    EXPECT_LE(1U, GetNumQueries(dns, host_name));
+    result_str = ToString(result);
+    EXPECT_EQ(result_str, "2001:db8::102:304");
+}
+
+TEST_F(ResolverTest, GetHostByName2_Dns64QuerySpecialUseIPv4Addresses) {
+    constexpr char THIS_NETWORK[] = "this_network";
+    constexpr char LOOPBACK[] = "loopback";
+    constexpr char LINK_LOCAL[] = "link_local";
+    constexpr char MULTICAST[] = "multicast";
+    constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
+
+    constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
+    constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
+    constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
+    constexpr char ADDR_MULTICAST[] = "224.0.0.1";
+    constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
+
+    constexpr char listen_addr[] = "::1";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
+    const std::vector<std::string> servers = {listen_addr};
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    static const struct TestConfig {
+        std::string name;
+        std::string addr;
+
+        std::string asHostName() const {
+            return StringPrintf("%s.example.com.",
+                                name.c_str());
+        }
+    } testConfigs[]{
+        {THIS_NETWORK,      ADDR_THIS_NETWORK},
+        {LOOPBACK,          ADDR_LOOPBACK},
+        {LINK_LOCAL,        ADDR_LINK_LOCAL},
+        {MULTICAST,         ADDR_MULTICAST},
+        {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
+    };
+
+    for (const auto& config : testConfigs) {
+        const std::string testHostName = config.asHostName();
+        SCOPED_TRACE(testHostName);
+
+        const char* host_name = testHostName.c_str();
+        dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
+
+        struct hostent* result = gethostbyname2(config.name.c_str(), AF_INET6);
+        EXPECT_LE(1U, GetNumQueries(dns, host_name));
+
+        // In AF_INET6 case, don't synthesize special use IPv4 address.
+        // Expect to have no answer
+        EXPECT_EQ(nullptr, result);
+
+        dns.clearQueries();
+    }
+}
+
+TEST_F(ResolverTest, PrefixDiscoveryBypassTls) {
+    constexpr char listen_addr[] = "::1";
+    constexpr char cleartext_port[] = "53";
+    constexpr char tls_port[] = "853";
+    constexpr char dns64_name[] = "ipv4only.arpa.";
+    const std::vector<std::string> servers = {listen_addr};
+
+    test::DNSResponder dns(listen_addr);
+    StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
+    test::DnsTlsFrontend tls(listen_addr, tls_port, listen_addr, cleartext_port);
+    ASSERT_TRUE(tls.startServer());
+
+    // Setup OPPORTUNISTIC mode and wait for the validation complete.
+    ASSERT_TRUE(
+            mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "", {}));
+    EXPECT_TRUE(tls.waitForQueries(1, 5000));
+    tls.clearQueries();
+
+    // Start NAT64 prefix discovery and wait for it complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // Verify it bypassed TLS even though there's a TLS server available.
+    EXPECT_EQ(0, tls.queries());
+    EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
+
+    // Restart the testing network to reset the cache.
+    mDnsClient.TearDown();
+    mDnsClient.SetUp();
+    dns.clearQueries();
+
+    // Setup STRICT mode and wait for the validation complete.
+    ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "",
+                                               {base64Encode(tls.fingerprint())}));
+    EXPECT_TRUE(tls.waitForQueries(1, 5000));
+    tls.clearQueries();
+
+    // Start NAT64 prefix discovery and wait for it to complete.
+    EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
+    EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
+
+    // Verify it bypassed TLS despite STRICT mode.
+    EXPECT_EQ(0, tls.queries());
+    EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
+}
+
+namespace {
+
+class ScopedSetNetworkForProcess {
+  public:
+    explicit ScopedSetNetworkForProcess(unsigned netId) {
+        mStoredNetId = getNetworkForProcess();
+        if (netId == mStoredNetId) return;
+        EXPECT_EQ(0, setNetworkForProcess(netId));
+    }
+    ~ScopedSetNetworkForProcess() { EXPECT_EQ(0, setNetworkForProcess(mStoredNetId)); }
+
+  private:
+    unsigned mStoredNetId;
+};
+
+class ScopedSetNetworkForResolv {
+  public:
+    explicit ScopedSetNetworkForResolv(unsigned netId) { EXPECT_EQ(0, setNetworkForResolv(netId)); }
+    ~ScopedSetNetworkForResolv() { EXPECT_EQ(0, setNetworkForResolv(NETID_UNSET)); }
+};
+
+void sendCommand(int fd, const std::string& cmd) {
+    ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size() + 1));
+    EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size() + 1));
+}
+
+int32_t readBE32(int fd) {
+    int32_t tmp;
+    int n = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
+    EXPECT_TRUE(n > 0);
+    return ntohl(tmp);
+}
+
+int readResponseCode(int fd) {
+    char buf[4];
+    int n = TEMP_FAILURE_RETRY(read(fd, &buf, sizeof(buf)));
+    EXPECT_TRUE(n > 0);
+    // The format of response code is that 4 bytes for the code & null.
+    buf[3] = '\0';
+    int result;
+    EXPECT_TRUE(ParseInt(buf, &result));
+    return result;
+}
+
+bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
+    if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
+        return false;
+    }
+    *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
+    return true;
+}
+
+android::net::UidRangeParcel makeUidRangeParcel(int start, int stop) {
+    android::net::UidRangeParcel res;
+    res.start = start;
+    res.stop = stop;
+
+    return res;
+}
+
+void expectNetIdWithLocalNameserversFlag(unsigned netId) {
+    unsigned dnsNetId = 0;
+    EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
+    EXPECT_TRUE(checkAndClearUseLocalNameserversFlag(&dnsNetId));
+    EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
+}
+
+void expectDnsNetIdEquals(unsigned netId) {
+    unsigned dnsNetId = 0;
+    EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
+    EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
+}
+
+void expectDnsNetIdIsDefaultNetwork(android::net::INetd* netdService) {
+    int currentNetid;
+    EXPECT_TRUE(netdService->networkGetDefault(&currentNetid).isOk());
+    expectDnsNetIdEquals(currentNetid);
+}
+
+void expectDnsNetIdWithVpn(android::net::INetd* netdService, unsigned vpnNetId,
+                           unsigned expectedNetId) {
+    EXPECT_TRUE(netdService->networkCreateVpn(vpnNetId, false /* secure */).isOk());
+    uid_t uid = getuid();
+    // Add uid to VPN
+    EXPECT_TRUE(netdService->networkAddUidRanges(vpnNetId, {makeUidRangeParcel(uid, uid)}).isOk());
+    expectDnsNetIdEquals(expectedNetId);
+    EXPECT_TRUE(netdService->networkDestroy(vpnNetId).isOk());
+}
+
+}  // namespace
+
+TEST_F(ResolverTest, getDnsNetId) {
+    // We've called setNetworkForProcess in SetupOemNetwork, so reset to default first.
+    setNetworkForProcess(NETID_UNSET);
+
+    expectDnsNetIdIsDefaultNetwork(mDnsClient.netdService());
+    expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_VPN_NETID);
+
+    // Test with setNetworkForProcess
+    {
+        ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID);
+        expectDnsNetIdEquals(TEST_NETID);
+    }
+
+    // Test with setNetworkForProcess with NETID_USE_LOCAL_NAMESERVERS
+    {
+        ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID |
+                                                              NETID_USE_LOCAL_NAMESERVERS);
+        expectNetIdWithLocalNameserversFlag(TEST_NETID);
+    }
+
+    // Test with setNetworkForResolv
+    {
+        ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
+        expectDnsNetIdEquals(TEST_NETID);
+    }
+
+    // Test with setNetworkForResolv with NETID_USE_LOCAL_NAMESERVERS
+    {
+        ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID |
+                                                            NETID_USE_LOCAL_NAMESERVERS);
+        expectNetIdWithLocalNameserversFlag(TEST_NETID);
+    }
+
+    // Test with setNetworkForResolv under bypassable vpn
+    {
+        ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
+        expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_NETID);
+    }
+
+    // Create socket connected to DnsProxyListener
+    int fd = dns_open_proxy();
+    EXPECT_TRUE(fd > 0);
+    unique_fd ufd(fd);
+
+    // Test command with wrong netId
+    sendCommand(fd, "getdnsnetid abc");
+    EXPECT_EQ(ResponseCode::DnsProxyQueryResult, readResponseCode(fd));
+    EXPECT_EQ(-EINVAL, readBE32(fd));
+
+    // Test unsupported command
+    sendCommand(fd, "getdnsnetidNotSupported");
+    // Keep in sync with FrameworkListener.cpp (500, "Command not recognized")
+    EXPECT_EQ(500, readResponseCode(fd));
+}
diff --git a/resolv/sethostent.cpp b/resolv/sethostent.cpp
new file mode 100644
index 0000000..2885fbc
--- /dev/null
+++ b/resolv/sethostent.cpp
@@ -0,0 +1,204 @@
+/*	$NetBSD: sethostent.c,v 1.20 2014/03/17 13:24:23 christos Exp $	*/
+
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <assert.h>
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+
+#include "hostent.h"
+#include "resolv_private.h"
+
+#define ALIGNBYTES (sizeof(uintptr_t) - 1)
+#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) & ~ALIGNBYTES)
+
+static void sethostent_r(FILE** hf) {
+    if (!*hf)
+        *hf = fopen(_PATH_HOSTS, "re");
+    else
+        rewind(*hf);
+}
+
+static void endhostent_r(FILE** hf) {
+    if (*hf) {
+        (void) fclose(*hf);
+        *hf = NULL;
+    }
+}
+
+// TODO: Consider returning a boolean result as files_getaddrinfo() does because the error code
+// does not currently return to netd.
+int _hf_gethtbyname2(const char* name, int af, getnamaddr* info) {
+    struct hostent *hp, hent;
+    char *buf, *ptr;
+    size_t len, num, i;
+    char* aliases[MAXALIASES];
+    char* addr_ptrs[MAXADDRS];
+
+    FILE* hf = NULL;
+    sethostent_r(&hf);
+    if (hf == NULL) {
+        // TODO: Consider converting to a private extended EAI_* error code.
+        // Currently, the EAI_* value has no corresponding error code for invalid argument socket
+        // length. In order to not rely on errno, convert the original error code pair, EAI_SYSTEM
+        // and EINVAL, to EAI_FAIL.
+        return EAI_FAIL;
+    }
+
+    if ((ptr = buf = (char*) malloc(len = info->buflen)) == NULL) {
+        return EAI_MEMORY;
+    }
+
+    hent.h_name = NULL;
+    hent.h_addrtype = 0;
+    hent.h_length = 0;
+
+    size_t anum = 0;
+    for (num = 0; num < MAXADDRS; /**/) {
+        info->hp->h_addrtype = af;
+        info->hp->h_length = 0;
+
+        int he;
+        hp = netbsd_gethostent_r(hf, info->hp, info->buf, info->buflen, &he);
+        if (hp == NULL) {
+            if (he == NETDB_INTERNAL && errno == ENOSPC) {
+                goto nospc;  // glibc compatibility.
+            }
+            break;
+        }
+
+        if (strcasecmp(hp->h_name, name) != 0) {
+            char** cp;
+            for (cp = hp->h_aliases; *cp != NULL; cp++)
+                if (strcasecmp(*cp, name) == 0) break;
+            // NOTE: does not increment num
+            if (*cp == NULL) continue;
+        }
+
+        if (num == 0) {
+            hent.h_addrtype = hp->h_addrtype;
+            hent.h_length = hp->h_length;
+
+            HENT_SCOPY(hent.h_name, hp->h_name, ptr, len);
+            for (anum = 0; hp->h_aliases[anum]; anum++) {
+                if (anum >= MAXALIASES) goto nospc;
+                HENT_SCOPY(aliases[anum], hp->h_aliases[anum], ptr, len);
+            }
+            ptr = (char*) ALIGN(ptr);
+            if ((size_t)(ptr - buf) >= info->buflen) goto nospc;
+        }
+
+        if (num >= MAXADDRS) goto nospc;
+        HENT_COPY(addr_ptrs[num], hp->h_addr_list[0], hp->h_length, ptr, len);
+
+        num++;
+    }
+    endhostent_r(&hf);
+
+    if (num == 0) {
+        free(buf);
+        // TODO: Perhaps convert HOST_NOT_FOUND to EAI_NONAME instead.
+        // The original return error number is h_errno HOST_NOT_FOUND which was converted to
+        // EAI_NODATA.
+        return EAI_NODATA;
+    }
+
+    hp = info->hp;
+    ptr = info->buf;
+    len = info->buflen;
+
+    hp->h_addrtype = hent.h_addrtype;
+    hp->h_length = hent.h_length;
+
+    HENT_ARRAY(hp->h_aliases, anum, ptr, len);
+    HENT_ARRAY(hp->h_addr_list, num, ptr, len);
+
+    for (i = 0; i < num; i++) {
+        HENT_COPY(hp->h_addr_list[i], addr_ptrs[i], hp->h_length, ptr, len);
+
+        // reserve space for mapping IPv4 address to IPv6 address in place
+        if (hp->h_addrtype == AF_INET) {
+            HENT_COPY(ptr, NAT64_PAD, sizeof(NAT64_PAD), ptr, len);
+        }
+    }
+    hp->h_addr_list[num] = NULL;
+
+    HENT_SCOPY(hp->h_name, hent.h_name, ptr, len);
+
+    for (i = 0; i < anum; i++) {
+        HENT_SCOPY(hp->h_aliases[i], aliases[i], ptr, len);
+    }
+    hp->h_aliases[anum] = NULL;
+
+    free(buf);
+    return 0;
+nospc:
+    free(buf);
+    return EAI_MEMORY;
+}
+
+// TODO: Consider returning a boolean result as files_getaddrinfo() does because the error code
+// does not currently return to netd.
+int _hf_gethtbyaddr(const unsigned char* uaddr, int len, int af, getnamaddr* info) {
+    info->hp->h_length = len;
+    info->hp->h_addrtype = af;
+
+    FILE* hf = NULL;
+    sethostent_r(&hf);
+    if (hf == NULL) {
+        // TODO: Consider converting to a private extended EAI_* error code.
+        // Currently, the EAI_* value has no corresponding error code for invalid argument socket
+        // length. In order to not rely on errno, convert the original error code pair, EAI_SYSTEM
+        // and EINVAL, to EAI_FAIL.
+        return EAI_FAIL;
+    }
+    struct hostent* hp;
+    int he;
+    while ((hp = netbsd_gethostent_r(hf, info->hp, info->buf, info->buflen, &he)) != NULL)
+        if (!memcmp(hp->h_addr_list[0], uaddr, (size_t) hp->h_length)) break;
+    endhostent_r(&hf);
+
+    if (hp == NULL) {
+        if (errno == ENOSPC) return EAI_MEMORY;  // glibc compatibility.
+        // TODO: Perhaps convert HOST_NOT_FOUND to EAI_NONAME instead.
+        // The original return error number is h_errno HOST_NOT_FOUND which was converted to
+        // EAI_NODATA.
+        return EAI_NODATA;
+    }
+    return 0;
+}
diff --git a/resolv/stats.proto b/resolv/stats.proto
new file mode 100644
index 0000000..60e2071
--- /dev/null
+++ b/resolv/stats.proto
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+package android.net;
+
+enum EventType {
+    EVENT_UNKNOWN = 0;
+    EVENT_GETADDRINFO = 1;
+    EVENT_GETHOSTBYNAME = 2;
+    EVENT_GETHOSTBYADDR = 3;
+    EVENT_RES_NSEND = 4;
+}
+
+// The return value of the DNS resolver for each DNS lookups.
+// bionic/libc/include/netdb.h
+// system/netd/resolv/include/netd_resolv/resolv.h
+enum ReturnCode {
+    RC_EAI_NO_ERROR = 0;
+    RC_EAI_ADDRFAMILY = 1;
+    RC_EAI_AGAIN = 2;
+    RC_EAI_BADFLAGS = 3;
+    RC_EAI_FAIL = 4;
+    RC_EAI_FAMILY = 5;
+    RC_EAI_MEMORY = 6;
+    RC_EAI_NODATA = 7;
+    RC_EAI_NONAME = 8;
+    RC_EAI_SERVICE = 9;
+    RC_EAI_SOCKTYPE = 10;
+    RC_EAI_SYSTEM = 11;
+    RC_EAI_BADHINTS = 12;
+    RC_EAI_PROTOCOL = 13;
+    RC_EAI_OVERFLOW = 14;
+    RC_RESOLV_TIMEOUT = 255;
+    RC_EAI_MAX = 256;
+}
+
+enum NsRcode {
+    NS_R_NO_ERROR = 0;  // No error occurred.
+    NS_R_FORMERR = 1;   // Format error.
+    NS_R_SERVFAIL = 2;  // Server failure.
+    NS_R_NXDOMAIN = 3;  // Name error.
+    NS_R_NOTIMPL = 4;   // Unimplemented.
+    NS_R_REFUSED = 5;   // Operation refused.
+    // these are for BIND_UPDATE
+    NS_R_YXDOMAIN = 6;  // Name exists
+    NS_R_YXRRSET = 7;   // RRset exists
+    NS_R_NXRRSET = 8;   // RRset does not exist
+    NS_R_NOTAUTH = 9;   // Not authoritative for zone
+    NS_R_NOTZONE = 10;  // Zone of record different from zone section
+    NS_R_MAX = 11;
+    // The following are EDNS extended rcodes
+    NS_R_BADVERS = 16;
+    // The following are TSIG errors
+    // NS_R_BADSIG  = 16,
+    NS_R_BADKEY = 17;
+    NS_R_BADTIME = 18;
+    NS_R_INTERNAL_ERROR = 254;
+    NS_R_TIMEOUT = 255;
+}
+
+// Currently defined type values for resources and queries.
+enum NsType {
+    NS_T_INVALID = 0;      // Cookie.
+    NS_T_A = 1;            // Host address.
+    NS_T_NS = 2;           // Authoritative server.
+    NS_T_MD = 3;           // Mail destination.
+    NS_T_MF = 4;           // Mail forwarder.
+    NS_T_CNAME = 5;        // Canonical name.
+    NS_T_SOA = 6;          // Start of authority zone.
+    NS_T_MB = 7;           // Mailbox domain name.
+    NS_T_MG = 8;           // Mail group member.
+    NS_T_MR = 9;           // Mail rename name.
+    NS_T_NULL = 10;        // Null resource record.
+    NS_T_WKS = 11;         // Well known service.
+    NS_T_PTR = 12;         // Domain name pointer.
+    NS_T_HINFO = 13;       // Host information.
+    NS_T_MINFO = 14;       // Mailbox information.
+    NS_T_MX = 15;          // Mail routing information.
+    NS_T_TXT = 16;         // Text strings.
+    NS_T_RP = 17;          // Responsible person.
+    NS_T_AFSDB = 18;       // AFS cell database.
+    NS_T_X25 = 19;         // X_25 calling address.
+    NS_T_ISDN = 20;        // ISDN calling address.
+    NS_T_RT = 21;          // Router.
+    NS_T_NSAP = 22;        // NSAP address.
+    NS_T_NSAP_PTR = 23;    // Reverse NSAP lookup (deprecated).
+    NS_T_SIG = 24;         // Security signature.
+    NS_T_KEY = 25;         // Security key.
+    NS_T_PX = 26;          // X.400 mail mapping.
+    NS_T_GPOS = 27;        // Geographical position (withdrawn).
+    NS_T_AAAA = 28;        // IPv6 Address.
+    NS_T_LOC = 29;         // Location Information.
+    NS_T_NXT = 30;         // Next domain (security).
+    NS_T_EID = 31;         // Endpoint identifier.
+    NS_T_NIMLOC = 32;      // Nimrod Locator.
+    NS_T_SRV = 33;         // Server Selection.
+    NS_T_ATMA = 34;        // ATM Address
+    NS_T_NAPTR = 35;       // Naming Authority PoinTeR
+    NS_T_KX = 36;          // Key Exchange
+    NS_T_CERT = 37;        // Certification record
+    NS_T_A6 = 38;          // IPv6 address (experimental)
+    NS_T_DNAME = 39;       // Non-terminal DNAME
+    NS_T_SINK = 40;        // Kitchen sink (experimentatl)
+    NS_T_OPT = 41;         // EDNS0 option (meta-RR)
+    NS_T_APL = 42;         // Address prefix list (RFC 3123)
+    NS_T_DS = 43;          // Delegation Signer
+    NS_T_SSHFP = 44;       // SSH Fingerprint
+    NS_T_IPSECKEY = 45;    // IPSEC Key
+    NS_T_RRSIG = 46;       // RRset Signature
+    NS_T_NSEC = 47;        // Negative security
+    NS_T_DNSKEY = 48;      // DNS Key
+    NS_T_DHCID = 49;       // Dynamic host configuratin identifier
+    NS_T_NSEC3 = 50;       // Negative security type 3
+    NS_T_NSEC3PARAM = 51;  // Negative security type 3 parameters
+    NS_T_HIP = 55;         // Host Identity Protocol
+    NS_T_SPF = 99;         // Sender Policy Framework
+    NS_T_TKEY = 249;       // Transaction key
+    NS_T_TSIG = 250;       // Transaction signature.
+    NS_T_IXFR = 251;       // Incremental zone transfer.
+    NS_T_AXFR = 252;       // Transfer zone of authority.
+    NS_T_MAILB = 253;      // Transfer mailbox records.
+    NS_T_MAILA = 254;      // Transfer mail agent records.
+    NS_T_ANY = 255;        // Wildcard match.
+    NS_T_ZXFR = 256;       // BIND-specific, nonstandard.
+    NS_T_DLV = 32769;      // DNSSEC look-aside validatation.
+    NS_T_MAX = 65536;
+}
+
+enum IpVersion {
+    IV_UNKNOWN = 0;
+    IV_IPV4 = 1;
+    IV_IPV6 = 2;
+}
+
+enum Protocol {
+    PROTO_UNKNOWN = 0;
+    PROTO_UDP = 1;
+    PROTO_TCP = 2;
+    PROTO_DOT = 3;
+}
+
+enum PrivateDnsModes {
+    PDM_UNKNOWN = 0;
+    PDM_OFF = 1;
+    PDM_OPPORTUNISTIC = 2;
+    PDM_STRICT = 3;
+}
+
+enum NetworkType {
+    NT_UNKNOWN = 0;
+    // Indicates this network uses a Cellular transport.
+    NT_CELLULAR = 1;
+    // Indicates this network uses a Wi-Fi transport.
+    NT_WIFI = 2;
+    // Indicates this network uses a Bluetooth transport.
+    NT_BLUETOOTH = 3;
+    // Indicates this network uses an Ethernet transport.
+    NT_ETHERNET = 4;
+    // Indicates this network uses a VPN transport.
+    NT_VPN = 5;
+    // Indicates this network uses a Wi-Fi Aware transport.
+    NT_WIFI_AWARE = 6;
+    // Indicates this network uses a LoWPAN transport.
+    NT_LOWPAN = 7;
+}
+
+enum CacheStatus{
+    // the cache can't handle that kind of queries.
+    // or the answer buffer is too small.
+    CS_UNSUPPORTED = 0;
+    // the cache doesn't know about this query.
+    CS_NOTFOUND = 1;
+    // the cache found the answer.
+    CS_FOUND = 2;
+    // Don't do anything on cache.
+    CS_SKIP = 3;
+}
+
+message DnsQueryEvent {
+    optional NsRcode rcode = 1;
+
+    optional NsType type = 2;
+
+    optional CacheStatus cache_hit = 3;
+
+    optional IpVersion ip_version = 4;
+
+    optional Protocol protocol = 5;
+
+    // Number of DNS query retry times
+    optional int32 retry_times = 6;
+
+    // Ordinal number of name server.
+    optional int32 dns_server_index = 7;
+
+    // Used only by TCP and DOT. True for new connections.
+    optional bool connected = 8;
+
+    optional int32 latency_micros = 9;
+}
+
+message DnsQueryEvents {
+    repeated DnsQueryEvent dns_query_event = 1;
+}
+
+/**
+ * Logs a DNS lookup operation initiated by the system resolver on behalf of an application
+ * invoking native APIs such as getaddrinfo() or Java APIs such as Network#getAllByName().
+ *
+ * The NetworkDnsEventReported message represents the entire lookup operation, which may
+ * result one or more queries to the recursive DNS resolvers. Those are individually logged
+ * in DnsQueryEvents to enable computing error rates and network latency and timeouts
+ * broken up by query type, transport, network interface, etc.
+ */
+message NetworkDnsEventReported {
+    optional EventType event_type = 1;
+
+    optional ReturnCode return_code = 2;
+
+    // The latency in microseconds of the entire DNS lookup operation.
+    optional int32 latency_micros = 3;
+
+    // Only valid for event_type = EVENT_GETADDRINFO.
+    optional int32 hints_ai_flags = 4;
+
+    // Flags passed to android_res_nsend() defined in multinetwork.h
+    // Only valid for event_type = EVENT_RESNSEND.
+    optional int32 res_nsend_flags = 5;
+
+    optional NetworkType network_type = 6;
+
+    // The DNS over TLS mode on a specific netId.
+    optional PrivateDnsModes private_dns_modes = 7;
+
+    // Additional pass-through fields opaque to statsd.
+    // The DNS resolver Mainline module can add new fields here without requiring an OS update.
+    optional DnsQueryEvents dns_query_events = 8;
+
+    // The sample rate of DNS stats (to statsd) is 1/sampling_rate_denom.
+    optional int32 sampling_rate_denom = 9;
+}
diff --git a/resolv/tests/BaseTestMetricsListener.cpp b/resolv/tests/BaseTestMetricsListener.cpp
new file mode 100644
index 0000000..414e383
--- /dev/null
+++ b/resolv/tests/BaseTestMetricsListener.cpp
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BaseTestMetricsListener.h"
+
+namespace android {
+namespace net {
+namespace metrics {
+
+void BaseTestMetricsListener::notify() {
+    std::lock_guard lock(mCvMutex);
+    mCv.notify_one();
+}
+
+void BaseTestMetricsListener::setVerified(EventFlag event) {
+    mVerified |= event;
+}
+
+android::binder::Status BaseTestMetricsListener::onDnsEvent(
+        int32_t /*netId*/, int32_t /*eventType*/, int32_t /*returnCode*/, int32_t /*latencyMs*/,
+        const std::string& /*hostname*/, const ::std::vector<std::string>& /*ipAddresses*/,
+        int32_t /*ipAddressesCount*/, int32_t /*uid*/) {
+    // default no-op
+    return android::binder::Status::ok();
+};
+
+android::binder::Status BaseTestMetricsListener::onPrivateDnsValidationEvent(
+        int32_t /*netId*/, const ::android::String16& /*ipAddress*/,
+        const ::android::String16& /*hostname*/, bool /*validated*/) {
+    // default no-op
+    return android::binder::Status::ok();
+};
+
+android::binder::Status BaseTestMetricsListener::onConnectEvent(
+        int32_t /*netId*/, int32_t /*error*/, int32_t /*latencyMs*/,
+        const ::android::String16& /*ipAddr*/, int32_t /*port*/, int32_t /*uid*/) {
+    // default no-op
+    return android::binder::Status::ok();
+};
+
+android::binder::Status BaseTestMetricsListener::onWakeupEvent(
+        const ::android::String16& /*prefix*/, int32_t /*uid*/, int32_t /*ethertype*/,
+        int32_t /*ipNextHeader*/, const ::std::vector<uint8_t>& /*dstHw*/,
+        const ::android::String16& /*srcIp*/, const ::android::String16& /*dstIp*/,
+        int32_t /*srcPort*/, int32_t /*dstPort*/, int64_t /*timestampNs*/) {
+    // default no-op
+    return android::binder::Status::ok();
+};
+
+android::binder::Status BaseTestMetricsListener::onTcpSocketStatsEvent(
+        const ::std::vector<int32_t>& /*networkIds*/, const ::std::vector<int32_t>& /*sentPackets*/,
+        const ::std::vector<int32_t>& /*lostPackets*/, const ::std::vector<int32_t>& /*rttUs*/,
+        const ::std::vector<int32_t>& /*sentAckDiffMs*/) {
+    // default no-op
+    return android::binder::Status::ok();
+};
+
+android::binder::Status BaseTestMetricsListener::onNat64PrefixEvent(
+        int32_t /*netId*/, bool /*added*/, const ::std::string& /*prefixString*/,
+        int32_t /*prefixLength*/) {
+    // default no-op
+    return android::binder::Status::ok();
+};
+
+}  // namespace metrics
+}  // namespace net
+}  // namespace android
\ No newline at end of file
diff --git a/resolv/tests/BaseTestMetricsListener.h b/resolv/tests/BaseTestMetricsListener.h
new file mode 100644
index 0000000..326647b
--- /dev/null
+++ b/resolv/tests/BaseTestMetricsListener.h
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _BASE_TEST_METRICS_LISTENER_H_
+#define _BASE_TEST_METRICS_LISTENER_H_
+
+#include <string>
+#include <vector>
+
+#include <binder/BinderService.h>
+
+#include "android/net/metrics/BnNetdEventListener.h"
+
+enum EventFlag : uint32_t {
+    onDnsEvent = 1 << 0,
+    onPrivateDnsValidationEvent = 1 << 1,
+    onConnectEvent = 1 << 2,
+    onWakeupEvent = 1 << 3,
+    onTcpSocketStatsEvent = 1 << 4,
+    onNat64PrefixEvent = 1 << 5,
+};
+
+namespace android {
+namespace net {
+namespace metrics {
+
+class BaseTestMetricsListener : public BnNetdEventListener {
+  public:
+    BaseTestMetricsListener() = default;
+    ~BaseTestMetricsListener() = default;
+
+    // Returns TRUE if the verification was successful. Otherwise, returns FALSE.
+    virtual bool isVerified() = 0;
+
+    std::condition_variable& getCv() { return mCv; }
+    std::mutex& getCvMutex() { return mCvMutex; }
+
+    android::binder::Status onDnsEvent(int32_t /*netId*/, int32_t /*eventType*/,
+                                       int32_t /*returnCode*/, int32_t /*latencyMs*/,
+                                       const std::string& /*hostname*/,
+                                       const ::std::vector<std::string>& /*ipAddresses*/,
+                                       int32_t /*ipAddressesCount*/, int32_t /*uid*/) override;
+    android::binder::Status onPrivateDnsValidationEvent(int32_t /*netId*/,
+                                                        const ::android::String16& /*ipAddress*/,
+                                                        const ::android::String16& /*hostname*/,
+                                                        bool /*validated*/) override;
+    android::binder::Status onConnectEvent(int32_t /*netId*/, int32_t /*error*/,
+                                           int32_t /*latencyMs*/,
+                                           const ::android::String16& /*ipAddr*/, int32_t /*port*/,
+                                           int32_t /*uid*/) override;
+    android::binder::Status onWakeupEvent(const ::android::String16& /*prefix*/, int32_t /*uid*/,
+                                          int32_t /*ethertype*/, int32_t /*ipNextHeader*/,
+                                          const ::std::vector<uint8_t>& /*dstHw*/,
+                                          const ::android::String16& /*srcIp*/,
+                                          const ::android::String16& /*dstIp*/, int32_t /*srcPort*/,
+                                          int32_t /*dstPort*/, int64_t /*timestampNs*/) override;
+    android::binder::Status onTcpSocketStatsEvent(
+            const ::std::vector<int32_t>& /*networkIds*/,
+            const ::std::vector<int32_t>& /*sentPackets*/,
+            const ::std::vector<int32_t>& /*lostPackets*/, const ::std::vector<int32_t>& /*rttUs*/,
+            const ::std::vector<int32_t>& /*sentAckDiffMs*/) override;
+    android::binder::Status onNat64PrefixEvent(int32_t /*netId*/, bool /*added*/,
+                                               const ::std::string& /*prefixString*/,
+                                               int32_t /*prefixLength*/) override;
+
+  private:
+    // The verified event(s) as a bitwise-OR combination of enum EventFlag flags.
+    uint32_t mVerified{};
+
+    // This lock prevents racing condition between signaling thread(s) and waiting thread(s).
+    std::mutex mCvMutex;
+
+    // Condition variable signaled when notify() is called.
+    std::condition_variable mCv;
+
+  protected:
+    // Notify who is waiting for test results. See also mCvMutex and mCv.
+    void notify();
+
+    // Get current verified event(s).
+    uint32_t getVerified() const { return mVerified; }
+
+    // Set the specific event as verified if its verification was successful.
+    void setVerified(EventFlag event);
+};
+
+}  // namespace metrics
+}  // namespace net
+}  // namespace android
+
+#endif  // _BASE_TEST_METRICS_LISTENER_H_
diff --git a/resolv/tests/TestMetrics.cpp b/resolv/tests/TestMetrics.cpp
new file mode 100644
index 0000000..4c3d36a
--- /dev/null
+++ b/resolv/tests/TestMetrics.cpp
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <netdb.h>
+
+#include "TestMetrics.h"
+
+namespace android {
+namespace net {
+namespace metrics {
+
+android::binder::Status TestOnDnsEvent::onDnsEvent(int32_t netId, int32_t eventType,
+                                                   int32_t returnCode, int32_t /*latencyMs*/,
+                                                   const std::string& hostname,
+                                                   const ::std::vector<std::string>& ipAddresses,
+                                                   int32_t ipAddressesCount, int32_t /*uid*/) {
+    // A bitwise-OR combination of all expected test cases.
+    // Currently, the maximum number of test case is 32 because a 32-bits bitwise-OR combination
+    // is used for checking and recording verified test cases.
+    static const uint32_t kExpectedTests = (1 << mResults.size()) - 1;
+
+    // A bitwise-OR combination for recording verified test cases.
+    static uint32_t verifiedTests = 0;
+
+    for (size_t i = 0; i < mResults.size(); ++i) {
+        // Generate bitwise flag to trace which testcase is running.
+        const uint32_t currentTestFlag = 1 << i;
+
+        // Ignore verified testcase.
+        if (verifiedTests & currentTestFlag) continue;
+
+        // Verify expected event content.
+        auto& result = mResults[i];
+        if (netId != result.netId) continue;
+        if (eventType != result.eventType) continue;
+        if (hostname != result.hostname) continue;
+        if (returnCode != result.returnCode) continue;
+        if (ipAddressesCount != result.ipAddressesCount) continue;
+        if (result.returnCode == 0 /*success*/) {
+            // Only verify first address.
+            // TODO: Check all addresses.
+            if (ipAddresses.empty() || ipAddresses.front() != result.ipAddress) continue;
+        }
+
+        // Record current testcase as verified.
+        verifiedTests |= currentTestFlag;
+        break;
+    }
+
+    // All testcases of onDnsEvent are verified. Notify who was waiting for test results.
+    if (verifiedTests == kExpectedTests) {
+        setVerified(EventFlag::onDnsEvent);
+        notify();
+    }
+
+    return android::binder::Status::ok();
+};
+
+}  // namespace metrics
+}  // namespace net
+}  // namespace android
\ No newline at end of file
diff --git a/resolv/tests/TestMetrics.h b/resolv/tests/TestMetrics.h
new file mode 100644
index 0000000..d3a4ad4
--- /dev/null
+++ b/resolv/tests/TestMetrics.h
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _TEST_METRICS_H_
+#define _TEST_METRICS_H_
+
+#include "BaseTestMetricsListener.h"
+
+namespace android {
+namespace net {
+namespace metrics {
+
+class TestOnDnsEvent : public BaseTestMetricsListener {
+  public:
+    // Both latencyMs and uid are not verified. No special reason.
+    struct TestResult {
+        int netId;
+        int eventType;
+        int returnCode;
+        int ipAddressesCount;
+        std::string hostname;
+        std::string ipAddress;  // Check first address only.
+    };
+
+    TestOnDnsEvent() = delete;
+    TestOnDnsEvent(const std::vector<TestResult>& results) : mResults(results){};
+
+    // BaseTestMetricsListener::isVerified() override.
+    bool isVerified() override { return (getVerified() & EventFlag::onDnsEvent) != 0; }
+
+    // Override for testing verification.
+    android::binder::Status onDnsEvent(int32_t netId, int32_t eventType, int32_t returnCode,
+                                       int32_t /*latencyMs*/, const std::string& hostname,
+                                       const std::vector<std::string>& ipAddresses,
+                                       int32_t ipAddressesCount, int32_t /*uid*/) override;
+
+  private:
+    const std::vector<TestResult>& mResults;  // Expected results for test verification.
+};
+
+}  // namespace metrics
+}  // namespace net
+}  // namespace android
+
+#endif  // _TEST_METRICS_H_
diff --git a/server/Android.bp b/server/Android.bp
index eba80bc..c7f2984 100644
--- a/server/Android.bp
+++ b/server/Android.bp
@@ -95,14 +95,15 @@
         "libbpf_android",
         "libbase",
         "libbinder",
+        "liblogwrap",
         "libnetdbpf",
         "libnetutils",
         "libnetdutils",
         "libpcap",
         "libqtaguid",
         "libssl",
-        "netd_aidl_interface-cpp",
-        "netd_event_listener_interface-cpp",
+        "netd_aidl_interface-V2-cpp",
+        "netd_event_listener_interface-V1-cpp",
     ],
     header_libs: [
         "libnetd_resolv_headers",
@@ -130,8 +131,10 @@
         "libcutils",
         "libdl",
         "libhidlbase",
+        "libhidltransport",
         "libjsoncpp",
         "liblog",
+        "liblogwrap",
         "libmdnssd",
         "libnetdbpf",
         "libnetdutils",
@@ -142,8 +145,8 @@
         "libselinux",
         "libsysutils",
         "libutils",
-        "netd_aidl_interface-unstable-cpp",
-        "netd_event_listener_interface-cpp",
+        "netd_aidl_interface-V2-cpp",
+        "netd_event_listener_interface-V1-cpp",
         "oemnetd_aidl_interface-cpp",
     ],
     static_libs: [
@@ -192,8 +195,8 @@
         "liblog",
         "libutils",
         "libbinder",
-        "dnsresolver_aidl_interface-cpp",
-        "netd_aidl_interface-cpp",
+        "dnsresolver_aidl_interface-V2-cpp",
+        "netd_aidl_interface-V2-cpp",
     ],
     srcs: [
         "ndc.cpp",
@@ -211,6 +214,7 @@
         "system/netd/include",
         "system/netd/server/binder",
         "system/netd/tests",
+        "system/core/logwrapper/include",
     ],
     srcs: [
         "BandwidthControllerTest.cpp",
@@ -235,9 +239,6 @@
         "libgmock",
         "libnetd_server",
         "libnetd_test_tun_interface",
-        "libqtaguid",
-        "netd_aidl_interface-cpp",
-        "netd_event_listener_interface-cpp",
     ],
     shared_libs: [
         "libbase",
@@ -249,7 +250,10 @@
         "libnetdbpf",
         "libnetdutils",
         "libnetutils",
+        "libqtaguid",
         "libsysutils",
         "libutils",
+        "netd_aidl_interface-V2-cpp",
+        "netd_event_listener_interface-V1-cpp",
     ],
 }
diff --git a/server/AndroidTest.xml b/server/AndroidTest.xml
new file mode 100644
index 0000000..2501d78
--- /dev/null
+++ b/server/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for netd_unit_test">
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="netd_unit_test->/data/local/tmp/netd_unit_test" />
+    </target_preparer>
+    <option name="test-suite-tag" value="apct" />
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="netd_unit_test" />
+    </test>
+</configuration>
diff --git a/server/BandwidthController.cpp b/server/BandwidthController.cpp
index 3efc8a3..7e9bff7 100644
--- a/server/BandwidthController.cpp
+++ b/server/BandwidthController.cpp
@@ -48,6 +48,7 @@
 #define LOG_TAG "BandwidthController"
 #include <cutils/properties.h>
 #include <log/log.h>
+#include <logwrap/logwrap.h>
 
 #include <netdutils/Syscalls.h>
 #include "BandwidthController.h"
diff --git a/server/ClatdController.cpp b/server/ClatdController.cpp
index cf0ab96..5a5566b 100644
--- a/server/ClatdController.cpp
+++ b/server/ClatdController.cpp
@@ -33,7 +33,6 @@
 #include <log/log.h>
 
 #include "ClatdController.h"
-#include "InterfaceController.h"
 
 #include "android-base/properties.h"
 #include "android-base/scopeguard.h"
@@ -140,11 +139,7 @@
 
     // Attempt to connect to the address. If the connection succeeds and getsockname returns the
     // same then the address is already assigned to the system and we can't use it.
-    struct sockaddr_in sin = {
-            .sin_family = AF_INET,
-            .sin_port = htons(53),
-            .sin_addr = {addr},
-    };
+    struct sockaddr_in sin = {.sin_family = AF_INET, .sin_addr = {addr}, .sin_port = 53};
     socklen_t len = sizeof(sin);
     bool inuse = connect(s, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
                  getsockname(s, (struct sockaddr*)&sin, &len) == 0 && (size_t)len >= sizeof(sin) &&
@@ -457,10 +452,6 @@
         return -res;
     }
 
-    // disable IPv6 on it - failing to do so is not a critical error
-    res = InterfaceController::setEnableIPv6(v4interface.c_str(), 0);
-    if (res) ALOGE("setEnableIPv6 %s failed (%s)", v4interface.c_str(), strerror(res));
-
     // 5. initialize tracker object
     ClatdTracker tracker;
     int ret = tracker.init(networkId, interface, v4interface, nat64Prefix);
diff --git a/server/Controllers.cpp b/server/Controllers.cpp
index f844544..c941a80 100644
--- a/server/Controllers.cpp
+++ b/server/Controllers.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <cinttypes>
 #include <regex>
 #include <set>
 #include <string>
@@ -240,39 +239,39 @@
 void Controllers::initIptablesRules() {
     Stopwatch s;
     initChildChains();
-    gLog.info("Creating child chains: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Creating child chains: %.1fms", s.getTimeAndReset());
 
     // Let each module setup their child chains
     setupOemIptablesHook();
-    gLog.info("Setting up OEM hooks: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Setting up OEM hooks: %.1fms", s.getTimeAndReset());
 
     /* When enabled, DROPs all packets except those matching rules. */
     firewallCtrl.setupIptablesHooks();
-    gLog.info("Setting up FirewallController hooks: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Setting up FirewallController hooks: %.1fms", s.getTimeAndReset());
 
     /* Does DROPs in FORWARD by default */
     tetherCtrl.setupIptablesHooks();
-    gLog.info("Setting up TetherController hooks: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Setting up TetherController hooks: %.1fms", s.getTimeAndReset());
 
     /*
      * Does REJECT in INPUT, OUTPUT. Does counting also.
      * No DROP/REJECT allowed later in netfilter-flow hook order.
      */
     bandwidthCtrl.setupIptablesHooks();
-    gLog.info("Setting up BandwidthController hooks: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Setting up BandwidthController hooks: %.1fms", s.getTimeAndReset());
 
     /*
      * Counts in nat: PREROUTING, POSTROUTING.
      * No DROP/REJECT allowed later in netfilter-flow hook order.
      */
     idletimerCtrl.setupIptablesHooks();
-    gLog.info("Setting up IdletimerController hooks: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Setting up IdletimerController hooks: %.1fms", s.getTimeAndReset());
 
     /*
      * Add rules for detecting IPv6/IPv4 TCP/UDP connections with TLS/DTLS header
      */
     strictCtrl.setupIptablesHooks();
-    gLog.info("Setting up StrictController hooks: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Setting up StrictController hooks: %.1fms", s.getTimeAndReset());
 }
 
 void Controllers::init() {
@@ -280,28 +279,28 @@
     Stopwatch s;
 
     clatdCtrl.init();
-    gLog.info("Initializing ClatdController: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Initializing ClatdController: %.1fms", s.getTimeAndReset());
 
     netdutils::Status tcStatus = trafficCtrl.start();
     if (!isOk(tcStatus)) {
         gLog.error("Failed to start trafficcontroller: (%s)", toString(tcStatus).c_str());
     }
-    gLog.info("Initializing traffic control: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Initializing traffic control: %.1fms", s.getTimeAndReset());
 
     bandwidthCtrl.setBpfEnabled(trafficCtrl.getBpfLevel() != android::bpf::BpfLevel::NONE);
     bandwidthCtrl.enableBandwidthControl();
-    gLog.info("Enabling bandwidth control: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Enabling bandwidth control: %.1fms", s.getTimeAndReset());
 
     if (int ret = RouteController::Init(NetworkController::LOCAL_NET_ID)) {
         gLog.error("Failed to initialize RouteController (%s)", strerror(-ret));
     }
-    gLog.info("Initializing RouteController: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Initializing RouteController: %.1fms", s.getTimeAndReset());
 
     netdutils::Status xStatus = XfrmController::Init();
     if (!isOk(xStatus)) {
         gLog.error("Failed to initialize XfrmController (%s)", netdutils::toString(xStatus).c_str());
     };
-    gLog.info("Initializing XfrmController: %" PRId64 "us", s.getTimeAndResetUs());
+    gLog.info("Initializing XfrmController: %.1fms", s.getTimeAndReset());
 }
 
 Controllers* gCtls = nullptr;
diff --git a/server/DummyNetwork.h b/server/DummyNetwork.h
index 5823ce5..32584aa 100644
--- a/server/DummyNetwork.h
+++ b/server/DummyNetwork.h
@@ -14,22 +14,27 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef NETD_SERVER_DUMMY_NETWORK_H
+#define NETD_SERVER_DUMMY_NETWORK_H
 
 #include "Network.h"
 
-namespace android::net {
+namespace android {
+namespace net {
 
 class DummyNetwork : public Network {
-  public:
+public:
     static const char* INTERFACE_NAME;
     explicit DummyNetwork(unsigned netId);
     virtual ~DummyNetwork();
 
-  private:
+private:
     Type getType() const override;
-    [[nodiscard]] int addInterface(const std::string& interface) override;
-    [[nodiscard]] int removeInterface(const std::string& interface) override;
+    int addInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+    int removeInterface(const std::string& interface) override WARN_UNUSED_RESULT;
 };
 
-}  // namespace android::net
+}  // namespace net
+}  // namespace android
+
+#endif  // NETD_SERVER_DUMMY_NETWORK_H
diff --git a/server/IdletimerController.cpp b/server/IdletimerController.cpp
index 103e7cd..acb8c6a 100644
--- a/server/IdletimerController.cpp
+++ b/server/IdletimerController.cpp
@@ -115,6 +115,7 @@
 
 #define LOG_TAG "IdletimerController"
 #include <log/log.h>
+#include <logwrap/logwrap.h>
 
 #include "IdletimerController.h"
 #include "NetdConstants.h"
diff --git a/server/InterfaceController.cpp b/server/InterfaceController.cpp
index 7504fb9..bad4ba2 100644
--- a/server/InterfaceController.cpp
+++ b/server/InterfaceController.cpp
@@ -30,6 +30,7 @@
 #include <android-base/strings.h>
 #include <linux/if_ether.h>
 #include <log/log.h>
+#include <logwrap/logwrap.h>
 #include <netutils/ifc.h>
 
 #include <android/net/INetd.h>
@@ -55,6 +56,13 @@
 using android::netdutils::toString;
 using android::netdutils::status::ok;
 
+#define RETURN_STATUS_IF_IFCERROR(exp)                           \
+    do {                                                         \
+        if ((exp) == -1) {                                       \
+            return statusFromErrno(errno, "Failed to add addr"); \
+        }                                                        \
+    } while (0);
+
 namespace {
 
 const char ipv4_proc_path[] = "/proc/sys/net/ipv4/conf";
@@ -282,9 +290,9 @@
 
     switch (mode) {
         case INetd::IPV6_ADDR_GEN_MODE_EUI64:
-            // Ignore return value. If /proc/.../addr_gen_mode is
+            // Ignore return value. If /proc/.../stable_secret is
             // missing we're probably in EUI64 mode already.
-            writeValueToPath(ipv6_proc_path, interface.c_str(), "addr_gen_mode", "0");
+            writeValueToPath(ipv6_proc_path, interface.c_str(), "stable_secret", "");
             break;
         case INetd::IPV6_ADDR_GEN_MODE_STABLE_PRIVACY: {
             return enableStablePrivacyAddresses(interface, getProperty, setProperty);
@@ -360,13 +368,11 @@
     return writeValueToPath(sys_net_path, interface, "mtu", mtu);
 }
 
-// Returns zero on success and negative errno on failure.
 int InterfaceController::addAddress(const char *interface,
         const char *addrString, int prefixLength) {
     return ifc_add_address(interface, addrString, prefixLength);
 }
 
-// Returns zero on success and negative errno on failure.
 int InterfaceController::delAddress(const char *interface,
         const char *addrString, int prefixLength) {
     return ifc_del_address(interface, addrString, prefixLength);
@@ -499,9 +505,8 @@
         }
     }
 
-    if (int ret = ifc_add_address(cfg.ifName.c_str(), cfg.ipv4Addr.c_str(), cfg.prefixLength)) {
-        return statusFromErrno(-ret, "Failed to add addr");
-    }
+    RETURN_STATUS_IF_IFCERROR(
+            ifc_add_address(cfg.ifName.c_str(), cfg.ipv4Addr.c_str(), cfg.prefixLength));
 
     return ok;
 }
diff --git a/server/IptablesRestoreControllerTest.cpp b/server/IptablesRestoreControllerTest.cpp
index 20f6183..d01d7ce 100644
--- a/server/IptablesRestoreControllerTest.cpp
+++ b/server/IptablesRestoreControllerTest.cpp
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
+#include <string>
 #include <fcntl.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
 #include <sys/file.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 
-#include <cinttypes>
-#include <iostream>
-#include <string>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
 
 #define LOG_TAG "IptablesRestoreControllerTest"
 #include <android-base/stringprintf.h>
@@ -55,7 +53,9 @@
   int mIptablesLock = -1;
   std::string mChainName;
 
-  static void SetUpTestSuite() { blockSigpipe(); }
+  static void SetUpTestCase() {
+      blockSigpipe();
+  }
 
   void SetUp() {
     ASSERT_EQ(0, createTestChain());
@@ -269,9 +269,9 @@
             EXPECT_EQ(0, con.execute(V4V6, IPTABLES_RESTORE_ADD, nullptr));
             EXPECT_EQ(0, con.execute(V4V6, IPTABLES_RESTORE_DEL, nullptr));
         }
-        int64_t timeTaken = s.getTimeAndResetUs();
-        std::cerr << "    Add/del " << iterations << " UID rules via restore: " << timeTaken
-                  << "us (" << (timeTaken / 2 / iterations) << "us per operation)" << std::endl;
+        float timeTaken = s.getTimeAndReset();
+        fprintf(stderr, "    Add/del %d UID rules via restore: %.1fms (%.2fms per operation)\n",
+                iterations, timeTaken, timeTaken / 2 / iterations);
     }
 }
 
diff --git a/server/LocalNetwork.h b/server/LocalNetwork.h
index 7a39a9d..2aa7900 100644
--- a/server/LocalNetwork.h
+++ b/server/LocalNetwork.h
@@ -14,11 +14,13 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef NETD_SERVER_LOCAL_NETWORK_H
+#define NETD_SERVER_LOCAL_NETWORK_H
 
 #include "Network.h"
 
-namespace android::net {
+namespace android {
+namespace net {
 
 class LocalNetwork : public Network {
 public:
@@ -27,8 +29,11 @@
 
 private:
     Type getType() const override;
-    [[nodiscard]] int addInterface(const std::string& interface) override;
-    [[nodiscard]] int removeInterface(const std::string& interface) override;
+    int addInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+    int removeInterface(const std::string& interface) override WARN_UNUSED_RESULT;
 };
 
-}  // namespace android::net
+}  // namespace net
+}  // namespace android
+
+#endif  // NETD_SERVER_LOCAL_NETWORK_H
diff --git a/server/MDnsSdListener.h b/server/MDnsSdListener.h
index 83cf23e..47ddc28 100644
--- a/server/MDnsSdListener.h
+++ b/server/MDnsSdListener.h
@@ -21,7 +21,6 @@
 #include <dns_sd.h>
 #include <sysutils/FrameworkListener.h>
 #include <mutex>
-#include <string>
 
 #include "NetdCommand.h"
 
@@ -80,7 +79,6 @@
         int stopService();
         void run();
         void deallocateServiceRef(DNSServiceRef* ref);
-        std::string threadName() { return std::string("MDnsSdMonitor"); }
 
       private:
         int rescan(); // returns the number of elements in the poll
diff --git a/server/NetdConstants.cpp b/server/NetdConstants.cpp
index 80282b3..40f78f6 100644
--- a/server/NetdConstants.cpp
+++ b/server/NetdConstants.cpp
@@ -29,6 +29,7 @@
 #include <android-base/stringprintf.h>
 #include <cutils/sockets.h>
 #include <log/log.h>
+#include <logwrap/logwrap.h>
 
 #include "Controllers.h"
 #include "NetdConstants.h"
diff --git a/server/NetdConstants.h b/server/NetdConstants.h
index c273e1b..97e75bd 100644
--- a/server/NetdConstants.h
+++ b/server/NetdConstants.h
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef _NETD_CONSTANTS_H
+#define _NETD_CONSTANTS_H
 
 #include <ifaddrs.h>
 #include <netdb.h>
@@ -27,6 +28,9 @@
 #include <netdutils/UidConstants.h>
 #include <private/android_filesystem_config.h>
 
+// Referred from SHA256_DIGEST_LENGTH in boringssl
+constexpr size_t SHA256_SIZE = 32;
+
 enum IptablesTarget { V4, V6, V4V6 };
 
 int execIptablesRestore(IptablesTarget target, const std::string& commands);
@@ -49,11 +53,24 @@
 #define UINT32_HEX_STRLEN sizeof("0x12345678")
 #define IPSEC_IFACE_PREFIX "ipsec"
 
+#define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
+
 const uid_t INVALID_UID = static_cast<uid_t>(-1);
 
 constexpr char TCP_RMEM_PROC_FILE[] = "/proc/sys/net/ipv4/tcp_rmem";
 constexpr char TCP_WMEM_PROC_FILE[] = "/proc/sys/net/ipv4/tcp_wmem";
 
+struct AddrinfoDeleter {
+    void operator()(struct addrinfo* p) const {
+        if (p != nullptr) {
+            freeaddrinfo(p);
+        }
+    }
+};
+
+typedef std::unique_ptr<struct addrinfo, struct AddrinfoDeleter> ScopedAddrinfo;
+
+
 struct IfaddrsDeleter {
     void operator()(struct ifaddrs *p) const {
         if (p != nullptr) {
@@ -64,7 +81,8 @@
 
 typedef std::unique_ptr<struct ifaddrs, struct IfaddrsDeleter> ScopedIfaddrs;
 
-namespace android::net {
+namespace android {
+namespace net {
 
 /**
  * This lock exists to make NetdNativeService RPCs (which come in on multiple Binder threads)
@@ -74,4 +92,7 @@
  */
 extern std::mutex gBigNetdLock;
 
-}  // namespace android::net
+}  // namespace net
+}  // namespace android
+
+#endif  // _NETD_CONSTANTS_H
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index 9aec5e2..65d4727 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -30,6 +30,8 @@
 #include <binder/IServiceManager.h>
 #include <binder/Status.h>
 #include <cutils/properties.h>
+#include <json/value.h>
+#include <json/writer.h>
 #include <log/log.h>
 #include <netdutils/DumpWriter.h>
 #include <utils/Errors.h>
@@ -38,6 +40,7 @@
 #include "BinderUtil.h"
 #include "Controllers.h"
 #include "InterfaceController.h"
+#include "NetdConstants.h"  // SHA256_SIZE
 #include "NetdNativeService.h"
 #include "NetdPermissions.h"
 #include "OemNetdListener.h"
@@ -905,16 +908,11 @@
 }
 
 binder::Status NetdNativeService::tetherStart(const std::vector<std::string>& dhcpRanges) {
-    return tetherStartWithConfiguration(true, dhcpRanges);
-}
-
-binder::Status NetdNativeService::tetherStartWithConfiguration(
-        bool usingLegacyDnsProxy, const std::vector<std::string>& dhcpRanges) {
     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
     if (dhcpRanges.size() % 2 == 1) {
         return statusFromErrcode(-EINVAL);
     }
-    int res = gCtls->tetherCtrl.startTethering(usingLegacyDnsProxy, dhcpRanges);
+    int res = gCtls->tetherCtrl.startTethering(dhcpRanges);
     return statusFromErrcode(res);
 }
 
diff --git a/server/NetdNativeService.h b/server/NetdNativeService.h
index 8f9c40f..68c9886 100644
--- a/server/NetdNativeService.h
+++ b/server/NetdNativeService.h
@@ -121,8 +121,6 @@
     binder::Status tetherGetStats(
             std::vector<android::net::TetherStatsParcel>* tetherStatsVec) override;
     binder::Status tetherStart(const std::vector<std::string>& dhcpRanges) override;
-    binder::Status tetherStartWithConfiguration(
-            bool usingLegacyDnsProxy, const std::vector<std::string>& dhcpRanges) override;
     binder::Status tetherStop() override;
     binder::Status tetherIsEnabled(bool* enabled) override;
     binder::Status tetherInterfaceAdd(const std::string& ifName) override;
diff --git a/server/NetlinkCommands.cpp b/server/NetlinkCommands.cpp
index acefa8e..7af33fe 100644
--- a/server/NetlinkCommands.cpp
+++ b/server/NetlinkCommands.cpp
@@ -65,25 +65,17 @@
     return response.err.error;  // Netlink errors are negative errno.
 }
 
-// Disable optimizations in ASan build.
-// ASan reports an out-of-bounds 32-bit(!) access in the first loop of the function (over iov[]).
-// TODO: verify if this bug is still present.
-#ifdef __clang__
-#if __has_feature(address_sanitizer)
-#define OPTNONE [[clang::optnone]]
-#endif
-#endif
-
-#ifndef OPTNONE
-#define OPTNONE /* nop */
-#endif
-
 // Sends a netlink request and possibly expects an ack.
 // |iov| is an array of struct iovec that contains the netlink message payload.
 // The netlink header is generated by this function based on |action| and |flags|.
 // Returns -errno if there was an error or if the kernel reported an error.
-OPTNONE int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen,
-                               const NetlinkDumpCallback* callback) {
+#ifdef __clang__
+#if __has_feature(address_sanitizer)
+__attribute__((optnone))
+#endif
+#endif
+WARN_UNUSED_RESULT int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen,
+                                          const NetlinkDumpCallback *callback) {
     nlmsghdr nlmsg = {
         .nlmsg_type = action,
         .nlmsg_flags = flags,
@@ -154,8 +146,8 @@
     return 0;
 }
 
-int rtNetlinkFlush(uint16_t getAction, uint16_t deleteAction, const char* what,
-                   const NetlinkDumpFilter& shouldDelete) {
+WARN_UNUSED_RESULT int rtNetlinkFlush(uint16_t getAction, uint16_t deleteAction,
+                                     const char *what, const NetlinkDumpFilter& shouldDelete) {
     // RTM_GETxxx is always RTM_DELxxx + 1, see <linux/rtnetlink.h>.
     if (getAction != deleteAction + 1) {
         ALOGE("Unknown flush type getAction=%d deleteAction=%d", getAction, deleteAction);
@@ -209,7 +201,7 @@
     return ret;
 }
 
-uint32_t getRtmU32Attribute(const nlmsghdr* nlh, int attribute) {
+uint32_t getRtmU32Attribute(const nlmsghdr *nlh, int attribute) {
     uint32_t rta_len = RTM_PAYLOAD(nlh);
     rtmsg *msg = reinterpret_cast<rtmsg *>(NLMSG_DATA(nlh));
     rtattr *rta = reinterpret_cast<rtattr *> RTM_RTA(msg);
diff --git a/server/NetlinkCommands.h b/server/NetlinkCommands.h
index c07194d..ef1ff48 100644
--- a/server/NetlinkCommands.h
+++ b/server/NetlinkCommands.h
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef NETD_SERVER_NETLINK_UTIL_H
+#define NETD_SERVER_NETLINK_UTIL_H
 
 #include <functional>
 #include <linux/netlink.h>
@@ -22,7 +23,8 @@
 
 #include "NetdConstants.h"
 
-namespace android::net {
+namespace android {
+namespace net {
 
 const sockaddr_nl KERNEL_NLADDR = {AF_NETLINK, 0, 0, 0};
 
@@ -42,29 +44,41 @@
 typedef std::function<bool(nlmsghdr *)> NetlinkDumpFilter;
 
 // Opens an RTNetlink socket and connects it to the kernel.
-[[nodiscard]] int openNetlinkSocket(int protocol);
+WARN_UNUSED_RESULT int openNetlinkSocket(int protocol);
 
 // Receives a netlink ACK. Returns 0 if the command succeeded or negative errno if the command
 // failed or receiving the ACK failed.
-[[nodiscard]] int recvNetlinkAck(int sock);
+WARN_UNUSED_RESULT int recvNetlinkAck(int sock);
 
 // Sends a netlink request and possibly expects an ACK. The first element of iov should be null and
 // will be set to the netlink message headerheader. The subsequent elements are the contents of the
 // request.
-[[nodiscard]] int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen,
-                                     const NetlinkDumpCallback* callback);
+
+// Disable optimizations in ASan build.
+// ASan reports an out-of-bounds 32-bit(!) access in the first loop of the
+// function (over iov[]).
+#ifdef __clang__
+#if __has_feature(address_sanitizer)
+__attribute__((optnone))
+#endif
+#endif
+WARN_UNUSED_RESULT int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen,
+                                          const NetlinkDumpCallback *callback);
 
 // Processes a netlink dump, passing every message to the specified |callback|.
-[[nodiscard]] int processNetlinkDump(int sock, const NetlinkDumpCallback& callback);
+WARN_UNUSED_RESULT int processNetlinkDump(int sock, const NetlinkDumpCallback& callback);
 
 // Flushes netlink objects that take an rtmsg structure (FIB rules, routes...). |getAction| and
 // |deleteAction| specify the netlink message types, e.g., RTM_GETRULE and RTM_DELRULE.
 // |shouldDelete| specifies whether a given object should be deleted or not. |what| is a
 // human-readable name for the objects being flushed, e.g. "rules".
-[[nodiscard]] int rtNetlinkFlush(uint16_t getAction, uint16_t deleteAction, const char* what,
-                                 const NetlinkDumpFilter& shouldDelete);
+WARN_UNUSED_RESULT int rtNetlinkFlush(uint16_t getAction, uint16_t deleteAction,
+                                      const char *what, const NetlinkDumpFilter& shouldDelete);
 
 // Returns the value of the specific __u32 attribute, or 0 if the attribute was not present.
 uint32_t getRtmU32Attribute(const nlmsghdr *nlh, int attribute);
 
-}  // namespace android::net
+}  // namespace net
+}  // namespace android
+
+#endif  // NETD_SERVER_NETLINK_UTIL_H
diff --git a/server/Network.h b/server/Network.h
index 8417f34..69af3ff 100644
--- a/server/Network.h
+++ b/server/Network.h
@@ -14,14 +14,16 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef NETD_SERVER_NETWORK_H
+#define NETD_SERVER_NETWORK_H
 
 #include "NetdConstants.h"
 
 #include <set>
 #include <string>
 
-namespace android::net {
+namespace android {
+namespace net {
 
 // A Network represents a collection of interfaces participating as a single administrative unit.
 class Network {
@@ -45,9 +47,9 @@
     const std::set<std::string>& getInterfaces() const;
 
     // These return 0 on success or negative errno on failure.
-    [[nodiscard]] virtual int addInterface(const std::string& interface) = 0;
-    [[nodiscard]] virtual int removeInterface(const std::string& interface) = 0;
-    [[nodiscard]] int clearInterfaces();
+    virtual int addInterface(const std::string& interface) WARN_UNUSED_RESULT = 0;
+    virtual int removeInterface(const std::string& interface) WARN_UNUSED_RESULT = 0;
+    int clearInterfaces() WARN_UNUSED_RESULT;
 
     std::string toString() const;
 
@@ -58,4 +60,7 @@
     std::set<std::string> mInterfaces;
 };
 
-}  // namespace android::net
+}  // namespace net
+}  // namespace android
+
+#endif  // NETD_SERVER_NETWORK_H
diff --git a/server/NetworkController.cpp b/server/NetworkController.cpp
index e490a9f..1e4894f 100644
--- a/server/NetworkController.cpp
+++ b/server/NetworkController.cpp
@@ -47,7 +47,8 @@
 
 using android::netdutils::DumpWriter;
 
-namespace android::net {
+namespace android {
+namespace net {
 
 namespace {
 
@@ -66,21 +67,21 @@
 // setPermissionForNetworks).
 // TODO: use std::mutex and GUARDED_BY instead of manual inspection.
 class NetworkController::DelegateImpl : public PhysicalNetwork::Delegate {
-  public:
+public:
     explicit DelegateImpl(NetworkController* networkController);
     virtual ~DelegateImpl();
 
-    [[nodiscard]] int modifyFallthrough(unsigned vpnNetId, const std::string& physicalInterface,
-                                        Permission permission, bool add);
+    int modifyFallthrough(unsigned vpnNetId, const std::string& physicalInterface,
+                          Permission permission, bool add) WARN_UNUSED_RESULT;
 
-  private:
-    [[nodiscard]] int addFallthrough(const std::string& physicalInterface,
-                                     Permission permission) override;
-    [[nodiscard]] int removeFallthrough(const std::string& physicalInterface,
-                                        Permission permission) override;
+private:
+    int addFallthrough(const std::string& physicalInterface,
+                       Permission permission) override WARN_UNUSED_RESULT;
+    int removeFallthrough(const std::string& physicalInterface,
+                          Permission permission) override WARN_UNUSED_RESULT;
 
-    [[nodiscard]] int modifyFallthrough(const std::string& physicalInterface, Permission permission,
-                                        bool add);
+    int modifyFallthrough(const std::string& physicalInterface, Permission permission,
+                          bool add) WARN_UNUSED_RESULT;
 
     NetworkController* const mNetworkController;
 };
@@ -235,6 +236,11 @@
     return fwmark.intValue;
 }
 
+uint32_t NetworkController::getNetworkForDns(unsigned* netId, uid_t uid) const {
+    ScopedRLock lock(mRWLock);
+    return getNetworkForDnsLocked(netId, uid);
+}
+
 // Returns the NetId that a given UID would use if no network is explicitly selected. Specifically,
 // the VPN that applies to the UID if any; otherwise, the default network.
 unsigned NetworkController::getNetworkForUser(uid_t uid) const {
@@ -844,4 +850,5 @@
     }
 }
 
-}  // namespace android::net
+}  // namespace net
+}  // namespace android
diff --git a/server/NetworkController.h b/server/NetworkController.h
index e0abde0..4a363b3 100644
--- a/server/NetworkController.h
+++ b/server/NetworkController.h
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef NETD_SERVER_NETWORK_CONTROLLER_H
+#define NETD_SERVER_NETWORK_CONTROLLER_H
 
 #include <android-base/thread_annotations.h>
 #include <android/multinetwork.h>
@@ -36,7 +37,8 @@
 
 struct android_net_context;
 
-namespace android::net {
+namespace android {
+namespace net {
 
 typedef std::shared_lock<std::shared_mutex> ScopedRLock;
 typedef std::lock_guard<std::shared_mutex> ScopedWLock;
@@ -91,40 +93,44 @@
     NetworkController();
 
     unsigned getDefaultNetwork() const;
-    [[nodiscard]] int setDefaultNetwork(unsigned netId);
+    int setDefaultNetwork(unsigned netId) WARN_UNUSED_RESULT;
 
+    // Sets |*netId| to an appropriate NetId to use for DNS for the given user. Call with |*netId|
+    // set to a non-NETID_UNSET value if the user already has indicated a preference. Returns the
+    // fwmark value to set on the socket when performing the DNS request.
+    uint32_t getNetworkForDns(unsigned* netId, uid_t uid) const;
     unsigned getNetworkForUser(uid_t uid) const;
     unsigned getNetworkForConnect(uid_t uid) const;
     void getNetworkContext(unsigned netId, uid_t uid, struct android_net_context* netcontext) const;
     unsigned getNetworkForInterface(const char* interface) const;
     bool isVirtualNetwork(unsigned netId) const;
 
-    [[nodiscard]] int createPhysicalNetwork(unsigned netId, Permission permission);
-    [[nodiscard]] int createPhysicalOemNetwork(Permission permission, unsigned* netId);
-    [[nodiscard]] int createVirtualNetwork(unsigned netId, bool secure);
-    [[nodiscard]] int destroyNetwork(unsigned netId);
+    int createPhysicalNetwork(unsigned netId, Permission permission) WARN_UNUSED_RESULT;
+    int createPhysicalOemNetwork(Permission permission, unsigned *netId) WARN_UNUSED_RESULT;
+    int createVirtualNetwork(unsigned netId, bool secure) WARN_UNUSED_RESULT;
+    int destroyNetwork(unsigned netId) WARN_UNUSED_RESULT;
 
-    [[nodiscard]] int addInterfaceToNetwork(unsigned netId, const char* interface);
-    [[nodiscard]] int removeInterfaceFromNetwork(unsigned netId, const char* interface);
+    int addInterfaceToNetwork(unsigned netId, const char* interface) WARN_UNUSED_RESULT;
+    int removeInterfaceFromNetwork(unsigned netId, const char* interface) WARN_UNUSED_RESULT;
 
     Permission getPermissionForUser(uid_t uid) const;
     void setPermissionForUsers(Permission permission, const std::vector<uid_t>& uids);
     int checkUserNetworkAccess(uid_t uid, unsigned netId) const;
-    [[nodiscard]] int setPermissionForNetworks(Permission permission,
-                                               const std::vector<unsigned>& netIds);
+    int setPermissionForNetworks(Permission permission,
+                                 const std::vector<unsigned>& netIds) WARN_UNUSED_RESULT;
 
-    [[nodiscard]] int addUsersToNetwork(unsigned netId, const UidRanges& uidRanges);
-    [[nodiscard]] int removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges);
+    int addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+    int removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) WARN_UNUSED_RESULT;
 
     // |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
     // route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address.
     //
     // Routes are added to tables determined by the interface, so only |interface| is actually used.
     // |netId| is given only to sanity check that the interface has the correct netId.
-    [[nodiscard]] int addRoute(unsigned netId, const char* interface, const char* destination,
-                               const char* nexthop, bool legacy, uid_t uid);
-    [[nodiscard]] int removeRoute(unsigned netId, const char* interface, const char* destination,
-                                  const char* nexthop, bool legacy, uid_t uid);
+    int addRoute(unsigned netId, const char* interface, const char* destination,
+                 const char* nexthop, bool legacy, uid_t uid) WARN_UNUSED_RESULT;
+    int removeRoute(unsigned netId, const char* interface, const char* destination,
+                    const char* nexthop, bool legacy, uid_t uid) WARN_UNUSED_RESULT;
 
     // Notes that the specified address has appeared on the specified interface.
     void addInterfaceAddress(unsigned ifIndex, const char* address);
@@ -141,12 +147,7 @@
   private:
     bool isValidNetworkLocked(unsigned netId) const;
     Network* getNetworkLocked(unsigned netId) const;
-
-    // Sets |*netId| to an appropriate NetId to use for DNS for the given user. Call with |*netId|
-    // set to a non-NETID_UNSET value if the user already has indicated a preference. Returns the
-    // fwmark value to set on the socket when performing the DNS request.
     uint32_t getNetworkForDnsLocked(unsigned* netId, uid_t uid) const;
-
     unsigned getNetworkForUserLocked(uid_t uid) const;
     unsigned getNetworkForConnectLocked(uid_t uid) const;
     unsigned getNetworkForInterfaceLocked(const char* interface) const;
@@ -155,11 +156,11 @@
     VirtualNetwork* getVirtualNetworkForUserLocked(uid_t uid) const;
     Permission getPermissionForUserLocked(uid_t uid) const;
     int checkUserNetworkAccessLocked(uid_t uid, unsigned netId) const;
-    [[nodiscard]] int createPhysicalNetworkLocked(unsigned netId, Permission permission);
+    int createPhysicalNetworkLocked(unsigned netId, Permission permission) WARN_UNUSED_RESULT;
 
-    [[nodiscard]] int modifyRoute(unsigned netId, const char* interface, const char* destination,
-                                  const char* nexthop, bool add, bool legacy, uid_t uid);
-    [[nodiscard]] int modifyFallthroughLocked(unsigned vpnNetId, bool add);
+    int modifyRoute(unsigned netId, const char* interface, const char* destination,
+                    const char* nexthop, bool add, bool legacy, uid_t uid) WARN_UNUSED_RESULT;
+    int modifyFallthroughLocked(unsigned vpnNetId, bool add) WARN_UNUSED_RESULT;
     void updateTcpSocketMonitorPolling();
 
     class DelegateImpl;
@@ -188,4 +189,7 @@
 
 };
 
-}  // namespace android::net
+}  // namespace net
+}  // namespace android
+
+#endif  // NETD_SERVER_NETWORK_CONTROLLER_H
diff --git a/server/PhysicalNetwork.cpp b/server/PhysicalNetwork.cpp
index 56f4ac3..7a1f305 100644
--- a/server/PhysicalNetwork.cpp
+++ b/server/PhysicalNetwork.cpp
@@ -23,12 +23,13 @@
 
 #include "log/log.h"
 
-namespace android::net {
+namespace android {
+namespace net {
 
 namespace {
 
-[[nodiscard]] int addToDefault(unsigned netId, const std::string& interface, Permission permission,
-                               PhysicalNetwork::Delegate* delegate) {
+WARN_UNUSED_RESULT int addToDefault(unsigned netId, const std::string& interface,
+                                    Permission permission, PhysicalNetwork::Delegate* delegate) {
     if (int ret = RouteController::addInterfaceToDefaultNetwork(interface.c_str(), permission)) {
         ALOGE("failed to add interface %s to default netId %u", interface.c_str(), netId);
         return ret;
@@ -39,8 +40,9 @@
     return 0;
 }
 
-[[nodiscard]] int removeFromDefault(unsigned netId, const std::string& interface,
-                                    Permission permission, PhysicalNetwork::Delegate* delegate) {
+WARN_UNUSED_RESULT int removeFromDefault(unsigned netId, const std::string& interface,
+                                         Permission permission,
+                                         PhysicalNetwork::Delegate* delegate) {
     if (int ret = RouteController::removeInterfaceFromDefaultNetwork(interface.c_str(),
                                                                      permission)) {
         ALOGE("failed to remove interface %s from default netId %u", interface.c_str(), netId);
@@ -54,13 +56,15 @@
 
 }  // namespace
 
-PhysicalNetwork::Delegate::~Delegate() {}
+PhysicalNetwork::Delegate::~Delegate() {
+}
 
 PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
         Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
 }
 
-PhysicalNetwork::~PhysicalNetwork() {}
+PhysicalNetwork::~PhysicalNetwork() {
+}
 
 Permission PhysicalNetwork::getPermission() const {
     return mPermission;
@@ -202,4 +206,5 @@
     return 0;
 }
 
-}  // namespace android::net
+}  // namespace net
+}  // namespace android
diff --git a/server/PhysicalNetwork.h b/server/PhysicalNetwork.h
index 0720824..89c9443 100644
--- a/server/PhysicalNetwork.h
+++ b/server/PhysicalNetwork.h
@@ -14,23 +14,25 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef NETD_SERVER_PHYSICAL_NETWORK_H
+#define NETD_SERVER_PHYSICAL_NETWORK_H
 
 #include "Network.h"
 #include "Permission.h"
 
-namespace android::net {
+namespace android {
+namespace net {
 
 class PhysicalNetwork : public Network {
-  public:
+public:
     class Delegate {
-      public:
+    public:
         virtual ~Delegate();
 
-        [[nodiscard]] virtual int addFallthrough(const std::string& physicalInterface,
-                                                 Permission permission) = 0;
-        [[nodiscard]] virtual int removeFallthrough(const std::string& physicalInterface,
-                                                    Permission permission) = 0;
+        virtual int addFallthrough(const std::string& physicalInterface,
+                                   Permission permission) WARN_UNUSED_RESULT = 0;
+        virtual int removeFallthrough(const std::string& physicalInterface,
+                                      Permission permission) WARN_UNUSED_RESULT = 0;
     };
 
     PhysicalNetwork(unsigned netId, Delegate* delegate);
@@ -38,15 +40,15 @@
 
     // These refer to permissions that apps must have in order to use this network.
     Permission getPermission() const;
-    [[nodiscard]] int setPermission(Permission permission);
+    int setPermission(Permission permission) WARN_UNUSED_RESULT;
 
-    [[nodiscard]] int addAsDefault();
-    [[nodiscard]] int removeAsDefault();
+    int addAsDefault() WARN_UNUSED_RESULT;
+    int removeAsDefault() WARN_UNUSED_RESULT;
 
-  private:
+private:
     Type getType() const override;
-    [[nodiscard]] int addInterface(const std::string& interface) override;
-    [[nodiscard]] int removeInterface(const std::string& interface) override;
+    int addInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+    int removeInterface(const std::string& interface) override WARN_UNUSED_RESULT;
     int destroySocketsLackingPermission(Permission permission);
     void invalidateRouteCache(const std::string& interface);
 
@@ -55,4 +57,7 @@
     bool mIsDefault;
 };
 
-}  // namespace android::net
+}  // namespace net
+}  // namespace android
+
+#endif  // NETD_SERVER_PHYSICAL_NETWORK_H
diff --git a/server/ResolvStub.cpp b/server/ResolvStub.cpp
index 2fb6625..5928790 100644
--- a/server/ResolvStub.cpp
+++ b/server/ResolvStub.cpp
@@ -55,7 +55,7 @@
 }
 
 int resolv_stub_init() {
-    void* netdResolvHandle = nullptr;
+    void* netdResolvHandle;
 
     for (const auto& dir : {APEX_LIB64_DIR, APEX_LIB_DIR}) {
         std::string path = std::string(dir) + "/" + LIBNAME;
@@ -64,7 +64,7 @@
             ALOGI("Loaded resolver library from %s", path.c_str());
             break;
         }
-        ALOGW("dlopen(%s) failed: %s", path.c_str(), strerror(errno));
+        ALOGW("dlopen(%s) failed: %s", path.c_str(), dlerror());
     }
 
     if (netdResolvHandle == nullptr) {
@@ -76,7 +76,6 @@
 #define RESOLV_STUB_LOAD_SYMBOL(x) resolvStubInitFunction(netdResolvHandle, STR(x), &RESOLV_STUB.x)
     RESOLV_STUB_LOAD_SYMBOL(resolv_has_nameservers);
     RESOLV_STUB_LOAD_SYMBOL(resolv_init);
-    RESOLV_STUB_LOAD_SYMBOL(resolv_gethostbyaddr_from_cache);
 #undef RESOLV_STUB_LOAD_SYMBOL
 #undef STR
 
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index a62ed6b..6722372 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -38,6 +38,7 @@
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
 #include "log/log.h"
+#include "logwrap/logwrap.h"
 #include "netid_client.h"
 #include "netutils/ifc.h"
 
@@ -45,7 +46,8 @@
 using android::base::WriteStringToFile;
 using android::net::UidRangeParcel;
 
-namespace android::net {
+namespace android {
+namespace net {
 
 auto RouteController::iptablesRestoreCommandFunction = execIptablesRestoreCommand;
 
@@ -102,7 +104,7 @@
 
 // Avoids "non-constant-expression cannot be narrowed from type 'unsigned int' to 'unsigned short'"
 // warnings when using RTA_LENGTH(x) inside static initializers (even when x is already uint16_t).
-static constexpr uint16_t U16_RTA_LENGTH(uint16_t x) {
+constexpr uint16_t U16_RTA_LENGTH(uint16_t x) {
     return RTA_LENGTH(x);
 }
 
@@ -122,12 +124,12 @@
 
 // END CONSTANTS ----------------------------------------------------------------------------------
 
-static const char* actionName(uint16_t action) {
+const char *actionName(uint16_t action) {
     static const char *ops[4] = {"adding", "deleting", "getting", "???"};
     return ops[action % 4];
 }
 
-static const char* familyName(uint8_t family) {
+const char *familyName(uint8_t family) {
     switch (family) {
         case AF_INET: return "IPv4";
         case AF_INET6: return "IPv6";
@@ -137,28 +139,20 @@
 
 // Caller must hold sInterfaceToTableLock.
 uint32_t RouteController::getRouteTableForInterfaceLocked(const char* interface) {
-    // If we already know the routing table for this interface name, use it.
-    // This ensures we can remove rules and routes for an interface that has been removed,
-    // or has been removed and re-added with a different interface index.
-    //
-    // The caller is responsible for ensuring that an interface is never added to a network
-    // until it has been removed from any network it was previously in. This ensures that
-    // if the same interface disconnects and then reconnects with a different interface ID
-    // when the reconnect happens the interface will not be in the map, and the code will
-    // determine the new routing table from the interface ID, below.
-    auto iter = sInterfaceToTable.find(interface);
-    if (iter != sInterfaceToTable.end()) {
-        return iter->second;
-    }
-
     uint32_t index = if_nametoindex(interface);
-    if (index == 0) {
+    if (index) {
+        index += RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX;
+        sInterfaceToTable[interface] = index;
+        return index;
+    }
+    // If the interface goes away if_nametoindex() will return 0 but we still need to know
+    // the index so we can remove the rules and routes.
+    auto iter = sInterfaceToTable.find(interface);
+    if (iter == sInterfaceToTable.end()) {
         ALOGE("cannot find interface %s", interface);
         return RT_TABLE_UNSPEC;
     }
-    index += RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX;
-    sInterfaceToTable[interface] = index;
-    return index;
+    return iter->second;
 }
 
 uint32_t RouteController::getIfIndex(const char* interface) {
@@ -237,10 +231,9 @@
 //   range (inclusive). Otherwise, the rule matches packets from all UIDs.
 //
 // Returns 0 on success or negative errno on failure.
-[[nodiscard]] static int modifyIpRule(uint16_t action, uint32_t priority, uint8_t ruleType,
-                                      uint32_t table, uint32_t fwmark, uint32_t mask,
-                                      const char* iif, const char* oif, uid_t uidStart,
-                                      uid_t uidEnd) {
+WARN_UNUSED_RESULT int modifyIpRule(uint16_t action, uint32_t priority, uint8_t ruleType,
+                                    uint32_t table, uint32_t fwmark, uint32_t mask, const char* iif,
+                                    const char* oif, uid_t uidStart, uid_t uidEnd) {
     // Ensure that if you set a bit in the fwmark, it's not being ignored by the mask.
     if (fwmark & ~mask) {
         ALOGE("mask 0x%x does not select all the bits set in fwmark 0x%x", mask, fwmark);
@@ -324,23 +317,23 @@
     return 0;
 }
 
-[[nodiscard]] static int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table,
-                                      uint32_t fwmark, uint32_t mask, const char* iif,
-                                      const char* oif, uid_t uidStart, uid_t uidEnd) {
+WARN_UNUSED_RESULT int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table,
+                                    uint32_t fwmark, uint32_t mask, const char* iif,
+                                    const char* oif, uid_t uidStart, uid_t uidEnd) {
     return modifyIpRule(action, priority, FR_ACT_TO_TBL, table, fwmark, mask, iif, oif, uidStart,
                         uidEnd);
 }
 
-[[nodiscard]] static int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table,
-                                      uint32_t fwmark, uint32_t mask) {
+WARN_UNUSED_RESULT int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table,
+                                    uint32_t fwmark, uint32_t mask) {
     return modifyIpRule(action, priority, table, fwmark, mask, IIF_NONE, OIF_NONE, INVALID_UID,
                         INVALID_UID);
 }
 
 // Adds or deletes an IPv4 or IPv6 route.
 // Returns 0 on success or negative errno on failure.
-int modifyIpRoute(uint16_t action, uint32_t table, const char* interface, const char* destination,
-                  const char* nexthop) {
+WARN_UNUSED_RESULT int modifyIpRoute(uint16_t action, uint32_t table, const char* interface,
+                                     const char* destination, const char* nexthop) {
     // At least the destination must be non-null.
     if (!destination) {
         ALOGE("null destination");
@@ -399,11 +392,11 @@
 
     // Assemble a rtmsg and put it in an array of iovec structures.
     rtmsg route = {
-            .rtm_family = family,
-            .rtm_dst_len = prefixLength,
-            .rtm_protocol = RTPROT_STATIC,
-            .rtm_scope = static_cast<uint8_t>(nexthop ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK),
-            .rtm_type = type,
+        .rtm_protocol = RTPROT_STATIC,
+        .rtm_type = type,
+        .rtm_family = family,
+        .rtm_dst_len = prefixLength,
+        .rtm_scope = static_cast<uint8_t>(nexthop ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK),
     };
 
     rtattr rtaDst     = { U16_RTA_LENGTH(rawLength), RTA_DST };
@@ -447,8 +440,8 @@
 //   replies, SYN-ACKs, etc).
 // + Mark sockets that accept connections from this interface so that the connection stays on the
 //   same interface.
-int modifyIncomingPacketMark(unsigned netId, const char* interface, Permission permission,
-                             bool add) {
+WARN_UNUSED_RESULT int modifyIncomingPacketMark(unsigned netId, const char* interface,
+                                                Permission permission, bool add) {
     Fwmark fwmark;
 
     fwmark.netId = netId;
@@ -473,7 +466,7 @@
 //
 // When a VPN is in effect, packets from the local network to upstream networks are forwarded into
 // the VPN's tunnel interface. When the VPN forwards the responses, they emerge out of the tunnel.
-[[nodiscard]] static int modifyVpnOutputToLocalRule(const char* vpnInterface, bool add) {
+WARN_UNUSED_RESULT int modifyVpnOutputToLocalRule(const char* vpnInterface, bool add) {
     return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_VPN_OUTPUT_TO_LOCAL,
                         ROUTE_TABLE_LOCAL_NETWORK, MARK_UNSET, MARK_UNSET, vpnInterface, OIF_NONE,
                         INVALID_UID, INVALID_UID);
@@ -484,8 +477,8 @@
 // Notice that this rule doesn't use the netId. I.e., no matter what netId the user's socket may
 // have, if they are subject to this VPN, their traffic has to go through it. Allows the traffic to
 // bypass the VPN if the protectedFromVpn bit is set.
-[[nodiscard]] static int modifyVpnUidRangeRule(uint32_t table, uid_t uidStart, uid_t uidEnd,
-                                               bool secure, bool add) {
+WARN_UNUSED_RESULT int modifyVpnUidRangeRule(uint32_t table, uid_t uidStart, uid_t uidEnd,
+                                             bool secure, bool add) {
     Fwmark fwmark;
     Fwmark mask;
 
@@ -512,8 +505,8 @@
 //
 // This is needed for DnsProxyListener to correctly resolve a request for a user who is in the
 // target set, but where the DnsProxyListener itself is not.
-[[nodiscard]] static int modifyVpnSystemPermissionRule(unsigned netId, uint32_t table, bool secure,
-                                                       bool add) {
+WARN_UNUSED_RESULT int modifyVpnSystemPermissionRule(unsigned netId, uint32_t table, bool secure,
+                                                     bool add) {
     Fwmark fwmark;
     Fwmark mask;
 
@@ -536,9 +529,9 @@
 // Even though we check permissions at the time we set a netId into the fwmark of a socket, we need
 // to check it again in the rules here, because a network's permissions may have been updated via
 // modifyNetworkPermission().
-[[nodiscard]] static int modifyExplicitNetworkRule(unsigned netId, uint32_t table,
-                                                   Permission permission, uid_t uidStart,
-                                                   uid_t uidEnd, bool add) {
+WARN_UNUSED_RESULT int modifyExplicitNetworkRule(unsigned netId, uint32_t table,
+                                                 Permission permission, uid_t uidStart,
+                                                 uid_t uidEnd, bool add) {
     Fwmark fwmark;
     Fwmark mask;
 
@@ -559,9 +552,9 @@
 //
 // Supports apps that use SO_BINDTODEVICE or IP_PKTINFO options and the kernel that already knows
 // the outgoing interface (typically for link-local communications).
-[[nodiscard]] static int modifyOutputInterfaceRules(const char* interface, uint32_t table,
-                                                    Permission permission, uid_t uidStart,
-                                                    uid_t uidEnd, bool add) {
+WARN_UNUSED_RESULT int modifyOutputInterfaceRules(const char* interface, uint32_t table,
+                                                  Permission permission, uid_t uidStart,
+                                                  uid_t uidEnd, bool add) {
     Fwmark fwmark;
     Fwmark mask;
 
@@ -588,7 +581,7 @@
 // This is for sockets that have not explicitly requested a particular network, but have been
 // bound to one when they called connect(). This ensures that sockets connected on a particular
 // network stay on that network even if the default network changes.
-[[nodiscard]] static int modifyImplicitNetworkRule(unsigned netId, uint32_t table, bool add) {
+WARN_UNUSED_RESULT int modifyImplicitNetworkRule(unsigned netId, uint32_t table, bool add) {
     Fwmark fwmark;
     Fwmark mask;
 
@@ -610,9 +603,9 @@
 //
 // If a packet with a VPN's netId doesn't find a route in the VPN's routing table, it's allowed to
 // go over the default network, provided it has the permissions required by the default network.
-int RouteController::modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
-                                              const char* physicalInterface,
-                                              Permission permission) {
+WARN_UNUSED_RESULT int RouteController::modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
+                                                                 const char* physicalInterface,
+                                                                 Permission permission) {
     uint32_t table = getRouteTableForInterface(physicalInterface);
     if (table == RT_TABLE_UNSPEC) {
         return -ESRCH;
@@ -632,7 +625,7 @@
 }
 
 // Add rules to allow legacy routes added through the requestRouteToHost() API.
-[[nodiscard]] static int addLegacyRouteRules() {
+WARN_UNUSED_RESULT int addLegacyRouteRules() {
     Fwmark fwmark;
     Fwmark mask;
 
@@ -658,7 +651,7 @@
 }
 
 // Add rules to lookup the local network when specified explicitly or otherwise.
-[[nodiscard]] static int addLocalNetworkRules(unsigned localNetId) {
+WARN_UNUSED_RESULT int addLocalNetworkRules(unsigned localNetId) {
     if (int ret = modifyExplicitNetworkRule(localNetId, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE,
                                             INVALID_UID, INVALID_UID, ACTION_ADD)) {
         return ret;
@@ -712,12 +705,12 @@
 // relying on the kernel-default "from all lookup main" rule at priority 32766 is not intended
 // behaviour. We do flush the kernel-default rules at startup, but having an explicit unreachable
 // rule will hopefully make things even clearer.
-[[nodiscard]] static int addUnreachableRule() {
+WARN_UNUSED_RESULT int addUnreachableRule() {
     return modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_UNREACHABLE, FR_ACT_UNREACHABLE, RT_TABLE_UNSPEC,
                         MARK_UNSET, MARK_UNSET, IIF_NONE, OIF_NONE, INVALID_UID, INVALID_UID);
 }
 
-[[nodiscard]] static int modifyLocalNetwork(unsigned netId, const char* interface, bool add) {
+WARN_UNUSED_RESULT int modifyLocalNetwork(unsigned netId, const char* interface, bool add) {
     if (int ret = modifyIncomingPacketMark(netId, interface, PERMISSION_NONE, add)) {
         return ret;
     }
@@ -726,8 +719,8 @@
 }
 
 /* static */
-int RouteController::modifyPhysicalNetwork(unsigned netId, const char* interface,
-                                           Permission permission, bool add) {
+WARN_UNUSED_RESULT int RouteController::modifyPhysicalNetwork(unsigned netId, const char* interface,
+                                                              Permission permission, bool add) {
     uint32_t table = getRouteTableForInterface(interface);
     if (table == RT_TABLE_UNSPEC) {
         return -ESRCH;
@@ -771,7 +764,7 @@
     return 0;
 }
 
-[[nodiscard]] static int modifyRejectNonSecureNetworkRule(const UidRanges& uidRanges, bool add) {
+WARN_UNUSED_RESULT int modifyRejectNonSecureNetworkRule(const UidRanges& uidRanges, bool add) {
     Fwmark fwmark;
     Fwmark mask;
     fwmark.protectedFromVpn = false;
@@ -788,9 +781,10 @@
     return 0;
 }
 
-int RouteController::modifyVirtualNetwork(unsigned netId, const char* interface,
-                                          const UidRanges& uidRanges, bool secure, bool add,
-                                          bool modifyNonUidBasedRules) {
+WARN_UNUSED_RESULT int RouteController::modifyVirtualNetwork(unsigned netId, const char* interface,
+                                                             const UidRanges& uidRanges,
+                                                             bool secure, bool add,
+                                                             bool modifyNonUidBasedRules) {
     uint32_t table = getRouteTableForInterface(interface);
     if (table == RT_TABLE_UNSPEC) {
         return -ESRCH;
@@ -826,8 +820,8 @@
     return 0;
 }
 
-int RouteController::modifyDefaultNetwork(uint16_t action, const char* interface,
-                                          Permission permission) {
+WARN_UNUSED_RESULT int RouteController::modifyDefaultNetwork(uint16_t action, const char* interface,
+                                                             Permission permission) {
     uint32_t table = getRouteTableForInterface(interface);
     if (table == RT_TABLE_UNSPEC) {
         return -ESRCH;
@@ -846,8 +840,9 @@
                         mask.intValue, IIF_LOOPBACK, OIF_NONE, INVALID_UID, INVALID_UID);
 }
 
-int RouteController::modifyTetheredNetwork(uint16_t action, const char* inputInterface,
-                                           const char* outputInterface) {
+WARN_UNUSED_RESULT int RouteController::modifyTetheredNetwork(uint16_t action,
+                                                              const char* inputInterface,
+                                                              const char* outputInterface) {
     uint32_t table = getRouteTableForInterface(outputInterface);
     if (table == RT_TABLE_UNSPEC) {
         return -ESRCH;
@@ -859,8 +854,9 @@
 
 // Adds or removes an IPv4 or IPv6 route to the specified table.
 // Returns 0 on success or negative errno on failure.
-int RouteController::modifyRoute(uint16_t action, const char* interface, const char* destination,
-                                 const char* nexthop, TableType tableType) {
+WARN_UNUSED_RESULT int RouteController::modifyRoute(uint16_t action, const char* interface,
+                                                    const char* destination, const char* nexthop,
+                                                    TableType tableType) {
     uint32_t table;
     switch (tableType) {
         case RouteController::INTERFACE: {
@@ -893,7 +889,7 @@
     return 0;
 }
 
-[[nodiscard]] static int clearTetheringRules(const char* inputInterface) {
+WARN_UNUSED_RESULT int clearTetheringRules(const char* inputInterface) {
     int ret = 0;
     while (ret == 0) {
         ret = modifyIpRule(RTM_DELRULE, RULE_PRIORITY_TETHERING, 0, MARK_UNSET, MARK_UNSET,
@@ -915,7 +911,7 @@
     return getRtmU32Attribute(nlh, RTA_TABLE);
 }
 
-[[nodiscard]] static int flushRules() {
+WARN_UNUSED_RESULT int flushRules() {
     NetlinkDumpFilter shouldDelete = [] (nlmsghdr *nlh) {
         // Don't touch rules at priority 0 because by default they are used for local input.
         return getRulePriority(nlh) != 0;
@@ -923,7 +919,7 @@
     return rtNetlinkFlush(RTM_GETRULE, RTM_DELRULE, "rules", shouldDelete);
 }
 
-int RouteController::flushRoutes(uint32_t table) {
+WARN_UNUSED_RESULT int RouteController::flushRoutes(uint32_t table) {
     NetlinkDumpFilter shouldDelete = [table] (nlmsghdr *nlh) {
         return getRouteTable(nlh) == table;
     };
@@ -932,7 +928,7 @@
 }
 
 // Returns 0 on success or negative errno on failure.
-int RouteController::flushRoutes(const char* interface) {
+WARN_UNUSED_RESULT int RouteController::flushRoutes(const char* interface) {
     std::lock_guard lock(sInterfaceToTableLock);
 
     uint32_t table = getRouteTableForInterfaceLocked(interface);
@@ -1098,4 +1094,6 @@
 std::mutex RouteController::sInterfaceToTableLock;
 std::map<std::string, uint32_t> RouteController::sInterfaceToTable;
 
-}  // namespace android::net
+
+}  // namespace net
+}  // namespace android
diff --git a/server/RouteController.h b/server/RouteController.h
index e36320f..d40288b 100644
--- a/server/RouteController.h
+++ b/server/RouteController.h
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef NETD_SERVER_ROUTE_CONTROLLER_H
+#define NETD_SERVER_ROUTE_CONTROLLER_H
 
-#include "NetdConstants.h"  // IptablesTarget
+#include "NetdConstants.h"
 #include "Permission.h"
 
 #include <android-base/thread_annotations.h>
@@ -26,7 +27,8 @@
 #include <map>
 #include <mutex>
 
-namespace android::net {
+namespace android {
+namespace net {
 
 class UidRanges;
 
@@ -44,7 +46,7 @@
 
     static const char* const LOCAL_MANGLE_INPUT;
 
-    [[nodiscard]] static int Init(unsigned localNetId);
+    static int Init(unsigned localNetId) WARN_UNUSED_RESULT;
 
     // Returns an ifindex given the interface name, by looking up in sInterfaceToTable.
     // This is currently only used by NetworkController::addInterfaceToNetwork
@@ -55,56 +57,55 @@
     // used to add them.
     static uint32_t getIfIndex(const char* interface) EXCLUDES(sInterfaceToTableLock);
 
-    [[nodiscard]] static int addInterfaceToLocalNetwork(unsigned netId, const char* interface);
-    [[nodiscard]] static int removeInterfaceFromLocalNetwork(unsigned netId, const char* interface);
+    static int addInterfaceToLocalNetwork(unsigned netId, const char* interface) WARN_UNUSED_RESULT;
+    static int removeInterfaceFromLocalNetwork(unsigned netId,
+                                               const char* interface) WARN_UNUSED_RESULT;
 
-    [[nodiscard]] static int addInterfaceToPhysicalNetwork(unsigned netId, const char* interface,
-                                                           Permission permission);
-    [[nodiscard]] static int removeInterfaceFromPhysicalNetwork(unsigned netId,
-                                                                const char* interface,
-                                                                Permission permission);
+    static int addInterfaceToPhysicalNetwork(unsigned netId, const char* interface,
+                                             Permission permission) WARN_UNUSED_RESULT;
+    static int removeInterfaceFromPhysicalNetwork(unsigned netId, const char* interface,
+                                                  Permission permission) WARN_UNUSED_RESULT;
 
-    [[nodiscard]] static int addInterfaceToVirtualNetwork(unsigned netId, const char* interface,
-                                                          bool secure, const UidRanges& uidRanges);
-    [[nodiscard]] static int removeInterfaceFromVirtualNetwork(unsigned netId,
-                                                               const char* interface, bool secure,
-                                                               const UidRanges& uidRanges);
+    static int addInterfaceToVirtualNetwork(unsigned netId, const char* interface, bool secure,
+                                            const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+    static int removeInterfaceFromVirtualNetwork(unsigned netId, const char* interface, bool secure,
+                                                 const UidRanges& uidRanges) WARN_UNUSED_RESULT;
 
-    [[nodiscard]] static int modifyPhysicalNetworkPermission(unsigned netId, const char* interface,
-                                                             Permission oldPermission,
-                                                             Permission newPermission);
+    static int modifyPhysicalNetworkPermission(unsigned netId, const char* interface,
+                                               Permission oldPermission,
+                                               Permission newPermission) WARN_UNUSED_RESULT;
 
-    [[nodiscard]] static int addUsersToVirtualNetwork(unsigned netId, const char* interface,
-                                                      bool secure, const UidRanges& uidRanges);
-    [[nodiscard]] static int removeUsersFromVirtualNetwork(unsigned netId, const char* interface,
-                                                           bool secure, const UidRanges& uidRanges);
+    static int addUsersToVirtualNetwork(unsigned netId, const char* interface, bool secure,
+                                        const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+    static int removeUsersFromVirtualNetwork(unsigned netId, const char* interface, bool secure,
+                                             const UidRanges& uidRanges) WARN_UNUSED_RESULT;
 
-    [[nodiscard]] static int addUsersToRejectNonSecureNetworkRule(const UidRanges& uidRanges);
-    [[nodiscard]] static int removeUsersFromRejectNonSecureNetworkRule(const UidRanges& uidRanges);
+    static int addUsersToRejectNonSecureNetworkRule(const UidRanges& uidRanges)
+                                                    WARN_UNUSED_RESULT;
+    static int removeUsersFromRejectNonSecureNetworkRule(const UidRanges& uidRanges)
+                                                         WARN_UNUSED_RESULT;
 
-    [[nodiscard]] static int addInterfaceToDefaultNetwork(const char* interface,
-                                                          Permission permission);
-    [[nodiscard]] static int removeInterfaceFromDefaultNetwork(const char* interface,
-                                                               Permission permission);
+    static int addInterfaceToDefaultNetwork(const char* interface,
+                                            Permission permission) WARN_UNUSED_RESULT;
+    static int removeInterfaceFromDefaultNetwork(const char* interface,
+                                                 Permission permission) WARN_UNUSED_RESULT;
 
     // |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
     // route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address.
-    [[nodiscard]] static int addRoute(const char* interface, const char* destination,
-                                      const char* nexthop, TableType tableType);
-    [[nodiscard]] static int removeRoute(const char* interface, const char* destination,
-                                         const char* nexthop, TableType tableType);
+    static int addRoute(const char* interface, const char* destination, const char* nexthop,
+                        TableType tableType) WARN_UNUSED_RESULT;
+    static int removeRoute(const char* interface, const char* destination, const char* nexthop,
+                           TableType tableType) WARN_UNUSED_RESULT;
 
-    [[nodiscard]] static int enableTethering(const char* inputInterface,
-                                             const char* outputInterface);
-    [[nodiscard]] static int disableTethering(const char* inputInterface,
-                                              const char* outputInterface);
+    static int enableTethering(const char* inputInterface,
+                               const char* outputInterface) WARN_UNUSED_RESULT;
+    static int disableTethering(const char* inputInterface,
+                                const char* outputInterface) WARN_UNUSED_RESULT;
 
-    [[nodiscard]] static int addVirtualNetworkFallthrough(unsigned vpnNetId,
-                                                          const char* physicalInterface,
-                                                          Permission permission);
-    [[nodiscard]] static int removeVirtualNetworkFallthrough(unsigned vpnNetId,
-                                                             const char* physicalInterface,
-                                                             Permission permission);
+    static int addVirtualNetworkFallthrough(unsigned vpnNetId, const char* physicalInterface,
+                                            Permission permission) WARN_UNUSED_RESULT;
+    static int removeVirtualNetworkFallthrough(unsigned vpnNetId, const char* physicalInterface,
+                                               Permission permission) WARN_UNUSED_RESULT;
 
     // For testing.
     static int (*iptablesRestoreCommandFunction)(IptablesTarget, const std::string&,
@@ -117,9 +118,9 @@
     static std::map<std::string, uint32_t> sInterfaceToTable GUARDED_BY(sInterfaceToTableLock);
 
     static int configureDummyNetwork();
-    [[nodiscard]] static int flushRoutes(const char* interface) EXCLUDES(sInterfaceToTableLock);
-    [[nodiscard]] static int flushRoutes(uint32_t table);
-    static uint32_t getRouteTableForInterfaceLocked(const char* interface)
+    static int flushRoutes(const char* interface) EXCLUDES(sInterfaceToTableLock);
+    static int flushRoutes(uint32_t table);
+    static uint32_t getRouteTableForInterfaceLocked(const char *interface)
             REQUIRES(sInterfaceToTableLock);
     static uint32_t getRouteTableForInterface(const char *interface) EXCLUDES(sInterfaceToTableLock);
     static int modifyDefaultNetwork(uint16_t action, const char* interface, Permission permission);
@@ -140,10 +141,14 @@
 // Public because they are called by by RouteControllerTest.cpp.
 // TODO: come up with a scheme of unit testing this code that does not rely on making all its
 // functions public.
-[[nodiscard]] int modifyIpRoute(uint16_t action, uint32_t table, const char* interface,
-                                const char* destination, const char* nexthop);
+int modifyIpRoute(uint16_t action, uint32_t table, const char* interface, const char* destination,
+                  const char* nexthop) WARN_UNUSED_RESULT;
+int flushRoutes(uint32_t table) WARN_UNUSED_RESULT;
 uint32_t getRulePriority(const nlmsghdr *nlh);
-[[nodiscard]] int modifyIncomingPacketMark(unsigned netId, const char* interface,
-                                           Permission permission, bool add);
+WARN_UNUSED_RESULT int modifyIncomingPacketMark(unsigned netId, const char* interface,
+                                                Permission permission, bool add);
 
-}  // namespace android::net
+}  // namespace net
+}  // namespace android
+
+#endif  // NETD_SERVER_ROUTE_CONTROLLER_H
diff --git a/server/SockDiag.cpp b/server/SockDiag.cpp
index 3e1f384..33c523a 100644
--- a/server/SockDiag.cpp
+++ b/server/SockDiag.cpp
@@ -14,29 +14,27 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "Netd"
-
-#include "SockDiag.h"
-
 #include <errno.h>
-#include <linux/inet_diag.h>
-#include <linux/netlink.h>
-#include <linux/sock_diag.h>
 #include <netdb.h>
+#include <string.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
-#include <string.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
 
-#include <cinttypes>
+#include <linux/netlink.h>
+#include <linux/sock_diag.h>
+#include <linux/inet_diag.h>
+
+#define LOG_TAG "Netd"
 
 #include <android-base/strings.h>
 #include <log/log.h>
-#include <netdutils/InternetAddresses.h>
 #include <netdutils/Stopwatch.h>
 
+#include "NetdConstants.h"
 #include "Permission.h"
+#include "SockDiag.h"
 
 #ifndef SOCK_DESTROY
 #define SOCK_DESTROY 21
@@ -46,7 +44,6 @@
 
 namespace android {
 
-using netdutils::ScopedAddrinfo;
 using netdutils::Stopwatch;
 
 namespace net {
@@ -326,8 +323,7 @@
     }
 
     if (mSocketsDestroyed > 0) {
-        ALOGI("Destroyed %d sockets on %s in %" PRId64 "us", mSocketsDestroyed, addrstr,
-              s.timeTakenUs());
+        ALOGI("Destroyed %d sockets on %s in %.1f ms", mSocketsDestroyed, addrstr, s.timeTaken());
     }
 
     return mSocketsDestroyed;
@@ -401,7 +397,7 @@
     }
 
     if (mSocketsDestroyed > 0) {
-        ALOGI("Destroyed %d sockets for UID in %" PRId64 "us", mSocketsDestroyed, s.timeTakenUs());
+        ALOGI("Destroyed %d sockets for UID in %.1f ms", mSocketsDestroyed, s.timeTaken());
     }
 
     return 0;
@@ -428,9 +424,9 @@
     }
 
     if (mSocketsDestroyed > 0) {
-        ALOGI("Destroyed %d sockets for %s skip={%s} in %" PRId64 "us", mSocketsDestroyed,
-              uidRanges.toString().c_str(), android::base::Join(skipUids, " ").c_str(),
-              s.timeTakenUs());
+        ALOGI("Destroyed %d sockets for %s skip={%s} in %.1f ms",
+              mSocketsDestroyed, uidRanges.toString().c_str(),
+              android::base::Join(skipUids, " ").c_str(), s.timeTaken());
     }
 
     return 0;
@@ -499,8 +495,8 @@
     };
 
     struct nlattr nla = {
-            .nla_len = sizeof(struct nlattr) + bytecodelen,
-            .nla_type = INET_DIAG_REQ_BYTECODE,
+        .nla_type = INET_DIAG_REQ_BYTECODE,
+        .nla_len = sizeof(struct nlattr) + bytecodelen,
     };
 
     iovec iov[] = {
@@ -521,8 +517,8 @@
     }
 
     if (mSocketsDestroyed > 0) {
-        ALOGI("Destroyed %d sockets for netId %d permission=%d in %" PRId64 "us", mSocketsDestroyed,
-              netId, permission, s.timeTakenUs());
+        ALOGI("Destroyed %d sockets for netId %d permission=%d in %.1f ms",
+              mSocketsDestroyed, netId, permission, s.timeTaken());
     }
 
     return 0;
diff --git a/server/SockDiagTest.cpp b/server/SockDiagTest.cpp
index b79471a..312f2c8 100644
--- a/server/SockDiagTest.cpp
+++ b/server/SockDiagTest.cpp
@@ -199,15 +199,14 @@
 
 inet_diag_msg makeDiagMessage(__u8 family,  const sockaddr *src, const sockaddr *dst) {
     inet_diag_msg msg = {
-            .idiag_family = family,
-            .idiag_state = TCP_ESTABLISHED,
-            .id =
-                    {
-                            .idiag_sport = 1234,
-                            .idiag_dport = 4321,
-                    },
-            .idiag_uid = AID_APP + 123,
-            .idiag_inode = 123456789,
+        .idiag_family = family,
+        .idiag_state = TCP_ESTABLISHED,
+        .idiag_uid = AID_APP + 123,
+        .idiag_inode = 123456789,
+        .id = {
+            .idiag_sport = 1234,
+            .idiag_dport = 4321,
+        }
     };
     EXPECT_TRUE(fillDiagAddr(msg.id.idiag_src, src));
     EXPECT_TRUE(fillDiagAddr(msg.id.idiag_dst, dst));
diff --git a/server/TetherController.cpp b/server/TetherController.cpp
index c987d63..0c5b6bf 100644
--- a/server/TetherController.cpp
+++ b/server/TetherController.cpp
@@ -36,7 +36,6 @@
 #include <vector>
 
 #define LOG_TAG "TetherController"
-#include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
@@ -117,6 +116,22 @@
     return !strcmp(BP_TOOLS_MODE, bootmode);
 }
 
+int setPosixSpawnFileActionsAddDup2(posix_spawn_file_actions_t* fa, int fd, int new_fd) {
+    int res = posix_spawn_file_actions_init(fa);
+    if (res) {
+        return res;
+    }
+    return posix_spawn_file_actions_adddup2(fa, fd, new_fd);
+}
+
+int setPosixSpawnAttrFlags(posix_spawnattr_t* attr, short flags) {
+    int res = posix_spawnattr_init(attr);
+    if (res) {
+        return res;
+    }
+    return posix_spawnattr_setflags(attr, flags);
+}
+
 }  // namespace
 
 auto TetherController::iptablesRestoreFunction = execIptablesRestoreWithOutput;
@@ -190,15 +205,8 @@
     return mForwardingRequests;
 }
 
-int TetherController::startTethering(bool usingLegacyDnsProxy, int num_addrs, char** dhcp_ranges) {
-    if (!usingLegacyDnsProxy && num_addrs == 0) {
-        // Both DHCP and DnsProxy are disabled, we don't need to start dnsmasq
-        configureForTethering(true);
-        mIsTetheringStarted = true;
-        return 0;
-    }
-
-    if (mIsTetheringStarted) {
+int TetherController::startTethering(int num_addrs, char **dhcp_ranges) {
+    if (mDaemonPid != 0) {
         ALOGE("Tethering already started");
         errno = EBUSY;
         return -errno;
@@ -237,11 +245,8 @@
             kDnsmasqUsername,
     };
 
-    if (!usingLegacyDnsProxy) {
-        argVector.push_back("--port=0");
-    }
-
-    // DHCP server will be disabled if num_addrs == 0 and no --dhcp-range is passed.
+    // DHCP server will be disabled if num_addrs == 0 and no --dhcp-range is
+    // passed.
     for (int addrIndex = 0; addrIndex < num_addrs; addrIndex += 2) {
         argVector.push_back(StringPrintf("--dhcp-range=%s,%s,1h", dhcp_ranges[addrIndex],
                                          dhcp_ranges[addrIndex + 1]));
@@ -262,33 +267,23 @@
     // dup2 creates fd without CLOEXEC, dnsmasq will receive commands through the
     // duplicated fd.
     posix_spawn_file_actions_t fa;
-    int res = posix_spawn_file_actions_init(&fa);
+    int res = setPosixSpawnFileActionsAddDup2(&fa, pipeRead.get(), STDIN_FILENO);
     if (res) {
-        ALOGE("posix_spawn_file_actions_init failed (%s)", strerror(res));
-        return -res;
-    }
-    const android::base::ScopeGuard faGuard = [&] { posix_spawn_file_actions_destroy(&fa); };
-    res = posix_spawn_file_actions_adddup2(&fa, pipeRead.get(), STDIN_FILENO);
-    if (res) {
-        ALOGE("posix_spawn_file_actions_adddup2 failed (%s)", strerror(res));
+        ALOGE("posix_spawn set fa failed (%s)", strerror(res));
         return -res;
     }
 
     posix_spawnattr_t attr;
-    res = posix_spawnattr_init(&attr);
+    res = setPosixSpawnAttrFlags(&attr, POSIX_SPAWN_USEVFORK);
     if (res) {
-        ALOGE("posix_spawnattr_init failed (%s)", strerror(res));
-        return -res;
-    }
-    const android::base::ScopeGuard attrGuard = [&] { posix_spawnattr_destroy(&attr); };
-    res = posix_spawnattr_setflags(&attr, POSIX_SPAWN_USEVFORK);
-    if (res) {
-        ALOGE("posix_spawnattr_setflags failed (%s)", strerror(res));
+        ALOGE("posix_spawn set attr flag failed (%s)", strerror(res));
         return -res;
     }
 
     pid_t pid;
     res = posix_spawn(&pid, args[0], &fa, &attr, &args[0], nullptr);
+    posix_spawnattr_destroy(&attr);
+    posix_spawn_file_actions_destroy(&fa);
     if (res) {
         ALOGE("posix_spawn failed (%s)", strerror(res));
         return -res;
@@ -296,7 +291,6 @@
     mDaemonPid = pid;
     mDaemonFd = pipeWrite.release();
     configureForTethering(true);
-    mIsTetheringStarted = true;
     applyDnsInterfaces();
     ALOGD("Tethering services running");
 
@@ -312,8 +306,7 @@
     return addrsCstrVec;
 }
 
-int TetherController::startTethering(bool usingLegacyDnsProxy,
-                                     const std::vector<std::string>& dhcpRanges) {
+int TetherController::startTethering(const std::vector<std::string>& dhcpRanges) {
     struct in_addr v4_addr;
     for (const auto& dhcpRange : dhcpRanges) {
         if (!inet_aton(dhcpRange.c_str(), &v4_addr)) {
@@ -321,20 +314,14 @@
         }
     }
     auto dhcp_ranges = toCstrVec(dhcpRanges);
-    return startTethering(usingLegacyDnsProxy, dhcp_ranges.size(), dhcp_ranges.data());
+    return startTethering(dhcp_ranges.size(), dhcp_ranges.data());
 }
 
 int TetherController::stopTethering() {
     configureForTethering(false);
 
-    if (!mIsTetheringStarted) {
-        ALOGE("Tethering already stopped");
-        return 0;
-    }
-
-    mIsTetheringStarted = false;
-    // dnsmasq is not started
     if (mDaemonPid == 0) {
+        ALOGE("Tethering already stopped");
         return 0;
     }
 
@@ -351,7 +338,7 @@
 }
 
 bool TetherController::isTetheringStarted() {
-    return mIsTetheringStarted;
+    return (mDaemonPid == 0 ? false : true);
 }
 
 // dnsmasq can't parse commands larger than this due to the fixed-size buffer
diff --git a/server/TetherController.h b/server/TetherController.h
index 7f8ba06..0a04874 100644
--- a/server/TetherController.h
+++ b/server/TetherController.h
@@ -43,8 +43,6 @@
     // some point since the controller was initialized.
     std::multimap<std::string, ForwardingDownstream> mFwdIfaces;
 
-    bool mIsTetheringStarted = false;
-
     // NetId to use for forwarded DNS queries. This may not be the default
     // network, e.g., in the case where we are tethering to a DUN APN.
     unsigned               mDnsNetId = 0;
@@ -75,9 +73,8 @@
     bool disableForwarding(const char* requester);
     const std::set<std::string>& getIpfwdRequesterList() const;
 
-    //TODO: Clean up the overload function
-    int startTethering(bool isLegacyDnsProxy, int num_addrs, char** dhcp_ranges);
-    int startTethering(bool isLegacyDnsProxy, const std::vector<std::string>& dhcpRanges);
+    int startTethering(int num_addrs, char **dhcp_ranges);
+    int startTethering(const std::vector<std::string>& dhcpRanges);
     int stopTethering();
     bool isTetheringStarted();
 
diff --git a/server/TrafficController.cpp b/server/TrafficController.cpp
index 86f1f53..8dceb5b 100644
--- a/server/TrafficController.cpp
+++ b/server/TrafficController.cpp
@@ -38,6 +38,7 @@
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
+#include <logwrap/logwrap.h>
 #include <netdutils/StatusOr.h>
 
 #include <netdutils/Misc.h>
@@ -77,7 +78,6 @@
 // Otherwise, apps would be able to avoid data usage accounting entirely by filling up the
 // map with tagged traffic entries.
 constexpr int TOTAL_UID_STATS_ENTRIES_LIMIT = STATS_MAP_SIZE * 0.9;
-constexpr mode_t S_NONE = 0;
 
 static_assert(BPF_PERMISSION_INTERNET == INetd::PERMISSION_INTERNET,
               "Mismatch between BPF and AIDL permissions: PERMISSION_INTERNET");
@@ -116,7 +116,7 @@
             mPrivilegedUser.find(appId) != mPrivilegedUser.end());
 }
 
-const std::string UidPermissionTypeToString(int permission) {
+const std::string UidPermissionTypeToString(uint8_t permission) {
     if (permission == INetd::PERMISSION_NONE) {
         return "PERMISSION_NONE";
     }
@@ -167,16 +167,19 @@
     return listener;
 }
 
-Status changeOwnerAndMode(const char* path, gid_t group, const char* debugName, mode_t groupMode) {
+Status changeOwnerAndMode(const char* path, gid_t group, const char* debugName, bool netdOnly) {
     int ret = chown(path, AID_ROOT, group);
     if (ret != 0) return statusFromErrno(errno, StringPrintf("change %s group failed", debugName));
 
-    // Ensure groupMode only contains group bits.
-    groupMode &= S_IRGRP | S_IWGRP;
-
-    // chmod doesn't by itself grant permission to all processes in that group to
-    // read/write the bpf map. They still need correct sepolicy.
-    ret = chmod(path, S_IRUSR | S_IWUSR | groupMode);
+    if (netdOnly) {
+        ret = chmod(path, S_IRWXU);
+    } else {
+        // Allow both netd and system server to obtain map fd from the path.
+        // chmod doesn't grant permission to all processes in that group to
+        // read/write the bpf map. They still need correct sepolicy to
+        // read/write the map.
+        ret = chmod(path, S_IRWXU | S_IRGRP | S_IWGRP);
+    }
     if (ret != 0) return statusFromErrno(errno, StringPrintf("change %s mode failed", debugName));
     return netdutils::status::ok;
 }
@@ -194,56 +197,43 @@
 Status TrafficController::initMaps() {
     std::lock_guard guard(mMutex);
     RETURN_IF_NOT_OK(mCookieTagMap.init(COOKIE_TAG_MAP_PATH));
-    RETURN_IF_NOT_OK(
-            changeOwnerAndMode(COOKIE_TAG_MAP_PATH, AID_NET_BW_ACCT, "CookieTagMap", S_IRGRP));
+    RETURN_IF_NOT_OK(changeOwnerAndMode(COOKIE_TAG_MAP_PATH, AID_NET_BW_ACCT, "CookieTagMap",
+                                        false));
 
     RETURN_IF_NOT_OK(mUidCounterSetMap.init(UID_COUNTERSET_MAP_PATH));
     RETURN_IF_NOT_OK(changeOwnerAndMode(UID_COUNTERSET_MAP_PATH, AID_NET_BW_ACCT,
-                                        "UidCounterSetMap", S_IRGRP));
+                                        "UidCounterSetMap", false));
 
     RETURN_IF_NOT_OK(mAppUidStatsMap.init(APP_UID_STATS_MAP_PATH));
-    RETURN_IF_NOT_OK(changeOwnerAndMode(APP_UID_STATS_MAP_PATH, AID_NET_BW_STATS, "AppUidStatsMap",
-                                        S_IRGRP));
+    RETURN_IF_NOT_OK(
+        changeOwnerAndMode(APP_UID_STATS_MAP_PATH, AID_NET_BW_STATS, "AppUidStatsMap", false));
 
     RETURN_IF_NOT_OK(mStatsMapA.init(STATS_MAP_A_PATH));
-    RETURN_IF_NOT_OK(
-            changeOwnerAndMode(STATS_MAP_A_PATH, AID_NET_BW_STATS, "StatsMapA", S_IRGRP | S_IWGRP));
+    RETURN_IF_NOT_OK(changeOwnerAndMode(STATS_MAP_A_PATH, AID_NET_BW_STATS, "StatsMapA", false));
 
     RETURN_IF_NOT_OK(mStatsMapB.init(STATS_MAP_B_PATH));
-    RETURN_IF_NOT_OK(
-            changeOwnerAndMode(STATS_MAP_B_PATH, AID_NET_BW_STATS, "StatsMapB", S_IRGRP | S_IWGRP));
+    RETURN_IF_NOT_OK(changeOwnerAndMode(STATS_MAP_B_PATH, AID_NET_BW_STATS, "StatsMapB", false));
 
     RETURN_IF_NOT_OK(mIfaceIndexNameMap.init(IFACE_INDEX_NAME_MAP_PATH));
     RETURN_IF_NOT_OK(changeOwnerAndMode(IFACE_INDEX_NAME_MAP_PATH, AID_NET_BW_STATS,
-                                        "IfaceIndexNameMap", S_IRGRP));
+                                        "IfaceIndexNameMap", false));
 
     RETURN_IF_NOT_OK(mIfaceStatsMap.init(IFACE_STATS_MAP_PATH));
-    RETURN_IF_NOT_OK(
-            changeOwnerAndMode(IFACE_STATS_MAP_PATH, AID_NET_BW_STATS, "IfaceStatsMap", S_IRGRP));
+    RETURN_IF_NOT_OK(changeOwnerAndMode(IFACE_STATS_MAP_PATH, AID_NET_BW_STATS, "IfaceStatsMap",
+                                        false));
 
     RETURN_IF_NOT_OK(mConfigurationMap.init(CONFIGURATION_MAP_PATH));
     RETURN_IF_NOT_OK(changeOwnerAndMode(CONFIGURATION_MAP_PATH, AID_NET_BW_STATS,
-                                        "ConfigurationMap", S_IRGRP));
+                                        "ConfigurationMap", false));
     RETURN_IF_NOT_OK(
             mConfigurationMap.writeValue(UID_RULES_CONFIGURATION_KEY, DEFAULT_CONFIG, BPF_ANY));
     RETURN_IF_NOT_OK(mConfigurationMap.writeValue(CURRENT_STATS_MAP_CONFIGURATION_KEY, SELECT_MAP_A,
                                                   BPF_ANY));
 
     RETURN_IF_NOT_OK(mUidOwnerMap.init(UID_OWNER_MAP_PATH));
-    RETURN_IF_NOT_OK(changeOwnerAndMode(UID_OWNER_MAP_PATH, AID_ROOT, "UidOwnerMap", S_NONE));
+    RETURN_IF_NOT_OK(changeOwnerAndMode(UID_OWNER_MAP_PATH, AID_ROOT, "UidOwnerMap", true));
     RETURN_IF_NOT_OK(mUidOwnerMap.clear());
     RETURN_IF_NOT_OK(mUidPermissionMap.init(UID_PERMISSION_MAP_PATH));
-
-    // The programs must be readable to process that modify iptables rules
-    RETURN_IF_NOT_OK(changeOwnerAndMode(XT_BPF_EGRESS_PROG_PATH, AID_NET_ADMIN,
-                                        "XtFilterEgressProgram", S_IRGRP));
-    RETURN_IF_NOT_OK(changeOwnerAndMode(XT_BPF_INGRESS_PROG_PATH, AID_NET_ADMIN,
-                                        "XtFilterIngressProgram", S_IRGRP));
-    RETURN_IF_NOT_OK(changeOwnerAndMode(XT_BPF_WHITELIST_PROG_PATH, AID_NET_ADMIN,
-                                        "XtWhitelistProgram", S_IRGRP));
-    RETURN_IF_NOT_OK(changeOwnerAndMode(XT_BPF_BLACKLIST_PROG_PATH, AID_NET_ADMIN,
-                                        "XtBlacklistProgram", S_IRGRP));
-
     return netdutils::status::ok;
 }
 
@@ -588,10 +578,8 @@
                                      UidOwnerMatchType match) {
     auto oldMatch = map.readValue(uid);
     if (isOk(oldMatch)) {
-        UidOwnerValue newMatch = {
-                .iif = (match == IIF_MATCH) ? 0 : oldMatch.value().iif,
-                .rule = static_cast<uint8_t>(oldMatch.value().rule & ~match),
-        };
+        UidOwnerValue newMatch = {.rule = static_cast<uint8_t>(oldMatch.value().rule & ~match),
+                                  .iif = (match == IIF_MATCH) ? 0 : oldMatch.value().iif};
         if (newMatch.rule == 0) {
             RETURN_IF_NOT_OK(map.deleteValue(uid));
         } else {
@@ -613,16 +601,11 @@
     }
     auto oldMatch = map.readValue(uid);
     if (isOk(oldMatch)) {
-        UidOwnerValue newMatch = {
-                .iif = iif ? iif : oldMatch.value().iif,
-                .rule = static_cast<uint8_t>(oldMatch.value().rule | match),
-        };
+        UidOwnerValue newMatch = {.rule = static_cast<uint8_t>(oldMatch.value().rule | match),
+                                  .iif = iif ? iif : oldMatch.value().iif};
         RETURN_IF_NOT_OK(map.writeValue(uid, newMatch, BPF_ANY));
     } else {
-        UidOwnerValue newMatch = {
-                .iif = iif,
-                .rule = static_cast<uint8_t>(match),
-        };
+        UidOwnerValue newMatch = {.rule = static_cast<uint8_t>(match), .iif = iif};
         RETURN_IF_NOT_OK(map.writeValue(uid, newMatch, BPF_ANY));
     }
     return netdutils::status::ok;
@@ -864,7 +847,7 @@
             mPrivilegedUser.erase(uid);
             if (mBpfLevel > BpfLevel::NONE) {
                 Status ret = mUidPermissionMap.deleteValue(uid);
-                if (!isOk(ret) && ret.code() != ENOENT) {
+                if (!isOk(ret) && ret.code() != ENONET) {
                     ALOGE("Failed to clean up the permission for %u: %s", uid,
                           strerror(ret.code()));
                 }
@@ -1092,28 +1075,15 @@
     uint32_t key = UID_RULES_CONFIGURATION_KEY;
     auto configuration = mConfigurationMap.readValue(key);
     if (isOk(configuration)) {
-        dw.println("current ownerMatch configuration: %d%s", configuration.value(),
-                   uidMatchTypeToString(configuration.value()).c_str());
+        dw.println("current ownerMatch configuration: %d", configuration.value());
     } else {
         dw.println("mConfigurationMap read ownerMatch configure failed with error: %s",
                    configuration.status().msg().c_str());
     }
-
     key = CURRENT_STATS_MAP_CONFIGURATION_KEY;
     configuration = mConfigurationMap.readValue(key);
     if (isOk(configuration)) {
-        const char* statsMapDescription = "???";
-        switch (configuration.value()) {
-            case SELECT_MAP_A:
-                statsMapDescription = "SELECT_MAP_A";
-                break;
-            case SELECT_MAP_B:
-                statsMapDescription = "SELECT_MAP_B";
-                break;
-                // No default clause, so if we ever add a third map, this code will fail to build.
-        }
-        dw.println("current statsMap configuration: %d %s", configuration.value(),
-                   statsMapDescription);
+        dw.println("current statsMap configuration: %d", configuration.value());
     } else {
         dw.println("mConfigurationMap read stats map configure failed with error: %s",
                    configuration.status().msg().c_str());
@@ -1139,7 +1109,7 @@
         dw.println("mUidOwnerMap print end with error: %s", res.msg().c_str());
     }
     dumpBpfMap("mUidPermissionMap", dw, "");
-    const auto printUidPermissionInfo = [&dw](const uint32_t& key, const int& value,
+    const auto printUidPermissionInfo = [&dw](const uint32_t& key, const uint8_t& value,
                                               const BpfMap<uint32_t, uint8_t>&) {
         dw.println("%u %s", key, UidPermissionTypeToString(value).c_str());
         return netdutils::status::ok;
diff --git a/server/VirtualNetwork.h b/server/VirtualNetwork.h
index 20c8dee..69b14d8 100644
--- a/server/VirtualNetwork.h
+++ b/server/VirtualNetwork.h
@@ -14,14 +14,16 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef NETD_SERVER_VIRTUAL_NETWORK_H
+#define NETD_SERVER_VIRTUAL_NETWORK_H
 
 #include <set>
 
 #include "Network.h"
 #include "UidRanges.h"
 
-namespace android::net {
+namespace android {
+namespace net {
 
 // A VirtualNetwork may be "secure" or not.
 //
@@ -38,14 +40,15 @@
     bool isSecure() const;
     bool appliesToUser(uid_t uid) const;
 
-    [[nodiscard]] int addUsers(const UidRanges& uidRanges, const std::set<uid_t>& protectableUsers);
-    [[nodiscard]] int removeUsers(const UidRanges& uidRanges,
-                                  const std::set<uid_t>& protectableUsers);
+    int addUsers(const UidRanges& uidRanges,
+                 const std::set<uid_t>& protectableUsers) WARN_UNUSED_RESULT;
+    int removeUsers(const UidRanges& uidRanges,
+                    const std::set<uid_t>& protectableUsers) WARN_UNUSED_RESULT;
 
-  private:
+private:
     Type getType() const override;
-    [[nodiscard]] int addInterface(const std::string& interface) override;
-    [[nodiscard]] int removeInterface(const std::string& interface) override;
+    int addInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+    int removeInterface(const std::string& interface) override WARN_UNUSED_RESULT;
     int maybeCloseSockets(bool add, const UidRanges& uidRanges,
                           const std::set<uid_t>& protectableUsers);
 
@@ -53,4 +56,7 @@
     UidRanges mUidRanges;
 };
 
-}  // namespace android::net
+}  // namespace net
+}  // namespace android
+
+#endif  // NETD_SERVER_VIRTUAL_NETWORK_H
diff --git a/server/XfrmController.cpp b/server/XfrmController.cpp
index 199638c..a57b492 100644
--- a/server/XfrmController.cpp
+++ b/server/XfrmController.cpp
@@ -53,6 +53,7 @@
 #include <cutils/properties.h>
 #include <log/log.h>
 #include <log/log_properties.h>
+#include <logwrap/logwrap.h>
 #include "Fwmark.h"
 #include "InterfaceController.h"
 #include "NetdConstants.h"
diff --git a/server/XfrmControllerTest.cpp b/server/XfrmControllerTest.cpp
index e7f5cfc..36af67a 100644
--- a/server/XfrmControllerTest.cpp
+++ b/server/XfrmControllerTest.cpp
@@ -19,6 +19,7 @@
 #include <cerrno>
 #include <cinttypes>
 #include <cstdint>
+#include <cstdio>
 #include <cstdlib>
 #include <set>
 #include <vector>
diff --git a/server/binder/android/net/INetd.aidl b/server/binder/android/net/INetd.aidl
index fdea52e..ec9bbc3 100644
--- a/server/binder/android/net/INetd.aidl
+++ b/server/binder/android/net/INetd.aidl
@@ -1194,18 +1194,4 @@
     * @return a IBinder object, it could be casted to oem specific interface.
     */
     IBinder getOemNetd();
-
-   /**
-    * Start tethering with given configuration
-    *
-    * @param usingLegacyDnsProxy, whether to enable or disable legacy DNS proxy server.
-    * @param dhcpRanges dhcp ranges to set.
-    *                   dhcpRanges might contain many addresss {addr1, addr2, aadr3, addr4...}
-    *                   Netd splits them into ranges: addr1-addr2, addr3-addr4, etc.
-    *                   An odd number of addrs will fail.
-    * @throws ServiceSpecificException in case of failure, with an error code indicating the
-    *         cause of the failure.
-    */
-    void tetherStartWithConfiguration(
-            boolean usingLegacyDnsProxy, in @utf8InCpp String[] dhcpRanges);
 }
diff --git a/server/main.cpp b/server/main.cpp
index d8ed96f..b783ce5 100644
--- a/server/main.cpp
+++ b/server/main.cpp
@@ -14,19 +14,19 @@
  * limitations under the License.
  */
 
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
+#include <chrono>
 #include <stdio.h>
 #include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
 #include <string.h>
+#include <mutex>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
-#include <chrono>
-#include <cinttypes>
-#include <mutex>
+
+#include <fcntl.h>
+#include <dirent.h>
 
 #define LOG_TAG "Netd"
 
@@ -82,21 +82,11 @@
     gLog.info(std::string(msg));
 }
 
-int tagSocketCallback(int sockFd, uint32_t tag, uid_t uid, pid_t) {
-    return gCtls->trafficCtrl.tagSocket(sockFd, tag, uid, geteuid());
-}
-
-bool evaluateDomainNameCallback(const android_net_context&, const char* /*name*/) {
-    return true;
-}
-
 bool initDnsResolver() {
     ResolverNetdCallbacks callbacks = {
-            .check_calling_permission = &checkCallingPermissionCallback,
             .get_network_context = &getNetworkContextCallback,
             .log = &logCallback,
-            .tagSocket = &tagSocketCallback,
-            .evaluate_domain_name = &evaluateDomainNameCallback,
+            .check_calling_permission = &checkCallingPermissionCallback,
     };
     return RESOLV_STUB.resolv_init(callbacks);
 }
@@ -185,7 +175,7 @@
         ALOGE("Unable to start NetdNativeService: %d", ret);
         exit(1);
     }
-    gLog.info("Registering NetdNativeService: %" PRId64 "us", subTime.getTimeAndResetUs());
+    gLog.info("Registering NetdNativeService: %.1fms", subTime.getTimeAndReset());
 
     android::net::process::ScopedPidFile pidFile(PID_FILE_PATH);
 
@@ -196,8 +186,9 @@
         ALOGE("Unable to start NetdHwService: %d", ret);
         exit(1);
     }
-    gLog.info("Registering NetdHwService: %" PRId64 "us", subTime.getTimeAndResetUs());
-    gLog.info("Netd started in %" PRId64 "us", s.timeTakenUs());
+    gLog.info("Registering NetdHwService: %.1fms", subTime.getTimeAndReset());
+
+    gLog.info("Netd started in %dms", static_cast<int>(s.timeTaken()));
 
     IPCThreadState::self()->joinThreadPool();
 
diff --git a/server/oem_iptables_hook.cpp b/server/oem_iptables_hook.cpp
index 39a6285..c7f8dbf 100644
--- a/server/oem_iptables_hook.cpp
+++ b/server/oem_iptables_hook.cpp
@@ -26,6 +26,7 @@
 
 #define LOG_TAG "OemIptablesHook"
 #include <log/log.h>
+#include <logwrap/logwrap.h>
 #include "NetdConstants.h"
 
 namespace {
diff --git a/tests/Android.bp b/tests/Android.bp
index 1ac413f..4237b25 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -47,23 +47,11 @@
     ],
 }
 
-cc_test_library {
-    name: "libnetd_test_utils",
-    srcs: [
-        "test_utils.cpp"
-    ],
-    export_include_dirs: ["."],
-    shared_libs: [
-        "libbase",
-    ],
-}
-
 cc_test {
     name: "netd_integration_test",
     test_suites: ["device-tests"],
     require_root: true,
     defaults: ["netd_defaults"],
-    tidy: false,  // cuts test build time by almost 1 minute
     srcs: [
         ":netd_integration_test_shared",
         "binder_test.cpp",
@@ -88,12 +76,12 @@
         "libcap",
         "libnetd_test_tun_interface",
         "libnetd_test_unsol_service",
-        "libnetd_test_utils",
         "libbpf_android",
+        "liblogwrap",
         "libnetdbpf",
         "libnetdutils",
         "libqtaguid",
-        "netd_aidl_interface-unstable-cpp",
+        "netd_aidl_interface-cpp",
         "netd_event_listener_interface-cpp",
         "oemnetd_aidl_interface-cpp",
     ],
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
new file mode 100644
index 0000000..7b18f9f
--- /dev/null
+++ b/tests/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!--
+    To run test manually:
+        make -j netd_integration_test && \
+        tradefed.sh run template/local_min -\-template:map test=netd_integration_test
+
+    For a list of options, see:
+        tools/tradefederation/core/src/com/android/tradefed/testtype/GTest.java
+-->
+<configuration description="Config for netd_integration_test">
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="netd_integration_test->/data/local/tmp/netd_integration_test" />
+    </target_preparer>
+    <option name="test-suite-tag" value="apct" />
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="netd_integration_test" />
+    </test>
+</configuration>
diff --git a/tests/benchmarks/Android.bp b/tests/benchmarks/Android.bp
index 59cac96..c14253d 100644
--- a/tests/benchmarks/Android.bp
+++ b/tests/benchmarks/Android.bp
@@ -9,10 +9,10 @@
         "liblog",
         "libnetd_client",
         "libnetdutils",
-        "libutils",
     ],
     static_libs: [
         "libnetd_test_dnsresponder",
+        "libutils",
         "dnsresolver_aidl_interface-cpp",
         "netd_aidl_interface-cpp",
         "netd_event_listener_interface-cpp",
@@ -23,11 +23,10 @@
     include_dirs: [
         "system/netd/include",
         "system/netd/client",
+        "system/netd/resolv/include",
         "system/netd/server",
         "system/netd/server/binder",
-    ],
-    header_libs: [
-        "libnetd_resolv_headers",
+        "system/netd/resolv/dns_responder",
     ],
     srcs: [
         "main.cpp",
@@ -44,6 +43,9 @@
         "libbpf_android",
         "libnetdutils",
     ],
+    static_libs: [
+        "libutils",
+    ],
     srcs: [
         "bpf_benchmark.cpp",
     ],
diff --git a/tests/benchmarks/AndroidTest.xml b/tests/benchmarks/AndroidTest.xml
new file mode 100644
index 0000000..7756cc2
--- /dev/null
+++ b/tests/benchmarks/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for netd_benchmark">
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="netd_benchmark->/data/local/tmp/netd_benchmark" />
+    </target_preparer>
+    <option name="test-suite-tag" value="apct" />
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="netd_benchmark" />
+    </test>
+</configuration>
diff --git a/tests/benchmarks/connect_benchmark.cpp b/tests/benchmarks/connect_benchmark.cpp
index ed90538..e08fb01 100644
--- a/tests/benchmarks/connect_benchmark.cpp
+++ b/tests/benchmarks/connect_benchmark.cpp
@@ -125,8 +125,8 @@
         }
 
         if (waitBetweenRuns) {
-            latencies[iterations] = stopwatch.timeTakenUs();
-            state.SetIterationTime(static_cast<double>(latencies[iterations]) / 1.0e6L);
+            latencies[iterations] = stopwatch.timeTaken() * 1e6L;
+            state.SetIterationTime(latencies[iterations] / 1e9L);
             std::this_thread::sleep_for(std::chrono::milliseconds(10));
             ++iterations;
         }
@@ -182,8 +182,8 @@
         }
 
         if (waitBetweenRuns) {
-            latencies[iterations] = stopwatch.timeTakenUs();
-            state.SetIterationTime(static_cast<double>(latencies[iterations]) / 1.0e6L);
+            latencies[iterations] = stopwatch.timeTaken() * 1e6L;
+            state.SetIterationTime(latencies[iterations] / 1e9L);
             std::this_thread::sleep_for(std::chrono::milliseconds(10));
             ++iterations;
         }
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index 7be8e55..917bf5d 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -21,8 +21,8 @@
 #include <cinttypes>
 #include <condition_variable>
 #include <cstdint>
+#include <cstdio>
 #include <cstdlib>
-#include <iostream>
 #include <mutex>
 #include <set>
 #include <vector>
@@ -50,6 +50,7 @@
 #include <com/android/internal/net/IOemNetd.h>
 #include <cutils/multiuser.h>
 #include <gtest/gtest.h>
+#include <logwrap/logwrap.h>
 #include <netdbpf/bpf_shared.h>
 #include <netutils/ifc.h>
 #include "Fwmark.h"
@@ -60,13 +61,12 @@
 #include "XfrmController.h"
 #include "android/net/INetd.h"
 #include "binder/IServiceManager.h"
-#include "netdutils/InternetAddresses.h"
 #include "netdutils/Stopwatch.h"
 #include "netdutils/Syscalls.h"
 #include "netid_client.h"  // NETID_UNSET
-#include "test_utils.h"
 #include "tun_interface.h"
 
+#define IP_PATH "/system/bin/ip"
 #define IP6TABLES_PATH "/system/bin/ip6tables"
 #define IPTABLES_PATH "/system/bin/iptables"
 #define TUN_DEV "/dev/tun"
@@ -87,14 +87,12 @@
 using android::base::StartsWith;
 using android::base::StringPrintf;
 using android::base::Trim;
-using android::base::unique_fd;
 using android::net::INetd;
 using android::net::InterfaceConfigurationParcel;
 using android::net::InterfaceController;
 using android::net::TetherStatsParcel;
 using android::net::TunInterface;
 using android::net::UidRangeParcel;
-using android::netdutils::ScopedAddrinfo;
 using android::netdutils::sSyscalls;
 using android::netdutils::Stopwatch;
 
@@ -151,8 +149,7 @@
         sTun2.destroy();
     }
 
-    static void fakeRemoteSocketPair(unique_fd* clientSocket, unique_fd* serverSocket,
-                                     unique_fd* acceptedSocket);
+    static void fakeRemoteSocketPair(int *clientSocket, int *serverSocket, int *acceptedSocket);
 
     void createVpnNetworkWithUid(bool secure, uid_t uid, int vpnNetId = TEST_NETID2,
                                  int fallthroughNetId = TEST_NETID1);
@@ -173,7 +170,7 @@
   public:
     explicit TimedOperation(const std::string &name): mName(name) {}
     virtual ~TimedOperation() {
-        std::cerr << "    " << mName << ": " << timeTakenUs() << "us" << std::endl;
+        fprintf(stderr, "    %s: %6.1f ms\n", mName.c_str(), timeTaken());
     }
 
   private:
@@ -187,6 +184,57 @@
     ASSERT_TRUE(isAlive);
 }
 
+static int randomUid() {
+    return 100000 * arc4random_uniform(7) + 10000 + arc4random_uniform(5000);
+}
+
+static std::vector<std::string> runCommand(const std::string& command) {
+    std::vector<std::string> lines;
+    FILE *f = popen(command.c_str(), "r");  // NOLINT(cert-env33-c)
+    if (f == nullptr) {
+        perror("popen");
+        return lines;
+    }
+
+    char *line = nullptr;
+    size_t bufsize = 0;
+    ssize_t linelen = 0;
+    while ((linelen = getline(&line, &bufsize, f)) >= 0) {
+        lines.push_back(std::string(line, linelen));
+        free(line);
+        line = nullptr;
+    }
+
+    pclose(f);
+    return lines;
+}
+
+static std::vector<std::string> listIpRules(const char *ipVersion) {
+    std::string command = StringPrintf("%s %s rule list", IP_PATH, ipVersion);
+    return runCommand(command);
+}
+
+static std::vector<std::string> listIptablesRule(const char *binary, const char *chainName) {
+    std::string command = StringPrintf("%s -w -n -L %s", binary, chainName);
+    return runCommand(command);
+}
+
+static int iptablesRuleLineLength(const char *binary, const char *chainName) {
+    return listIptablesRule(binary, chainName).size();
+}
+
+static bool iptablesRuleExists(const char *binary,
+                               const char *chainName,
+                               const std::string& expectedRule) {
+    std::vector<std::string> rules = listIptablesRule(binary, chainName);
+    for (const auto& rule : rules) {
+        if(rule.find(expectedRule) != std::string::npos) {
+            return true;
+        }
+    }
+    return false;
+}
+
 static bool iptablesNoSocketAllowRuleExists(const char *chainName){
     return iptablesRuleExists(IPTABLES_PATH, chainName, NO_SOCKET_ALLOW_RULE) &&
            iptablesRuleExists(IP6TABLES_PATH, chainName, NO_SOCKET_ALLOW_RULE);
@@ -293,7 +341,7 @@
 }
 
 TEST_F(BinderTest, IpSecSetEncapSocketOwner) {
-    unique_fd uniqueFd(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+    android::base::unique_fd uniqueFd(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
     android::os::ParcelFileDescriptor sockFd(std::move(uniqueFd));
 
     int sockOptVal = UDP_ENCAP_ESPINUDP;
@@ -580,18 +628,22 @@
 
     std::vector<UidRangeParcel> uidRanges = {makeUidRangeParcel(BASE_UID + 150, BASE_UID + 224),
                                              makeUidRangeParcel(BASE_UID + 226, BASE_UID + 300)};
-    // Make sure no rules existed before calling commands.
-    for (auto const& range : uidRanges) {
-        EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY, range, "prohibit"));
-    }
+
+    const std::vector<std::string> initialRulesV4 = listIpRules(IP_RULE_V4);
+    const std::vector<std::string> initialRulesV6 = listIpRules(IP_RULE_V6);
+
     // Create two valid rules.
     ASSERT_TRUE(mNetd->networkRejectNonSecureVpn(true, uidRanges).isOk());
+    EXPECT_EQ(initialRulesV4.size() + 2, listIpRules(IP_RULE_V4).size());
+    EXPECT_EQ(initialRulesV6.size() + 2, listIpRules(IP_RULE_V6).size());
     for (auto const& range : uidRanges) {
         EXPECT_TRUE(ipRuleExistsForRange(RULE_PRIORITY, range, "prohibit"));
     }
 
     // Remove the rules.
     ASSERT_TRUE(mNetd->networkRejectNonSecureVpn(false, uidRanges).isOk());
+    EXPECT_EQ(initialRulesV4.size(), listIpRules(IP_RULE_V4).size());
+    EXPECT_EQ(initialRulesV6.size(), listIpRules(IP_RULE_V6).size());
     for (auto const& range : uidRanges) {
         EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY, range, "prohibit"));
     }
@@ -600,12 +652,15 @@
     binder::Status status = mNetd->networkRejectNonSecureVpn(false, uidRanges);
     ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
     EXPECT_EQ(ENOENT, status.serviceSpecificErrorCode());
+
+    // All rules should be the same as before.
+    EXPECT_EQ(initialRulesV4, listIpRules(IP_RULE_V4));
+    EXPECT_EQ(initialRulesV6, listIpRules(IP_RULE_V6));
 }
 
 // Create a socket pair that isLoopbackSocket won't think is local.
-void BinderTest::fakeRemoteSocketPair(unique_fd* clientSocket, unique_fd* serverSocket,
-                                      unique_fd* acceptedSocket) {
-    serverSocket->reset(socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0));
+void BinderTest::fakeRemoteSocketPair(int *clientSocket, int *serverSocket, int *acceptedSocket) {
+    *serverSocket = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
     struct sockaddr_in6 server6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.dstAddr() };
     ASSERT_EQ(0, bind(*serverSocket, (struct sockaddr *) &server6, sizeof(server6)));
 
@@ -613,14 +668,13 @@
     ASSERT_EQ(0, getsockname(*serverSocket, (struct sockaddr *) &server6, &addrlen));
     ASSERT_EQ(0, listen(*serverSocket, 10));
 
-    clientSocket->reset(socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0));
+    *clientSocket = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
     struct sockaddr_in6 client6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.srcAddr() };
     ASSERT_EQ(0, bind(*clientSocket, (struct sockaddr *) &client6, sizeof(client6)));
     ASSERT_EQ(0, connect(*clientSocket, (struct sockaddr *) &server6, sizeof(server6)));
     ASSERT_EQ(0, getsockname(*clientSocket, (struct sockaddr *) &client6, &addrlen));
 
-    acceptedSocket->reset(
-            accept4(*serverSocket, (struct sockaddr*)&server6, &addrlen, SOCK_CLOEXEC));
+    *acceptedSocket = accept4(*serverSocket, (struct sockaddr *) &server6, &addrlen, SOCK_CLOEXEC);
     ASSERT_NE(-1, *acceptedSocket);
 
     ASSERT_EQ(0, memcmp(&client6, &server6, sizeof(client6)));
@@ -648,7 +702,7 @@
 }
 
 TEST_F(BinderTest, SocketDestroy) {
-    unique_fd clientSocket, serverSocket, acceptedSocket;
+    int clientSocket, serverSocket, acceptedSocket;
     ASSERT_NO_FATAL_FAILURE(fakeRemoteSocketPair(&clientSocket, &serverSocket, &acceptedSocket));
 
     // Pick a random UID in the system UID range.
@@ -688,6 +742,10 @@
     skipUids.resize(skipUids.size() - 1);
     EXPECT_TRUE(mNetd->socketDestroy(uidRanges, skipUids).isOk());
     checkSocketpairClosed(clientSocket, acceptedSocket);
+
+    close(clientSocket);
+    close(serverSocket);
+    close(acceptedSocket);
 }
 
 namespace {
@@ -989,11 +1047,8 @@
     std::string intIface1 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
     std::string intIface2 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
     std::string intIface3 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
-
-    // Ensure we won't use the same interface name, otherwise the test will fail.
-    u_int32_t rNumber = arc4random_uniform(10000);
-    std::string extIface1 = StringPrintf("netdtest_%u", rNumber);
-    std::string extIface2 = StringPrintf("netdtest_%u", rNumber + 1);
+    std::string extIface1 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
+    std::string extIface2 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
 
     addTetherCounterValues(IPTABLES_PATH,  intIface1, extIface1, 123, 111);
     addTetherCounterValues(IP6TABLES_PATH, intIface1, extIface1, 456,  10);
@@ -1566,13 +1621,13 @@
 }
 
 TEST_F(BinderTest, BandwidthSetGlobalAlert) {
-    int64_t testAlertBytes = 2097200;
+    long testAlertBytes = 2097149;
 
     binder::Status status = mNetd->bandwidthSetGlobalAlert(testAlertBytes);
     EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
     expectBandwidthGlobalAlertRuleExists(testAlertBytes);
 
-    testAlertBytes = 2098230;
+    testAlertBytes = 2097152;
     status = mNetd->bandwidthSetGlobalAlert(testAlertBytes);
     EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
     expectBandwidthGlobalAlertRuleExists(testAlertBytes);
@@ -1608,6 +1663,21 @@
 
 namespace {
 
+std::vector<std::string> listIpRoutes(const char* ipVersion, const char* table) {
+    std::string command = StringPrintf("%s %s route ls table %s", IP_PATH, ipVersion, table);
+    return runCommand(command);
+}
+
+bool ipRouteExists(const char* ipVersion, const char* table, const std::string& ipRoute) {
+    std::vector<std::string> routes = listIpRoutes(ipVersion, table);
+    for (const auto& route : routes) {
+        if (route.find(ipRoute) != std::string::npos) {
+            return true;
+        }
+    }
+    return false;
+}
+
 std::string ipRouteString(const std::string& ifName, const std::string& dst,
                           const std::string& nextHop) {
     std::string dstString = (dst == "0.0.0.0/0" || dst == "::/0") ? "default" : dst;
@@ -1902,20 +1972,16 @@
 }
 
 TEST_F(BinderTest, NetworkSetProtectAllowDeny) {
-    binder::Status status = mNetd->networkSetProtectAllow(TEST_UID1);
+    const int testUid = randomUid();
+    binder::Status status = mNetd->networkSetProtectAllow(testUid);
     EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
     bool ret = false;
-    status = mNetd->networkCanProtect(TEST_UID1, &ret);
+    status = mNetd->networkCanProtect(testUid, &ret);
     EXPECT_TRUE(ret);
 
-    status = mNetd->networkSetProtectDeny(TEST_UID1);
+    status = mNetd->networkSetProtectDeny(testUid);
     EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-
-    // Clear uid permission before calling networkCanProtect to ensure
-    // the call won't be affected by uid permission.
-    EXPECT_TRUE(mNetd->networkClearPermissionForUser({TEST_UID1}).isOk());
-
-    status = mNetd->networkCanProtect(TEST_UID1, &ret);
+    status = mNetd->networkCanProtect(testUid, &ret);
     EXPECT_FALSE(ret);
 }
 
@@ -1992,30 +2058,22 @@
     std::vector<std::string> noDhcpRange = {};
     static const char dnsdName[] = "dnsmasq";
 
-    for (bool usingLegacyDnsProxy : {true, false}) {
-        binder::Status status =
-                mNetd->tetherStartWithConfiguration(usingLegacyDnsProxy, noDhcpRange);
-        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-        SCOPED_TRACE(StringPrintf("usingLegacyDnsProxy: %d", usingLegacyDnsProxy));
-        if (usingLegacyDnsProxy == true) {
-            expectProcessExists(dnsdName);
-        } else {
-            expectProcessDoesNotExist(dnsdName);
-        }
+    binder::Status status = mNetd->tetherStart(noDhcpRange);
+    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+    expectProcessExists(dnsdName);
 
-        bool tetherEnabled;
-        status = mNetd->tetherIsEnabled(&tetherEnabled);
-        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-        EXPECT_TRUE(tetherEnabled);
+    bool tetherEnabled;
+    status = mNetd->tetherIsEnabled(&tetherEnabled);
+    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+    EXPECT_TRUE(tetherEnabled);
 
-        status = mNetd->tetherStop();
-        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-        expectProcessDoesNotExist(dnsdName);
+    status = mNetd->tetherStop();
+    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+    expectProcessDoesNotExist(dnsdName);
 
-        status = mNetd->tetherIsEnabled(&tetherEnabled);
-        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-        EXPECT_FALSE(tetherEnabled);
-    }
+    status = mNetd->tetherIsEnabled(&tetherEnabled);
+    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+    EXPECT_FALSE(tetherEnabled);
 }
 
 TEST_F(BinderTest, TetherInterfaceAddRemoveList) {
@@ -3108,14 +3166,10 @@
 
 bool sendIPv6PacketFromUid(uid_t uid, const in6_addr& dstAddr, Fwmark* fwmark, int tunFd) {
     ScopedUidChange scopedUidChange(uid);
-    unique_fd testSocket(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+    android::base::unique_fd testSocket(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
     if (testSocket < 0) return false;
 
-    const sockaddr_in6 dst6 = {
-            .sin6_family = AF_INET6,
-            .sin6_port = 42,
-            .sin6_addr = dstAddr,
-    };
+    const sockaddr_in6 dst6 = {.sin6_family = AF_INET6, .sin6_addr = dstAddr, .sin6_port = 42};
     int res = connect(testSocket, (sockaddr*)&dst6, sizeof(dst6));
     socklen_t fwmarkLen = sizeof(fwmark->intValue);
     EXPECT_NE(-1, getsockopt(testSocket, SOL_SOCKET, SO_MARK, &(fwmark->intValue), &fwmarkLen));
@@ -3228,4 +3282,4 @@
     // Get current default network NetId
     ASSERT_TRUE(mNetd->networkGetDefault(&mStoredDefaultNetwork).isOk());
     expectVpnFallthroughWorks(mNetd.get(), true /* bypassable */, TEST_UID1, sTun, sTun2);
-}
+}
\ No newline at end of file
diff --git a/tests/netd_test.cpp b/tests/netd_test.cpp
index 9a6e69c..7e14b01 100644
--- a/tests/netd_test.cpp
+++ b/tests/netd_test.cpp
@@ -7,7 +7,7 @@
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
+ * Unless requied by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
diff --git a/tests/netlink_listener_test.cpp b/tests/netlink_listener_test.cpp
index 8c9b622..b39182c 100644
--- a/tests/netlink_listener_test.cpp
+++ b/tests/netlink_listener_test.cpp
@@ -150,11 +150,8 @@
     checkMassiveSocketDestroy(100, false);
 }
 
-// Disabled because flaky on blueline-userdebug; this test relies on the main thread
-// winning a race against the NetlinkListener::run() thread. There's no way to ensure
-// things will be scheduled the same way across all architectures and test environments.
-TEST_F(NetlinkListenerTest, DISABLED_TestSkDestroyError) {
+TEST_F(NetlinkListenerTest, TestSkDestroyError) {
     SKIP_IF_BPF_NOT_SUPPORTED;
 
-    checkMassiveSocketDestroy(50000, true);
+    checkMassiveSocketDestroy(20000, true);
 }
diff --git a/tests/runtests.sh b/tests/runtests.sh
new file mode 100755
index 0000000..6f828fc
--- /dev/null
+++ b/tests/runtests.sh
@@ -0,0 +1,162 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+
+readonly DEFAULT_TESTS="
+    netdutils_test
+    netd_unit_test
+    netd_integration_test
+    resolv_integration_test
+    resolv_unit_test
+"
+
+readonly EXTENDED_TESTS="
+    netd_benchmark
+"
+
+readonly TEST_DEVICE_PATH="/data/local/tmp"
+
+REPO_TOP=""
+SOONG_BIN=""
+DEBUG=""
+
+function logToStdErr() {
+    echo "$1" >&2
+}
+
+function testAndSetRepoTop() {
+    if [[ -n "$1" && -d "$1/.repo" ]]; then
+        REPO_TOP="$1"
+        SOONG_BIN="$REPO_TOP/build/soong/soong_ui.bash"
+        return 0
+    fi
+    return 1
+}
+
+function gotoRepoTop() {
+    if testAndSetRepoTop "$ANDROID_BUILD_TOP"; then
+        return
+    fi
+
+    while ! testAndSetRepoTop "$PWD"; do
+        if [[ "$PWD" == "/" ]]; then
+            break
+        fi
+        cd ..
+    done
+}
+
+function runCmd() {
+    local cmd="$@"
+    echo "#"
+    echo "# $cmd"
+    $DEBUG $cmd
+    return $?
+}
+
+function runOneTest() {
+    local test="$1"
+    echo
+    echo "###"
+    echo "# $test"
+    echo "###"
+
+    local prefix="$ANDROID_TARGET_OUT_TESTCASES/$test/$TARGET_ARCH/$test"
+    for bits in '' 32 64; do
+            local testbin="${prefix}${bits}"
+            if [ -f "$testbin" ]; then
+                runCmd adb push "$testbin" "$TEST_DEVICE_PATH/$test" &&
+                    runCmd adb shell "$TEST_DEVICE_PATH/$test" &&
+                    runCmd adb shell "rm $TEST_DEVICE_PATH/$test"
+                return $?
+            fi
+    done
+
+    logToStdErr "Couldn't find test binary '$prefix'"
+    return 1
+}
+
+function main() {
+    if [ ! -v ANDROID_BUILD_TOP ]; then
+        logToStdErr "You need to source and lunch before you can use this script"
+        return 1
+    fi
+    gotoRepoTop
+    if ! testAndSetRepoTop "$REPO_TOP"; then
+        logToStdErr "Could not find useful top of repo directory"
+        return 1
+    fi
+    logToStdErr "Using REPO_TOP=$REPO_TOP"
+
+    TARGET_ARCH=$("$SOONG_BIN" --dumpvar-mode TARGET_ARCH)
+    if [ -z "$TARGET_ARCH" ]; then
+        logToStdErr "Could not determine TARGET_ARCH"
+        return 1
+    fi
+
+    local test_regex=""
+    while [[ $# -gt 0 ]]; do
+        case "$1" in
+            "-n")
+                DEBUG=echo
+                shift
+                ;;
+            *)
+                # Allow us to do things like "runtests.sh integration", etc.
+                test_regex="$1"
+                shift
+                ;;
+        esac
+    done
+
+    # Try becoming root, in case the tests will be run on a device
+    # with a userdebug build. Failure to become root is not fatal
+    # for all (in fact, not even most) tests so don't exit on error.
+    runCmd adb root || logToStdErr "WARNING: unable to 'adb root'"
+
+    local failures=0
+    local skipped=0
+
+    # Find out which tests to run.
+    local tests=""
+    for testName in $DEFAULT_TESTS; do
+        if [[ -z "$test_regex" || "$testName" =~ "$test_regex" ]]; then
+            tests="$tests $testName"
+        else
+            logToStdErr "Skipping $testName"
+            skipped=$((skipped + 1))
+        fi
+    done
+
+    # If something has been specified, also check the extended tests for
+    # a possible match (i.e. in order to run benchmarks, etc).
+    if [[ -n "$test_regex" ]]; then
+        for testName in $EXTENDED_TESTS; do
+            if [[ "$testName" =~ "$test_regex" ]]; then
+                tests="$tests $testName"
+            fi
+        done
+    fi
+
+    if [[ -z "$tests" ]]; then
+        logToStdErr "No tests matched"
+        return 1
+    fi
+
+    # Build all the specified tests.
+    runCmd "$SOONG_BIN" --make-mode "$tests" || return $?
+
+    # Run all the specified tests.
+    for testName in $tests; do
+        runOneTest "$testName" || failures=$((failures + 1))
+    done
+
+    echo "Number of tests failing: $failures"
+    [[ $skipped -gt 0 ]] && echo "Number of tests skipped: $skipped"
+    return $failures
+}
+
+
+main "$@"
+exit $?
diff --git a/tests/test_utils.cpp b/tests/test_utils.cpp
deleted file mode 100644
index 27b17c5..0000000
--- a/tests/test_utils.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * test_utils.cpp - miscellaneous unit test utilities.
- */
-
-#include <cstdio>
-#include <string>
-#include <vector>
-
-#include <android-base/stringprintf.h>
-
-#include "test_utils.h"
-
-#define IP_PATH "/system/bin/ip"
-
-using android::base::StringPrintf;
-
-int randomUid() {
-    // Pick a random UID consisting of:
-    // - Random user profile (0 - 6)
-    // - Random app ID starting from 12000 (FIRST_APPLICATION_UID + 2000). This ensures no conflicts
-    //   with existing app UIDs unless the user has installed more than 2000 apps, and is still less
-    //   than LAST_APPLICATION_UID (19999).
-    return 100000 * arc4random_uniform(7) + 12000 + arc4random_uniform(3000);
-}
-
-std::vector<std::string> runCommand(const std::string& command) {
-    std::vector<std::string> lines;
-    FILE* f = popen(command.c_str(), "r");  // NOLINT(cert-env33-c)
-    if (f == nullptr) {
-        perror("popen");
-        return lines;
-    }
-
-    char* line = nullptr;
-    size_t bufsize = 0;
-    ssize_t linelen = 0;
-    while ((linelen = getline(&line, &bufsize, f)) >= 0) {
-        lines.push_back(std::string(line, linelen));
-        free(line);
-        line = nullptr;
-    }
-
-    pclose(f);
-    return lines;
-}
-
-std::vector<std::string> listIpRules(const char* ipVersion) {
-    std::string command = StringPrintf("%s %s rule list", IP_PATH, ipVersion);
-    return runCommand(command);
-}
-
-std::vector<std::string> listIptablesRule(const char* binary, const char* chainName) {
-    std::string command = StringPrintf("%s -w -n -L %s", binary, chainName);
-    return runCommand(command);
-}
-
-int iptablesRuleLineLength(const char* binary, const char* chainName) {
-    return listIptablesRule(binary, chainName).size();
-}
-
-bool iptablesRuleExists(const char* binary, const char* chainName,
-                        const std::string& expectedRule) {
-    std::vector<std::string> rules = listIptablesRule(binary, chainName);
-    for (const auto& rule : rules) {
-        if (rule.find(expectedRule) != std::string::npos) {
-            return true;
-        }
-    }
-    return false;
-}
-
-std::vector<std::string> listIpRoutes(const char* ipVersion, const char* table) {
-    std::string command = StringPrintf("%s %s route ls table %s", IP_PATH, ipVersion, table);
-    return runCommand(command);
-}
-
-bool ipRouteExists(const char* ipVersion, const char* table, const std::string& ipRoute) {
-    std::vector<std::string> routes = listIpRoutes(ipVersion, table);
-    for (const auto& route : routes) {
-        if (route.find(ipRoute) != std::string::npos) {
-            return true;
-        }
-    }
-    return false;
-}
diff --git a/tests/test_utils.h b/tests/test_utils.h
deleted file mode 100644
index c8cd6ce..0000000
--- a/tests/test_utils.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * test_utils.h - miscellaneous unit test utilities.
- */
-
-#pragma once
-
-#include <string>
-#include <vector>
-
-int randomUid();
-
-std::vector<std::string> runCommand(const std::string& command);
-
-std::vector<std::string> listIpRules(const char* ipVersion);
-
-std::vector<std::string> listIptablesRule(const char* binary, const char* chainName);
-
-int iptablesRuleLineLength(const char* binary, const char* chainName);
-
-bool iptablesRuleExists(const char* binary, const char* chainName, const std::string& expectedRule);
-
-std::vector<std::string> listIpRoutes(const char* ipVersion, const char* table);
-
-bool ipRouteExists(const char* ipVersion, const char* table, const std::string& ipRoute);
diff --git a/tests/tun_interface.cpp b/tests/tun_interface.cpp
index e412ffd..65f1528 100644
--- a/tests/tun_interface.cpp
+++ b/tests/tun_interface.cpp
@@ -137,7 +137,7 @@
     timeval timeout = {.tv_usec = 200 * 1000};
     if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == -1) return -errno;
 
-    if (int ret = ifc_add_address(mIfName.c_str(), addr.c_str(), prefixlen)) return ret;
+    if (ifc_add_address(mIfName.c_str(), addr.c_str(), prefixlen)) return -errno;
 
     int family;
     size_t addrlen;
