Move resolver_test.cpp from netd_integration_test to a new resolv_integration_test

1. make resolver_test.cpp as an independent integration test
2. rename libnetd_resolv_test to resolv_unit_test

Test: manually make and run:
      - netd_integration_test
      - resolv_integration_test
      - resolv_unit_test
Test: run runtests.sh, make sure no missing test and get all pass
Test: atest resolv_integration_test
Change-Id: I29a115444d7955c5b6239df80481e29cd3f0e686
diff --git a/tests/Android.bp b/tests/Android.bp
index 5b35fdc..80f5217 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -35,16 +35,10 @@
         ":netd_metrics_aidl",
         "binder_test.cpp",
         "bpf_base_test.cpp",
-        "dns_responder/dns_responder.cpp",
         "netd_test.cpp",
-        "resolver_test.cpp",
         "netlink_listener_test.cpp",
     ],
-    include_dirs: [
-        "system/netd/resolv/include",
-        "system/netd/server",
-        "system/netd/tests/dns_responder",
-    ],
+    include_dirs: ["system/netd/server"],
     shared_libs: [
         "libbase",
         "libbinder",
@@ -60,7 +54,6 @@
     ],
     static_libs: [
         "libcap",
-        "libnetd_test_dnsresponder",
         "libnetd_test_tun_interface",
         "libbpf_android",
         "liblogwrap",
diff --git a/tests/benchmarks/Android.bp b/tests/benchmarks/Android.bp
index d2079c1..afed8d7 100644
--- a/tests/benchmarks/Android.bp
+++ b/tests/benchmarks/Android.bp
@@ -24,7 +24,7 @@
         "system/netd/resolv/include",
         "system/netd/server",
         "system/netd/server/binder",
-        "system/netd/tests/dns_responder",
+        "system/netd/resolv/dns_responder",
     ],
     srcs: [
         ":netd_metrics_aidl",
diff --git a/tests/dns_responder/Android.bp b/tests/dns_responder/Android.bp
deleted file mode 100644
index 727d7c4..0000000
--- a/tests/dns_responder/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-cc_library_static {
-    name: "libnetd_test_dnsresponder",
-    defaults: ["netd_defaults"],
-    cflags: [
-        "-Wunused-parameter",
-        "-Wthread-safety",
-    ],
-    shared_libs: [
-        "libbase",
-        "libbinder",
-        "liblog",
-        "libnetd_client",
-        "libnetdaidl",
-        "libnetdutils",
-        "libssl",
-        "netd_aidl_interface-cpp",
-    ],
-    static_libs: ["libutils"],
-    aidl: {
-        include_dirs: [
-            "frameworks/native/aidl/binder",
-            "system/netd/server/binder",
-        ],
-    },
-    include_dirs: [
-        "system/netd/include",
-        "system/netd/resolv",
-        "system/netd/server",
-        "system/netd/server/binder",
-        "system/netd/tests/dns_responder",
-    ],
-    srcs: [
-        "dns_responder.cpp",
-        "dns_responder_client.cpp",
-        "dns_tls_frontend.cpp",
-    ],
-}
diff --git a/tests/dns_responder/dns_responder.cpp b/tests/dns_responder/dns_responder.cpp
deleted file mode 100644
index 0860142..0000000
--- a/tests/dns_responder/dns_responder.cpp
+++ /dev/null
@@ -1,866 +0,0 @@
-/*
- * 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/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <iostream>
-#include <vector>
-
-#define LOG_TAG "DNSResponder"
-#include <log/log.h>
-#include <netdutils/SocketOption.h>
-
-using android::netdutils::enableSockopt;
-
-namespace test {
-
-std::string errno2str() {
-    char error_msg[512] = { 0 };
-    if (strerror_r(errno, error_msg, sizeof(error_msg)))
-        return std::string();
-    return std::string(error_msg);
-}
-
-#define APLOGI(fmt, ...) ALOGI(fmt ": [%d] %s", __VA_ARGS__, errno, errno2str().c_str())
-
-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;
-    return "unknown";
-}
-
-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;
-}
-
-bool DNSResponder::running() const {
-    return socket_ != -1;
-}
-
-bool DNSResponder::startServer() {
-    if (running()) {
-        ALOGI("server already running");
-        return false;
-    }
-    addrinfo ai_hints{
-        .ai_family = AF_UNSPEC,
-        .ai_socktype = SOCK_DGRAM,
-        .ai_flags = AI_PASSIVE
-    };
-    addrinfo* ai_res;
-    int rv = getaddrinfo(listen_address_.c_str(), listen_service_.c_str(),
-                         &ai_hints, &ai_res);
-    if (rv) {
-        ALOGI("getaddrinfo(%s, %s) failed: %s", listen_address_.c_str(),
-            listen_service_.c_str(), gai_strerror(rv));
-        return false;
-    }
-    int s = -1;
-    for (const addrinfo* ai = ai_res ; ai ; ai = ai->ai_next) {
-        s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-        if (s < 0) continue;
-        enableSockopt(s, SOL_SOCKET, SO_REUSEPORT).ignoreError();
-        enableSockopt(s, SOL_SOCKET, SO_REUSEADDR).ignoreError();
-        if (bind(s, ai->ai_addr, ai->ai_addrlen)) {
-            APLOGI("bind failed for socket %d", s);
-            close(s);
-            s = -1;
-            continue;
-        }
-        std::string host_str = addr2str(ai->ai_addr, ai->ai_addrlen);
-        ALOGI("bound to UDP %s:%s", host_str.c_str(), listen_service_.c_str());
-        break;
-    }
-    freeaddrinfo(ai_res);
-    if (s < 0) {
-        ALOGI("bind() failed");
-        return false;
-    }
-
-    int flags = fcntl(s, F_GETFL, 0);
-    if (flags < 0) flags = 0;
-    if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
-        APLOGI("fcntl(F_SETFL) failed for socket %d", s);
-        close(s);
-        return false;
-    }
-
-    int ep_fd = epoll_create1(EPOLL_CLOEXEC);
-    if (ep_fd < 0) {
-        char error_msg[512] = { 0 };
-        if (strerror_r(errno, error_msg, sizeof(error_msg)))
-            strncpy(error_msg, "UNKNOWN", sizeof(error_msg));
-        APLOGI("epoll_create1() failed: %s", error_msg);
-        close(s);
-        return false;
-    }
-    epoll_event ev;
-    ev.events = EPOLLIN;
-    ev.data.fd = s;
-    if (epoll_ctl(ep_fd, EPOLL_CTL_ADD, s, &ev) < 0) {
-        APLOGI("epoll_ctl() failed for socket %d", s);
-        close(ep_fd);
-        close(s);
-        return false;
-    }
-
-    epoll_fd_ = ep_fd;
-    socket_ = s;
-    {
-        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;
-    }
-    if (terminate_) {
-        ALOGI("LOGIC ERROR");
-        return false;
-    }
-    ALOGI("stopping server");
-    terminate_ = true;
-    handler_thread_.join();
-    close(epoll_fd_);
-    close(socket_);
-    terminate_ = false;
-    socket_ = -1;
-    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[1];
-    while (!terminate_) {
-        int n = epoll_wait(epoll_fd_, evs, 1, poll_timeout_ms_);
-        if (n == 0) continue;
-        if (n < 0) {
-            ALOGI("epoll_wait() failed");
-            // TODO(imaipi): terminate on error.
-            return;
-        }
-        char buffer[4096];
-        sockaddr_storage sa;
-        socklen_t sa_len = sizeof(sa);
-        ssize_t len;
-        do {
-            len = recvfrom(socket_, buffer, sizeof(buffer), 0,
-                           (sockaddr*) &sa, &sa_len);
-        } while (len < 0 && (errno == EAGAIN || errno == EINTR));
-        if (len <= 0) {
-            ALOGI("recvfrom() failed");
-            continue;
-        }
-        ALOGI("read %zd bytes", len);
-        char response[4096];
-        size_t response_len = sizeof(response);
-        if (handleDNSRequest(buffer, len, response, &response_len) &&
-            response_len > 0) {
-            len = sendto(socket_, 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) {
-                ALOGI("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) ALOGI("response is flawed");
-
-        } else {
-            ALOGI("not responding");
-        }
-    }
-}
-
-bool DNSResponder::handleDNSRequest(const char* buffer, ssize_t len,
-                                    char* response, size_t* response_len)
-                                    const {
-    ALOGI("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 (!header.additionals.empty() && fail_on_edns_) {
-        ALOGI("DNS request has an additional section (assumed EDNS). "
-              "Simulating an ancient (pre-EDNS) server.");
-        return makeErrorResponse(&header, ns_rcode::ns_r_formerr, response,
-                                 response_len);
-    }
-    {
-        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 true;
-        } 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_);
-    auto it = mappings_.find(QueryKey(question.qname.name, question.qtype));
-    if (it == mappings_.end()) {
-        // 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;
-    }
-    ALOGI("mapping found for %s %s: %s", question.qname.name.c_str(),
-        dnstype2str(question.qtype), it->second.c_str());
-    DNSRecord record;
-    record.name = question.qname;
-    record.rtype = question.qtype;
-    record.rclass = ns_class::ns_c_in;
-    record.ttl = 5;  // seconds
-    if (question.qtype == ns_type::ns_t_a) {
-        record.rdata.resize(4);
-        if (inet_pton(AF_INET, it->second.c_str(), record.rdata.data()) != 1) {
-            ALOGI("inet_pton(AF_INET, %s) failed", it->second.c_str());
-            return false;
-        }
-    } else if (question.qtype == ns_type::ns_t_aaaa) {
-        record.rdata.resize(16);
-        if (inet_pton(AF_INET6, it->second.c_str(), record.rdata.data()) != 1) {
-            ALOGI("inet_pton(AF_INET6, %s) failed", it->second.c_str());
-            return false;
-        }
-    } else {
-        ALOGI("unhandled qtype %s", dnstype2str(question.qtype));
-        return false;
-    }
-    answers->push_back(std::move(record));
-    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;
-}
-
-}  // namespace test
diff --git a/tests/dns_responder/dns_responder.h b/tests/dns_responder/dns_responder.h
deleted file mode 100644
index e3da72d..0000000
--- a/tests/dns_responder/dns_responder.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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 <mutex>
-#include <string>
-#include <thread>
-#include <unordered_map>
-#include <vector>
-
-#include <android-base/thread_annotations.h>
-
-namespace test {
-
-struct DNSHeader;
-struct DNSQuestion;
-struct DNSRecord;
-
-/*
- * 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, std::string listen_service, int poll_timeout_ms,
-                 ns_rcode error_rcode);
-    ~DNSResponder();
-    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 setFailOnEdns(bool fail) { fail_on_edns_ = fail; }
-    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();
-
-  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);
-        }
-    };
-
-    // DNS request handler.
-    void requestHandler();
-
-    // Parses and generates a response message for incoming DNS requests.
-    // Returns false on parsing errors.
-    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 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;
-
-
-    // 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;
-
-    // If true, behave like an old DNS server that doesn't support EDNS.
-    // Default false.
-    std::atomic<bool> fail_on_edns_ = false;
-
-    // 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.
-    int socket_ = -1;
-    // File descriptor for epoll.
-    int epoll_fd_ = -1;
-    // Signal for request handler termination.
-    std::atomic<bool> terminate_ = false;
-    // Thread for handling incoming threads.
-    std::thread handler_thread_ GUARDED_BY(update_mutex_);
-    std::mutex update_mutex_;
-};
-
-}  // namespace test
-
-#endif  // DNS_RESPONDER_H
diff --git a/tests/dns_responder/dns_responder_client.cpp b/tests/dns_responder/dns_responder_client.cpp
deleted file mode 100644
index efc6d8e..0000000
--- a/tests/dns_responder/dns_responder_client.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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/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;
-
-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;
-        }
-    }
-}
-
-bool DnsResponderClient::SetResolversForNetwork(const std::vector<std::string>& servers,
-        const std::vector<std::string>& domains, const std::vector<int>& params) {
-    const auto rv = mNetdSrv->setResolverConfiguration(TEST_NETID, servers, domains, params,
-            "", {}, {});
-    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 rv = mNetdSrv->setResolverConfiguration(TEST_NETID, servers, domains, params,
-            name, tlsServers, fingerprints);
-    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();
-    }
-}
-
-void DnsResponderClient::ShutdownDNSServers(std::vector<std::unique_ptr<test::DNSResponder>>* dns) {
-    for (const auto& d : *dns) {
-        d->stopServer();
-    }
-    dns->clear();
-}
-
-int DnsResponderClient::SetupOemNetwork() {
-    mNetdSrv->networkDestroy(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;
-    }
-    int oemNetId = TEST_NETID;
-    setNetworkForProcess(oemNetId);
-    if ((unsigned) oemNetId != getNetworkForProcess()) {
-        return -1;
-    }
-    return oemNetId;
-}
-
-void DnsResponderClient::TearDownOemNetwork(int oemNetId) {
-    if (oemNetId != -1) {
-        mNetdSrv->networkDestroy(oemNetId);
-    }
-}
-
-void DnsResponderClient::SetUp() {
-    // binder setup
-    auto binder = android::defaultServiceManager()->getService(android::String16("netd"));
-    mNetdSrv = android::interface_cast<android::net::INetd>(binder);
-
-    // Ensure resolutions go via proxy.
-    setenv(ANDROID_DNS_MODE, "", 1);
-    mOemNetId = SetupOemNetwork();
-}
-
-void DnsResponderClient::TearDown() {
-    TearDownOemNetwork(mOemNetId);
-}
diff --git a/tests/dns_responder/dns_responder_client.h b/tests/dns_responder/dns_responder_client.h
deleted file mode 100644
index c03c1b5..0000000
--- a/tests/dns_responder/dns_responder_client.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#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 "android/net/INetd.h"
-#include "binder/IServiceManager.h"
-#include "NetdClient.h"
-#include "dns_responder.h"
-
-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,
-            const std::vector<std::string>& domains, const std::vector<int>& params);
-
-    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);
-
-    static void ShutdownDNSServers(std::vector<std::unique_ptr<test::DNSResponder>>* dns);
-
-    int SetupOemNetwork();
-
-    void TearDownOemNetwork(int oemNetId);
-
-    virtual void SetUp();
-
-    virtual void TearDown();
-
-public:
-    android::sp<android::net::INetd> mNetdSrv = nullptr;
-    int mOemNetId = -1;
-};
-
-#endif  // DNS_RESPONDER_CLIENT_H
diff --git a/tests/dns_responder/dns_tls_frontend.cpp b/tests/dns_responder/dns_tls_frontend.cpp
deleted file mode 100644
index 443fb8f..0000000
--- a/tests/dns_responder/dns_tls_frontend.cpp
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * 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 <netdb.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/poll.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/ssl.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 };
-    if (strerror_r(errno, error_msg, sizeof(error_msg)))
-        return std::string();
-    return std::string(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;
-    int rv = getaddrinfo(listen_address_.c_str(), listen_service_.c_str(),
-                         &frontend_ai_hints, &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;
-    }
-
-    int s = -1;
-    for (const addrinfo* ai = frontend_ai_res ; ai ; ai = ai->ai_next) {
-        s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-        if (s < 0) continue;
-        enableSockopt(s, SOL_SOCKET, SO_REUSEPORT).ignoreError();
-        enableSockopt(s, SOL_SOCKET, SO_REUSEADDR).ignoreError();
-        if (bind(s, ai->ai_addr, ai->ai_addrlen)) {
-            APLOGI("bind failed for socket %d", s);
-            close(s);
-            s = -1;
-            continue;
-        }
-        std::string host_str = addr2str(ai->ai_addr, ai->ai_addrlen);
-        ALOGI("bound to TCP %s:%s", host_str.c_str(), listen_service_.c_str());
-        break;
-    }
-    freeaddrinfo(frontend_ai_res);
-    if (s < 0) {
-        ALOGE("server socket creation failed");
-        return false;
-    }
-
-    if (listen(s, 1) < 0) {
-        ALOGE("listen failed");
-        return false;
-    }
-
-    socket_ = s;
-
-    // Set up UDP client socket to backend.
-    addrinfo backend_ai_hints{
-        .ai_family = AF_UNSPEC,
-        .ai_socktype = SOCK_DGRAM
-    };
-    addrinfo* backend_ai_res;
-    rv = getaddrinfo(backend_address_.c_str(), backend_service_.c_str(),
-                         &backend_ai_hints, &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_ = socket(backend_ai_res->ai_family, backend_ai_res->ai_socktype,
-        backend_ai_res->ai_protocol);
-    if (backend_socket_ < 0) {
-        ALOGE("backend socket creation failed");
-        return false;
-    }
-    connect(backend_socket_, backend_ai_res->ai_addr, backend_ai_res->ai_addrlen);
-    freeaddrinfo(backend_ai_res);
-
-    {
-        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");
-    struct pollfd fds[1] = {{ .fd = socket_, .events = POLLIN }};
-
-    while (!terminate_) {
-        int poll_code = poll(fds, 1, 10 /* ms */);
-        if (poll_code == 0) {
-            // Timeout.  Poll again.
-            continue;
-        } else if (poll_code < 0) {
-            ALOGW("Poll failed with error %d", poll_code);
-            // Error.
-            break;
-        }
-        sockaddr_storage addr;
-        socklen_t len = sizeof(addr);
-
-        ALOGD("Trying to accept a client");
-        int client = accept4(socket_, reinterpret_cast<sockaddr*>(&addr), &len, SOCK_CLOEXEC);
-        ALOGD("Got client socket %d", client);
-        if (client < 0) {
-            // Stop
-            break;
-        }
-
-        bssl::UniquePtr<SSL> ssl(SSL_new(ctx_.get()));
-        SSL_set_fd(ssl.get(), client);
-
-        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());
-        }
-
-        close(client);
-
-        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("Request handler terminating");
-}
-
-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_, 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_, 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;
-    }
-    if (terminate_) {
-        ALOGI("LOGIC ERROR");
-        return false;
-    }
-    ALOGI("stopping frontend");
-    terminate_ = true;
-    handler_thread_.join();
-    close(socket_);
-    close(backend_socket_);
-    terminate_ = false;
-    socket_ = -1;
-    backend_socket_ = -1;
-    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;
-}
-
-}  // namespace test
diff --git a/tests/dns_responder/dns_tls_frontend.h b/tests/dns_responder/dns_tls_frontend.h
deleted file mode 100644
index b4630cf..0000000
--- a/tests/dns_responder/dns_tls_frontend.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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 <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),
-            queries_(0), terminate_(false) { }
-    ~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_; }
-    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);
-
-    std::string listen_address_;
-    std::string listen_service_;
-    std::string backend_address_;
-    std::string backend_service_;
-    bssl::UniquePtr<SSL_CTX> ctx_;
-    int socket_ = -1;
-    int backend_socket_ = -1;
-    std::atomic<int> queries_;
-    std::atomic<bool> terminate_;
-    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/tests/resolver_test.cpp b/tests/resolver_test.cpp
deleted file mode 100644
index 5196bba..0000000
--- a/tests/resolver_test.cpp
+++ /dev/null
@@ -1,1460 +0,0 @@
-/*
- * 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 "netd_test"
-
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <chrono>
-#include <iterator>
-#include <numeric>
-#include <thread>
-
-#include <android-base/stringprintf.h>
-#include <cutils/sockets.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.h"
-#include "dns_responder_client.h"
-#include "dns_tls_frontend.h"
-
-#include "NetdConstants.h"
-#include "ResolverStats.h"
-
-#include "android/net/INetd.h"
-#include "android/net/metrics/INetdEventListener.h"
-#include "binder/IServiceManager.h"
-#include "netdutils/SocketOption.h"
-
-// TODO: make this dynamic and stop depending on implementation details.
-#define TEST_NETID 30
-
-// 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::StringPrintf;
-using android::net::ResolverStats;
-using android::net::metrics::INetdEventListener;
-using android::netdutils::enableSockopt;
-
-// 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
-
-// Emulates the behavior of UnorderedElementsAreArray, which currently cannot be used.
-// TODO: Use UnorderedElementsAreArray, which depends on being able to compile libgmock_host,
-// if that is not possible, improve this hacky algorithm, which is O(n**2)
-template <class A, class B>
-bool UnorderedCompareArray(const A& a, const B& b) {
-    if (a.size() != b.size()) return false;
-    for (const auto& a_elem : a) {
-        size_t a_count = 0;
-        for (const auto& a_elem2 : a) {
-            if (a_elem == a_elem2) {
-                ++a_count;
-            }
-        }
-        size_t b_count = 0;
-        for (const auto& b_elem : b) {
-            if (a_elem == b_elem) ++b_count;
-        }
-        if (a_count != b_count) return false;
-    }
-    return true;
-}
-
-class ResolverTest : public ::testing::Test, public DnsResponderClient {
-  protected:
-    void SetUp() {
-        // Ensure resolutions go via proxy.
-        DnsResponderClient::SetUp();
-
-        // If DNS reporting is off: turn it on so we run through everything.
-        auto rv = mNetdSrv->getMetricsReportingLevel(&mOriginalMetricsLevel);
-        ASSERT_TRUE(rv.isOk());
-        if (mOriginalMetricsLevel != INetdEventListener::REPORTING_LEVEL_FULL) {
-            rv = mNetdSrv->setMetricsReportingLevel(INetdEventListener::REPORTING_LEVEL_FULL);
-            ASSERT_TRUE(rv.isOk());
-        }
-    }
-
-    void TearDown() {
-        if (mOriginalMetricsLevel != INetdEventListener::REPORTING_LEVEL_FULL) {
-            auto rv = mNetdSrv->setMetricsReportingLevel(mOriginalMetricsLevel);
-            ASSERT_TRUE(rv.isOk());
-        }
-
-        DnsResponderClient::TearDown();
-    }
-
-    bool GetResolverInfo(std::vector<std::string>* servers, std::vector<std::string>* domains,
-            __res_params* params, std::vector<ResolverStats>* stats) {
-        using android::net::INetd;
-        std::vector<int32_t> params32;
-        std::vector<int32_t> stats32;
-        auto rv = mNetdSrv->getResolverInfo(TEST_NETID, servers, domains, &params32, &stats32);
-        if (!rv.isOk() || params32.size() != INetd::RESOLVER_PARAMS_COUNT) {
-            return false;
-        }
-        *params = __res_params {
-            .sample_validity = static_cast<uint16_t>(
-                    params32[INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY]),
-            .success_threshold = static_cast<uint8_t>(
-                    params32[INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD]),
-            .min_samples = static_cast<uint8_t>(
-                    params32[INetd::RESOLVER_PARAMS_MIN_SAMPLES]),
-            .max_samples = static_cast<uint8_t>(
-                    params32[INetd::RESOLVER_PARAMS_MAX_SAMPLES]),
-            .base_timeout_msec = params32[INetd::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
-        };
-        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()); }
-
-    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;
-    }
-
-    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::Mapping> mappings;
-        ASSERT_NO_FATAL_FAILURE(SetupMappings(num_hosts, domains, &mappings));
-        ASSERT_NO_FATAL_FAILURE(SetupDNSServers(MAXNS, mappings, &dns, &servers));
-
-        ASSERT_TRUE(SetResolversForNetwork(servers, domains, mDefaultParams_Binder));
-
-        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());
-        ASSERT_NO_FATAL_FAILURE(ShutdownDNSServers(&dns));
-    }
-
-    const std::vector<std::string> mDefaultSearchDomains = { "example.com" };
-    // <sample validity in s> <success threshold in percent> <min samples> <max samples>
-    const std::vector<int> mDefaultParams_Binder = {
-            300,     // SAMPLE_VALIDITY
-            25,      // SUCCESS_THRESHOLD
-            8,   8,  // {MIN,MAX}_SAMPLES
-            100,     // BASE_TIMEOUT_MSEC
-    };
-
-  private:
-    int mOriginalMetricsLevel;
-};
-
-TEST_F(ResolverTest, GetHostByName) {
-    const char* listen_addr = "127.0.0.3";
-    const char* listen_srv = "53";
-    const char* host_name = "hello.example.com.";
-    const char *nonexistent_host_name = "nonexistent.example.com.";
-    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.3");
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = { listen_addr };
-    ASSERT_TRUE(SetResolversForNetwork(servers, mDefaultSearchDomains, mDefaultParams_Binder));
-
-    const hostent* result;
-
-    dns.clearQueries();
-    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, 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);
-
-    dns.stopServer();
-}
-
-TEST_F(ResolverTest, GetHostByName_localhost) {
-    constexpr char name[] = "localhost";
-    constexpr char name_camelcase[] = "LocalHost";
-    constexpr char addr[] = "127.0.0.1";
-    constexpr char name_ip6[] = "ip6-localhost";
-    constexpr char addr_ip6[] = "::1";
-    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
-    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);
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = {listen_addr};
-    ASSERT_TRUE(SetResolversForNetwork(servers, mDefaultSearchDomains, mDefaultParams_Binder));
-    dns.clearQueries();
-
-    // Expect no DNS queries; localhost is resolved via /etc/hosts
-    const hostent* result = gethostbyname(name);
-    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(addr, 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(addr, 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(name_ip6);
-    EXPECT_EQ(2, dns.queries().size()) << dns.dumpQueries();
-    EXPECT_EQ(1, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_dot)) << dns.dumpQueries();
-    EXPECT_EQ(1, 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(name_ip6, 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(addr_ip6, ToString(result));
-    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
-
-    dns.stopServer();
-}
-
-TEST_F(ResolverTest, GetHostByName_numeric) {
-    // Add a dummy nameserver which shouldn't receive any queries
-    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);
-    ASSERT_TRUE(dns.startServer());
-    ASSERT_TRUE(
-            SetResolversForNetwork({listen_addr}, mDefaultSearchDomains, mDefaultParams_Binder));
-
-    // Numeric v4 address: expect no DNS queries
-    constexpr char numeric_v4[] = "192.168.0.1";
-    dns.clearQueries();
-    const hostent* result = gethostbyname(numeric_v4);
-    EXPECT_EQ(0, 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(0, 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(0, 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(2, dns.queries().size());  // OUCH!
-    ASSERT_TRUE(result == nullptr);
-
-    dns.stopServer();
-}
-
-TEST_F(ResolverTest, BinderSerialization) {
-    using android::net::INetd;
-    std::vector<int> params_offsets = {
-        INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY,
-        INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD,
-        INetd::RESOLVER_PARAMS_MIN_SAMPLES,
-        INetd::RESOLVER_PARAMS_MAX_SAMPLES,
-        INetd::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC,
-    };
-    int size = static_cast<int>(params_offsets.size());
-    EXPECT_EQ(size, INetd::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::INetd;
-
-    std::vector<std::string> domains = { "example.com" };
-    std::vector<std::unique_ptr<test::DNSResponder>> dns;
-    std::vector<std::string> servers;
-    std::vector<Mapping> mappings;
-    ASSERT_NO_FATAL_FAILURE(SetupMappings(1, domains, &mappings));
-    ASSERT_NO_FATAL_FAILURE(SetupDNSServers(4, mappings, &dns, &servers));
-    ASSERT_EQ(1U, mappings.size());
-    const Mapping& mapping = mappings[0];
-
-    ASSERT_TRUE(SetResolversForNetwork(servers, domains, mDefaultParams_Binder));
-
-    const hostent* result = gethostbyname(mapping.host.c_str());
-    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;
-    __res_params res_params;
-    std::vector<ResolverStats> res_stats;
-    ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_params, &res_stats));
-    EXPECT_EQ(servers.size(), res_servers.size());
-    EXPECT_EQ(domains.size(), res_domains.size());
-    ASSERT_EQ(INetd::RESOLVER_PARAMS_COUNT, mDefaultParams_Binder.size());
-    EXPECT_EQ(mDefaultParams_Binder[INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY],
-            res_params.sample_validity);
-    EXPECT_EQ(mDefaultParams_Binder[INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
-            res_params.success_threshold);
-    EXPECT_EQ(mDefaultParams_Binder[INetd::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
-    EXPECT_EQ(mDefaultParams_Binder[INetd::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
-    EXPECT_EQ(mDefaultParams_Binder[INetd::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
-              res_params.base_timeout_msec);
-    EXPECT_EQ(servers.size(), res_stats.size());
-
-    EXPECT_TRUE(UnorderedCompareArray(res_servers, servers));
-    EXPECT_TRUE(UnorderedCompareArray(res_domains, domains));
-
-    ASSERT_NO_FATAL_FAILURE(ShutdownDNSServers(&dns));
-}
-
-TEST_F(ResolverTest, GetAddrInfo) {
-    const char* listen_addr = "127.0.0.4";
-    const char* listen_addr2 = "127.0.0.5";
-    const char* listen_srv = "53";
-    const char* host_name = "howdy.example.com.";
-    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
-    dns.addMapping(host_name, ns_type::ns_t_aaaa, "::1.2.3.4");
-    ASSERT_TRUE(dns.startServer());
-
-    test::DNSResponder dns2(listen_addr2, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns2.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
-    dns2.addMapping(host_name, ns_type::ns_t_aaaa, "::1.2.3.4");
-    ASSERT_TRUE(dns2.startServer());
-
-    std::vector<std::string> servers = { listen_addr };
-    ASSERT_TRUE(SetResolversForNetwork(servers, mDefaultSearchDomains, mDefaultParams_Binder));
-    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.
-    servers = { listen_addr2 };
-    ASSERT_TRUE(SetResolversForNetwork(servers, mDefaultSearchDomains, mDefaultParams_Binder));
-    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 << "'";
-
-    dns.stopServer();
-    dns2.stopServer();
-}
-
-TEST_F(ResolverTest, GetAddrInfoV4) {
-    constexpr char listen_addr[] = "127.0.0.5";
-    constexpr char listen_srv[] = "53";
-    constexpr char host_name[] = "hola.example.com.";
-    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.5");
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = { listen_addr };
-    ASSERT_TRUE(SetResolversForNetwork(servers, mDefaultSearchDomains, mDefaultParams_Binder));
-
-    addrinfo hints = {.ai_family = AF_INET};
-    ScopedAddrinfo result = safe_getaddrinfo("hola", nullptr, &hints);
-    EXPECT_TRUE(result != nullptr);
-    EXPECT_EQ(1U, GetNumQueries(dns, host_name));
-    EXPECT_EQ("1.2.3.5", ToString(result));
-}
-
-TEST_F(ResolverTest, GetAddrInfo_localhost) {
-    constexpr char name[] = "localhost";
-    constexpr char addr[] = "127.0.0.1";
-    constexpr char name_ip6[] = "ip6-localhost";
-    constexpr char addr_ip6[] = "::1";
-
-    // Add a dummy nameserver which shouldn't receive any queries
-    constexpr char listen_addr[] = "127.0.0.5";
-    constexpr char listen_srv[] = "53";
-    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = {listen_addr};
-    ASSERT_TRUE(SetResolversForNetwork(servers, mDefaultSearchDomains, mDefaultParams_Binder));
-
-    ScopedAddrinfo result = safe_getaddrinfo(name, 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(addr, ToString(result));
-
-    result = safe_getaddrinfo(name_ip6, 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(addr_ip6, ToString(result));
-}
-
-TEST_F(ResolverTest, GetHostByNameBrokenEdns) {
-    const char* listen_addr = "127.0.0.3";
-    const char* listen_srv = "53";
-    const char* host_name = "edns.example.com.";
-    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.3");
-    dns.setFailOnEdns(true);  // This is the only change from the basic test.
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = { listen_addr };
-    ASSERT_TRUE(SetResolversForNetwork(servers, mDefaultSearchDomains, mDefaultParams_Binder));
-
-    const hostent* result;
-
-    dns.clearQueries();
-    result = gethostbyname("edns");
-    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, GetAddrInfoBrokenEdns) {
-    const char* listen_addr = "127.0.0.5";
-    const char* listen_srv = "53";
-    const char* host_name = "edns2.example.com.";
-    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.5");
-    dns.setFailOnEdns(true);  // This is the only change from the basic test.
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = { listen_addr };
-    ASSERT_TRUE(SetResolversForNetwork(servers, mDefaultSearchDomains, mDefaultParams_Binder));
-
-    addrinfo hints = {.ai_family = AF_INET};
-    ScopedAddrinfo result = safe_getaddrinfo("edns2", nullptr, &hints);
-    EXPECT_TRUE(result != nullptr);
-    EXPECT_EQ(1U, GetNumQueries(dns, host_name));
-    EXPECT_EQ("1.2.3.5", ToString(result));
-}
-
-TEST_F(ResolverTest, MultidomainResolution) {
-    std::vector<std::string> searchDomains = { "example1.com", "example2.com", "example3.com" };
-    const char* listen_addr = "127.0.0.6";
-    const char* listen_srv = "53";
-    const char* host_name = "nihao.example2.com.";
-    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.3");
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = { listen_addr };
-    ASSERT_TRUE(SetResolversForNetwork(servers, searchDomains, mDefaultParams_Binder));
-
-    dns.clearQueries();
-    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);
-    dns.stopServer();
-}
-
-TEST_F(ResolverTest, GetAddrInfoV6_numeric) {
-    constexpr char listen_addr0[] = "127.0.0.7";
-    constexpr char listen_srv[] = "53";
-    constexpr char host_name[] = "ohayou.example.com.";
-    constexpr char numeric_addr[] = "fe80::1%lo";
-
-    test::DNSResponder dns(listen_addr0, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns.setResponseProbability(0.0);
-    dns.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::5");
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = {listen_addr0};
-    ASSERT_TRUE(SetResolversForNetwork(servers, mDefaultSearchDomains, mDefaultParams_Binder));
-
-    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) {
-    const char* listen_addr0 = "127.0.0.7";
-    const char* listen_addr1 = "127.0.0.8";
-    const char* listen_srv = "53";
-    const char* host_name = "ohayou.example.com.";
-    test::DNSResponder dns0(listen_addr0, listen_srv, 250, ns_rcode::ns_r_servfail);
-    test::DNSResponder dns1(listen_addr1, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns0.setResponseProbability(0.0);
-    dns0.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::5");
-    dns1.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::6");
-    ASSERT_TRUE(dns0.startServer());
-    ASSERT_TRUE(dns1.startServer());
-    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(SetResolversForNetwork(servers, mDefaultSearchDomains, 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.
-    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) {
-    const char* listen_addr0 = "127.0.0.7";
-    const char* listen_addr1 = "127.0.0.8";
-    const char* listen_srv = "53";
-    const char* host_name1 = "ohayou.example.com.";
-    const char* host_name2 = "ciao.example.com.";
-
-    // 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);
-    dns0.addMapping(host_name1, ns_type::ns_t_aaaa, "2001:db8::5");
-    dns1.addMapping(host_name1, ns_type::ns_t_aaaa, "2001:db8::6");
-    dns0.addMapping(host_name2, ns_type::ns_t_aaaa, "2001:db8::5");
-    dns1.addMapping(host_name2, ns_type::ns_t_aaaa, "2001:db8::6");
-    ASSERT_TRUE(dns0.startServer());
-    ASSERT_TRUE(dns1.startServer());
-    std::vector<std::string> servers = {listen_addr0, listen_addr1};
-    ASSERT_TRUE(SetResolversForNetwork(servers, mDefaultSearchDomains, mDefaultParams_Binder));
-
-    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) {
-    const char* listen_addr0 = "127.0.0.9";
-    const char* listen_addr1 = "127.0.0.10";
-    const char* listen_addr2 = "127.0.0.11";
-    const char* listen_srv = "53";
-    const char* host_name = "konbanha.example.com.";
-    test::DNSResponder dns0(listen_addr0, listen_srv, 250, ns_rcode::ns_r_servfail);
-    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);
-    dns0.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::5");
-    dns1.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::6");
-    dns2.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::7");
-    ASSERT_TRUE(dns0.startServer());
-    ASSERT_TRUE(dns1.startServer());
-    ASSERT_TRUE(dns2.startServer());
-    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(SetResolversForNetwork(serverSubset, mDefaultSearchDomains,
-                    mDefaultParams_Binder));
-            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();
-    }
-}
-
-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::INetd;
-    std::vector<std::string> servers;
-    std::vector<std::string> domains;
-    ASSERT_TRUE(SetResolversForNetwork(servers, domains, mDefaultParams_Binder));
-    std::vector<std::string> res_servers;
-    std::vector<std::string> res_domains;
-    __res_params res_params;
-    std::vector<ResolverStats> res_stats;
-    ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_params, &res_stats));
-    EXPECT_EQ(0U, res_servers.size());
-    EXPECT_EQ(0U, res_domains.size());
-    ASSERT_EQ(INetd::RESOLVER_PARAMS_COUNT, mDefaultParams_Binder.size());
-    EXPECT_EQ(mDefaultParams_Binder[INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY],
-            res_params.sample_validity);
-    EXPECT_EQ(mDefaultParams_Binder[INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
-            res_params.success_threshold);
-    EXPECT_EQ(mDefaultParams_Binder[INetd::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
-    EXPECT_EQ(mDefaultParams_Binder[INetd::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
-    EXPECT_EQ(mDefaultParams_Binder[INetd::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
-              res_params.base_timeout_msec);
-}
-
-TEST_F(ResolverTest, SearchPathChange) {
-    const char* listen_addr = "127.0.0.13";
-    const char* listen_srv = "53";
-    const char* host_name1 = "test13.domain1.org.";
-    const char* host_name2 = "test13.domain2.org.";
-    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name1, ns_type::ns_t_aaaa, "2001:db8::13");
-    dns.addMapping(host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13");
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = { listen_addr };
-    std::vector<std::string> domains = { "domain1.org" };
-    ASSERT_TRUE(SetResolversForNetwork(servers, domains, mDefaultParams_Binder));
-
-    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(SetResolversForNetwork(servers, domains, mDefaultParams_Binder));
-    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));
-}
-
-TEST_F(ResolverTest, MaxServerPrune_Binder) {
-    using android::net::INetd;
-
-    std::vector<std::string> domains = { "example.com" };
-    std::vector<std::unique_ptr<test::DNSResponder>> dns;
-    std::vector<std::string> servers;
-    std::vector<Mapping> mappings;
-    ASSERT_NO_FATAL_FAILURE(SetupMappings(1, domains, &mappings));
-    ASSERT_NO_FATAL_FAILURE(SetupDNSServers(MAXNS + 1, mappings, &dns, &servers));
-
-    ASSERT_TRUE(SetResolversForNetwork(servers, domains,  mDefaultParams_Binder));
-
-    std::vector<std::string> res_servers;
-    std::vector<std::string> res_domains;
-    __res_params res_params;
-    std::vector<ResolverStats> res_stats;
-    ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_params, &res_stats));
-    EXPECT_EQ(static_cast<size_t>(MAXNS), res_servers.size());
-
-    ASSERT_NO_FATAL_FAILURE(ShutdownDNSServers(&dns));
-}
-
-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));
-}
-
-// Test what happens if the specified TLS server is nonexistent.
-TEST_F(ResolverTest, GetHostByName_TlsMissing) {
-    const char* listen_addr = "127.0.0.3";
-    const char* listen_srv = "53";
-    const char* host_name = "tlsmissing.example.com.";
-    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.3");
-    ASSERT_TRUE(dns.startServer());
-    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(SetResolversWithTls(servers, mDefaultSearchDomains, mDefaultParams_Binder, "", {}));
-
-    const hostent* result;
-
-    result = gethostbyname("tlsmissing");
-    ASSERT_FALSE(result == nullptr);
-    EXPECT_EQ("1.2.3.3", ToString(result));
-
-    // Clear TLS bit.
-    ASSERT_TRUE(SetResolversForNetwork(servers, mDefaultSearchDomains,  mDefaultParams_Binder));
-    dns.stopServer();
-}
-
-// Test what happens if the specified TLS server replies with garbage.
-TEST_F(ResolverTest, GetHostByName_TlsBroken) {
-    const char* listen_addr = "127.0.0.3";
-    const char* listen_srv = "53";
-    const char* host_name1 = "tlsbroken1.example.com.";
-    const char* host_name2 = "tlsbroken2.example.com.";
-    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name1, ns_type::ns_t_a, "1.2.3.1");
-    dns.addMapping(host_name2, ns_type::ns_t_a, "1.2.3.2");
-    ASSERT_TRUE(dns.startServer());
-    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(SetResolversWithTls(servers, mDefaultSearchDomains, mDefaultParams_Binder, "", {}));
-
-    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(SetResolversForNetwork(servers, mDefaultSearchDomains,  mDefaultParams_Binder));
-    dns.stopServer();
-    close(s);
-}
-
-TEST_F(ResolverTest, GetHostByName_Tls) {
-    const char* listen_addr = "127.0.0.3";
-    const char* listen_udp = "53";
-    const char* listen_tls = "853";
-    const char* host_name1 = "tls1.example.com.";
-    const char* host_name2 = "tls2.example.com.";
-    const char* host_name3 = "tls3.example.com.";
-    test::DNSResponder dns(listen_addr, listen_udp, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name1, ns_type::ns_t_a, "1.2.3.1");
-    dns.addMapping(host_name2, ns_type::ns_t_a, "1.2.3.2");
-    dns.addMapping(host_name3, ns_type::ns_t_a, "1.2.3.3");
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = { listen_addr };
-
-    test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
-    ASSERT_TRUE(tls.startServer());
-    ASSERT_TRUE(SetResolversWithTls(servers, mDefaultSearchDomains, mDefaultParams_Binder, "", {}));
-
-    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(SetResolversForNetwork(servers, mDefaultSearchDomains, mDefaultParams_Binder));
-
-    result = gethostbyname("tls3");
-    ASSERT_FALSE(result == nullptr);
-    EXPECT_EQ("1.2.3.3", ToString(result));
-
-    dns.stopServer();
-}
-
-TEST_F(ResolverTest, GetHostByName_TlsFingerprint) {
-    const char* listen_addr = "127.0.0.3";
-    const char* listen_udp = "53";
-    const char* listen_tls = "853";
-    test::DNSResponder dns(listen_addr, listen_udp, 250, ns_rcode::ns_r_servfail);
-    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(SetResolversWithTls(servers, mDefaultSearchDomains, mDefaultParams_Binder, "",
-                { 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(SetResolversForNetwork(servers, mDefaultSearchDomains,  mDefaultParams_Binder));
-        tls.stopServer();
-    }
-    dns.stopServer();
-}
-
-TEST_F(ResolverTest, GetHostByName_BadTlsFingerprint) {
-    const char* listen_addr = "127.0.0.3";
-    const char* listen_udp = "53";
-    const char* listen_tls = "853";
-    const char* host_name = "badtlsfingerprint.example.com.";
-    test::DNSResponder dns(listen_addr, listen_udp, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.1");
-    ASSERT_TRUE(dns.startServer());
-    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(SetResolversWithTls(servers, mDefaultSearchDomains, mDefaultParams_Binder, "",
-            { 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(SetResolversForNetwork(servers, mDefaultSearchDomains,  mDefaultParams_Binder));
-    tls.stopServer();
-    dns.stopServer();
-}
-
-// 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) {
-    const char* listen_addr = "127.0.0.3";
-    const char* listen_udp = "53";
-    const char* listen_tls = "853";
-    const char* host_name = "twotlsfingerprints.example.com.";
-    test::DNSResponder dns(listen_addr, listen_udp, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.1");
-    ASSERT_TRUE(dns.startServer());
-    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(SetResolversWithTls(servers, mDefaultSearchDomains, mDefaultParams_Binder, "",
-            { 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(SetResolversForNetwork(servers, mDefaultSearchDomains,  mDefaultParams_Binder));
-    tls.stopServer();
-    dns.stopServer();
-}
-
-TEST_F(ResolverTest, GetHostByName_TlsFingerprintGoesBad) {
-    const char* listen_addr = "127.0.0.3";
-    const char* listen_udp = "53";
-    const char* listen_tls = "853";
-    const char* host_name1 = "tlsfingerprintgoesbad1.example.com.";
-    const char* host_name2 = "tlsfingerprintgoesbad2.example.com.";
-    test::DNSResponder dns(listen_addr, listen_udp, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name1, ns_type::ns_t_a, "1.2.3.1");
-    dns.addMapping(host_name2, ns_type::ns_t_a, "1.2.3.2");
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = { listen_addr };
-
-    test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
-    ASSERT_TRUE(tls.startServer());
-    ASSERT_TRUE(SetResolversWithTls(servers, mDefaultSearchDomains, mDefaultParams_Binder, "",
-            { 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(SetResolversForNetwork(servers, mDefaultSearchDomains,  mDefaultParams_Binder));
-    tls.stopServer();
-    dns.stopServer();
-}
-
-TEST_F(ResolverTest, GetHostByName_TlsFailover) {
-    const char* listen_addr1 = "127.0.0.3";
-    const char* listen_addr2 = "127.0.0.4";
-    const char* listen_udp = "53";
-    const char* listen_tls = "853";
-    const char* host_name1 = "tlsfailover1.example.com.";
-    const char* host_name2 = "tlsfailover2.example.com.";
-    test::DNSResponder dns1(listen_addr1, listen_udp, 250, ns_rcode::ns_r_servfail);
-    test::DNSResponder dns2(listen_addr2, listen_udp, 250, ns_rcode::ns_r_servfail);
-    dns1.addMapping(host_name1, ns_type::ns_t_a, "1.2.3.1");
-    dns1.addMapping(host_name2, ns_type::ns_t_a, "1.2.3.2");
-    dns2.addMapping(host_name1, ns_type::ns_t_a, "1.2.3.3");
-    dns2.addMapping(host_name2, ns_type::ns_t_a, "1.2.3.4");
-    ASSERT_TRUE(dns1.startServer());
-    ASSERT_TRUE(dns2.startServer());
-    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(SetResolversWithTls(servers, mDefaultSearchDomains, mDefaultParams_Binder, "",
-            { 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(SetResolversForNetwork(servers, mDefaultSearchDomains,  mDefaultParams_Binder));
-    tls2.stopServer();
-    dns1.stopServer();
-    dns2.stopServer();
-}
-
-TEST_F(ResolverTest, GetHostByName_BadTlsName) {
-    const char* listen_addr = "127.0.0.3";
-    const char* listen_udp = "53";
-    const char* listen_tls = "853";
-    const char* host_name = "badtlsname.example.com.";
-    test::DNSResponder dns(listen_addr, listen_udp, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.1");
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = { listen_addr };
-
-    test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
-    ASSERT_TRUE(tls.startServer());
-    ASSERT_TRUE(SetResolversWithTls(servers, mDefaultSearchDomains, mDefaultParams_Binder,
-            "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(SetResolversForNetwork(servers, mDefaultSearchDomains,  mDefaultParams_Binder));
-    tls.stopServer();
-    dns.stopServer();
-}
-
-TEST_F(ResolverTest, GetAddrInfo_Tls) {
-    const char* listen_addr = "127.0.0.3";
-    const char* listen_udp = "53";
-    const char* listen_tls = "853";
-    const char* host_name = "addrinfotls.example.com.";
-    test::DNSResponder dns(listen_addr, listen_udp, 250, ns_rcode::ns_r_servfail);
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
-    dns.addMapping(host_name, ns_type::ns_t_aaaa, "::1.2.3.4");
-    ASSERT_TRUE(dns.startServer());
-    std::vector<std::string> servers = { listen_addr };
-
-    test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
-    ASSERT_TRUE(tls.startServer());
-    ASSERT_TRUE(SetResolversWithTls(servers, mDefaultSearchDomains, mDefaultParams_Binder, "",
-            { 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(SetResolversForNetwork(servers, mDefaultSearchDomains,  mDefaultParams_Binder));
-    tls.stopServer();
-    dns.stopServer();
-}
-
-TEST_F(ResolverTest, TlsBypass) {
-    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, cleartext_port, 250, ns_rcode::ns_r_servfail);
-    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(SetResolversForNetwork(
-                    servers, mDefaultSearchDomains,  mDefaultParams_Binder));
-        } else if (config.mode == OPPORTUNISTIC) {
-            ASSERT_TRUE(SetResolversWithTls(
-                    servers, mDefaultSearchDomains, mDefaultParams_Binder, "", {}));
-            // 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(SetResolversWithTls(
-                    servers, mDefaultSearchDomains, mDefaultParams_Binder, "",
-                    { 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();
-    }
-
-    dns.stopServer();
-}
-
-TEST_F(ResolverTest, StrictMode_NoTlsServers) {
-    const std::vector<uint8_t> NOOP_FINGERPRINT(SHA256_SIZE, 0U);
-    const char cleartext_addr[] = "127.0.0.53";
-    const char cleartext_port[] = "53";
-    const std::vector<std::string> servers = { cleartext_addr };
-
-    test::DNSResponder dns(cleartext_addr, cleartext_port, 250, ns_rcode::ns_r_servfail);
-    const char* host_name = "strictmode.notlsips.example.com.";
-    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
-    dns.addMapping(host_name, ns_type::ns_t_aaaa, "::1.2.3.4");
-    ASSERT_TRUE(dns.startServer());
-
-    ASSERT_TRUE(SetResolversWithTls(
-            servers, mDefaultSearchDomains, mDefaultParams_Binder,
-            {}, "", { base64Encode(NOOP_FINGERPRINT) }));
-
-    addrinfo* ai_result = nullptr;
-    EXPECT_NE(0, getaddrinfo(host_name, nullptr, nullptr, &ai_result));
-    EXPECT_EQ(0U, GetNumQueries(dns, host_name));
-}
diff --git a/tests/runtests.sh b/tests/runtests.sh
index d59dd19..a221116 100755
--- a/tests/runtests.sh
+++ b/tests/runtests.sh
@@ -7,7 +7,8 @@
     netdutils_test
     netd_unit_test
     netd_integration_test
-    libnetd_resolv_test
+    resolv_integration_test
+    resolv_unit_test
 "
 
 readonly EXTENDED_TESTS="