diff --git a/server/ResolverController.cpp b/server/ResolverController.cpp
index a299120..0b326b0 100644
--- a/server/ResolverController.cpp
+++ b/server/ResolverController.cpp
@@ -38,6 +38,7 @@
 #include <android/net/INetd.h>
 #include <android/net/metrics/INetdEventListener.h>
 
+#include "Controllers.h"
 #include "DumpWriter.h"
 #include "EventReporter.h"
 #include "Fwmark.h"
@@ -45,18 +46,13 @@
 #include "Permission.h"
 #include "ResolverController.h"
 #include "ResolverStats.h"
-#include "netd_resolv/DnsTlsServer.h"
-#include "netd_resolv/DnsTlsTransport.h"
 #include "netd_resolv/params.h"
 #include "netd_resolv/resolv.h"
 #include "netd_resolv/stats.h"
-#include "netdutils/BackoffSequence.h"
 
 namespace android {
-
-using netdutils::BackoffSequence;
-
 namespace net {
+
 namespace {
 
 std::string addrToString(const sockaddr_storage* addr) {
@@ -66,324 +62,50 @@
     return std::string(out);
 }
 
-bool parseServer(const char* server, sockaddr_storage* parsed) {
-    addrinfo hints = {
-        .ai_family = AF_UNSPEC,
-        .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV
-    };
-    addrinfo* res;
-
-    int err = getaddrinfo(server, "853", &hints, &res);
-    if (err != 0) {
-        ALOGW("Failed to parse server address (%s): %s", server, gai_strerror(err));
-        return false;
-    }
-
-    memcpy(parsed, res->ai_addr, res->ai_addrlen);
-    freeaddrinfo(res);
-    return true;
-}
-
 const char* getPrivateDnsModeString(PrivateDnsMode mode) {
     switch (mode) {
-        case PrivateDnsMode::OFF: return "OFF";
-        case PrivateDnsMode::OPPORTUNISTIC: return "OPPORTUNISTIC";
-        case PrivateDnsMode::STRICT: return "STRICT";
+        case PrivateDnsMode::OFF:
+            return "OFF";
+        case PrivateDnsMode::OPPORTUNISTIC:
+            return "OPPORTUNISTIC";
+        case PrivateDnsMode::STRICT:
+            return "STRICT";
     }
 }
 
-constexpr const char* validationStatusToString(ResolverController::Validation value) {
+constexpr const char* validationStatusToString(Validation value) {
     switch (value) {
-        case ResolverController::Validation::in_process:     return "in_process";
-        case ResolverController::Validation::success:        return "success";
-        case ResolverController::Validation::fail:           return "fail";
-        case ResolverController::Validation::unknown_server: return "unknown_server";
-        case ResolverController::Validation::unknown_netid:  return "unknown_netid";
-        default: return "unknown_status";
+        case Validation::in_process:
+            return "in_process";
+        case Validation::success:
+            return "success";
+        case Validation::fail:
+            return "fail";
+        case Validation::unknown_server:
+            return "unknown_server";
+        case Validation::unknown_netid:
+            return "unknown_netid";
+        default:
+            return "unknown_status";
     }
 }
 
-
-class PrivateDnsConfiguration {
-  public:
-    typedef ResolverController::PrivateDnsStatus PrivateDnsStatus;
-    typedef ResolverController::Validation Validation;
-    typedef std::map<DnsTlsServer, Validation, AddressComparator> PrivateDnsTracker;
-
-    int set(uint32_t netId, uint32_t mark, const std::vector<std::string>& servers,
-            const std::string& name, const std::set<std::vector<uint8_t>>& fingerprints) {
+void onPrivateDnsValidation(unsigned netId, const char* server, const char* hostname,
+                            bool success) {
+    // Send a validation event to NetdEventListenerService.
+    const auto netdEventListener = net::gCtls->eventReporter.getNetdEventListener();
+    if (netdEventListener != nullptr) {
+        netdEventListener->onPrivateDnsValidationEvent(netId, android::String16(server),
+                                                       android::String16(hostname), success);
         if (DBG) {
-            ALOGD("PrivateDnsConfiguration::set(%u, 0x%x, %zu, %s, %zu)", netId, mark,
-                  servers.size(), name.c_str(), fingerprints.size());
+            ALOGD("Sending validation %s event on netId %u for %s with hostname %s",
+                  success ? "success" : "failure", netId, server, hostname);
         }
 
-        const bool explicitlyConfigured = !name.empty() || !fingerprints.empty();
-
-        // Parse the list of servers that has been passed in
-        std::set<DnsTlsServer> tlsServers;
-        for (size_t i = 0; i < servers.size(); ++i) {
-            sockaddr_storage parsed;
-            if (!parseServer(servers[i].c_str(), &parsed)) {
-                return -EINVAL;
-            }
-            DnsTlsServer server(parsed);
-            server.name = name;
-            server.fingerprints = fingerprints;
-            tlsServers.insert(server);
-        }
-
-        std::lock_guard guard(mPrivateDnsLock);
-        if (explicitlyConfigured) {
-            mPrivateDnsModes[netId] = PrivateDnsMode::STRICT;
-        } else if (!tlsServers.empty()) {
-            mPrivateDnsModes[netId] = PrivateDnsMode::OPPORTUNISTIC;
-        } else {
-            mPrivateDnsModes[netId] = PrivateDnsMode::OFF;
-            mPrivateDnsTransports.erase(netId);
-            return 0;
-        }
-
-        // Create the tracker if it was not present
-        auto netPair = mPrivateDnsTransports.find(netId);
-        if (netPair == mPrivateDnsTransports.end()) {
-            // No TLS tracker yet for this netId.
-            bool added;
-            std::tie(netPair, added) = mPrivateDnsTransports.emplace(netId, PrivateDnsTracker());
-            if (!added) {
-                ALOGE("Memory error while recording private DNS for netId %d", netId);
-                return -ENOMEM;
-            }
-        }
-        auto& tracker = netPair->second;
-
-        // Remove any servers from the tracker that are not in |servers| exactly.
-        for (auto it = tracker.begin(); it != tracker.end();) {
-            if (tlsServers.count(it->first) == 0) {
-                it = tracker.erase(it);
-            } else {
-                ++it;
-            }
-        }
-
-        // Add any new or changed servers to the tracker, and initiate async checks for them.
-        for (const auto& server : tlsServers) {
-            if (needsValidation(tracker, server)) {
-                validatePrivateDnsProvider(server, tracker, netId, mark);
-            }
-        }
-        return 0;
+    } else {
+        ALOGE("Validation event not sent since NetdEventListenerService is unavailable.");
     }
-
-    PrivateDnsStatus getStatus(unsigned netId) {
-        PrivateDnsStatus status{PrivateDnsMode::OFF, {}};
-
-        // This mutex is on the critical path of every DNS lookup.
-        //
-        // If the overhead of mutex acquisition proves too high, we could reduce
-        // it by maintaining an atomic_int32_t counter of TLS-enabled netids, or
-        // by using an RWLock.
-        std::lock_guard guard(mPrivateDnsLock);
-
-        const auto mode = mPrivateDnsModes.find(netId);
-        if (mode == mPrivateDnsModes.end()) return status;
-        status.mode = mode->second;
-
-        const auto netPair = mPrivateDnsTransports.find(netId);
-        if (netPair != mPrivateDnsTransports.end()) {
-            for (const auto& serverPair : netPair->second) {
-                if (serverPair.second == Validation::success) {
-                    status.validatedServers.push_back(serverPair.first);
-                }
-            }
-        }
-
-        return status;
-    }
-
-    void clear(unsigned netId) {
-        if (DBG) {
-            ALOGD("PrivateDnsConfiguration::clear(%u)", netId);
-        }
-        std::lock_guard guard(mPrivateDnsLock);
-        mPrivateDnsModes.erase(netId);
-        mPrivateDnsTransports.erase(netId);
-    }
-
-    void dump(DumpWriter& dw, unsigned netId) {
-        std::lock_guard guard(mPrivateDnsLock);
-
-        const auto& mode = mPrivateDnsModes.find(netId);
-        dw.println("Private DNS mode: %s", getPrivateDnsModeString(
-                (mode != mPrivateDnsModes.end()) ? mode->second : PrivateDnsMode::OFF));
-        const auto& netPair = mPrivateDnsTransports.find(netId);
-        if (netPair == mPrivateDnsTransports.end()) {
-            dw.println("No Private DNS servers configured");
-        } else {
-            const auto& tracker = netPair->second;
-            dw.println("Private DNS configuration (%zu entries)", tracker.size());
-            dw.incIndent();
-            for (const auto& kv : tracker) {
-                const auto& server = kv.first;
-                const auto status = kv.second;
-                dw.println("%s name{%s} status{%s}",
-                        addrToString(&(server.ss)).c_str(),
-                        server.name.c_str(),
-                        validationStatusToString(status));
-            }
-            dw.decIndent();
-        }
-    }
-
-  private:
-    void validatePrivateDnsProvider(const DnsTlsServer& server, PrivateDnsTracker& tracker,
-                                    unsigned netId, uint32_t mark) REQUIRES(mPrivateDnsLock) {
-        if (DBG) {
-            ALOGD("validatePrivateDnsProvider(%s, %u)", addrToString(&(server.ss)).c_str(), netId);
-        }
-
-        tracker[server] = Validation::in_process;
-        if (DBG) {
-            ALOGD("Server %s marked as in_process.  Tracker now has size %zu",
-                    addrToString(&(server.ss)).c_str(), tracker.size());
-        }
-        // Note that capturing |server| and |netId| in this lambda create copies.
-        std::thread validate_thread([this, server, netId, mark] {
-            // cat /proc/sys/net/ipv4/tcp_syn_retries yields "6".
-            //
-            // Start with a 1 minute delay and backoff to once per hour.
-            //
-            // Assumptions:
-            //     [1] Each TLS validation is ~10KB of certs+handshake+payload.
-            //     [2] Network typically provision clients with <=4 nameservers.
-            //     [3] Average month has 30 days.
-            //
-            // Each validation pass in a given hour is ~1.2MB of data. And 24
-            // such validation passes per day is about ~30MB per month, in the
-            // worst case. Otherwise, this will cost ~600 SYNs per month
-            // (6 SYNs per ip, 4 ips per validation pass, 24 passes per day).
-            auto backoff = BackoffSequence<>::Builder()
-                    .withInitialRetransmissionTime(std::chrono::seconds(60))
-                    .withMaximumRetransmissionTime(std::chrono::seconds(3600))
-                    .build();
-
-            while (true) {
-                // ::validate() is a blocking call that performs network operations.
-                // It can take milliseconds to minutes, up to the SYN retry limit.
-                const bool success = DnsTlsTransport::validate(server, netId, mark);
-                if (DBG) {
-                    ALOGD("validateDnsTlsServer returned %d for %s", success,
-                            addrToString(&(server.ss)).c_str());
-                }
-
-                const bool needs_reeval = this->recordPrivateDnsValidation(server, netId, success);
-                if (!needs_reeval) {
-                    break;
-                }
-
-                if (backoff.hasNextTimeout()) {
-                    std::this_thread::sleep_for(backoff.getNextTimeout());
-                } else {
-                    break;
-                }
-            }
-        });
-        validate_thread.detach();
-    }
-
-    bool recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool success) {
-        constexpr bool NEEDS_REEVALUATION = true;
-        constexpr bool DONT_REEVALUATE = false;
-
-        std::lock_guard guard(mPrivateDnsLock);
-
-        auto netPair = mPrivateDnsTransports.find(netId);
-        if (netPair == mPrivateDnsTransports.end()) {
-            ALOGW("netId %u was erased during private DNS validation", netId);
-            return DONT_REEVALUATE;
-        }
-
-        const auto mode = mPrivateDnsModes.find(netId);
-        if (mode == mPrivateDnsModes.end()) {
-            ALOGW("netId %u has no private DNS validation mode", netId);
-            return DONT_REEVALUATE;
-        }
-        const bool modeDoesReevaluation = (mode->second == PrivateDnsMode::STRICT);
-
-        bool reevaluationStatus =
-                (success || !modeDoesReevaluation) ? DONT_REEVALUATE : NEEDS_REEVALUATION;
-
-        auto& tracker = netPair->second;
-        auto serverPair = tracker.find(server);
-        if (serverPair == tracker.end()) {
-            ALOGW("Server %s was removed during private DNS validation",
-                    addrToString(&(server.ss)).c_str());
-            success = false;
-            reevaluationStatus = DONT_REEVALUATE;
-        } else if (!(serverPair->first == server)) {
-            // TODO: It doesn't seem correct to overwrite the tracker entry for
-            // |server| down below in this circumstance... Fix this.
-            ALOGW("Server %s was changed during private DNS validation",
-                    addrToString(&(server.ss)).c_str());
-            success = false;
-            reevaluationStatus = DONT_REEVALUATE;
-        }
-
-        // Send a validation event to NetdEventListenerService.
-        if (mNetdEventListener == nullptr) {
-            mNetdEventListener = mEventReporter.getNetdEventListener();
-        }
-        if (mNetdEventListener != nullptr) {
-            const String16 ipLiteral(addrToString(&(server.ss)).c_str());
-            const String16 hostname(server.name.empty() ? "" : server.name.c_str());
-            mNetdEventListener->onPrivateDnsValidationEvent(netId, ipLiteral, hostname, success);
-            if (DBG) {
-                ALOGD("Sending validation %s event on netId %u for %s with hostname %s",
-                        success ? "success" : "failure", netId,
-                        addrToString(&(server.ss)).c_str(), server.name.c_str());
-            }
-        } else {
-            ALOGE("Validation event not sent since NetdEventListenerService is unavailable.");
-        }
-
-        if (success) {
-            tracker[server] = Validation::success;
-            if (DBG) {
-                ALOGD("Validation succeeded for %s! Tracker now has %zu entries.",
-                        addrToString(&(server.ss)).c_str(), tracker.size());
-            }
-        } else {
-            // Validation failure is expected if a user is on a captive portal.
-            // TODO: Trigger a second validation attempt after captive portal login
-            // succeeds.
-            tracker[server] = (reevaluationStatus == NEEDS_REEVALUATION) ? Validation::in_process
-                                                                         : Validation::fail;
-            if (DBG) {
-                ALOGD("Validation failed for %s!", addrToString(&(server.ss)).c_str());
-            }
-        }
-
-        return reevaluationStatus;
-    }
-
-    // Start validation for newly added servers as well as any servers that have
-    // landed in Validation::fail state. Note that servers that have failed
-    // multiple validation attempts but for which there is still a validating
-    // thread running are marked as being Validation::in_process.
-    static bool needsValidation(const PrivateDnsTracker& tracker, const DnsTlsServer& server) {
-        const auto& iter = tracker.find(server);
-        return (iter == tracker.end()) || (iter->second == Validation::fail);
-    }
-
-    EventReporter mEventReporter;
-
-    std::mutex mPrivateDnsLock;
-    std::map<unsigned, PrivateDnsMode> mPrivateDnsModes GUARDED_BY(mPrivateDnsLock);
-    // Structure for tracking the validation status of servers on a specific netId.
-    // Using the AddressComparator ensures at most one entry per IP address.
-    std::map<unsigned, PrivateDnsTracker> mPrivateDnsTransports GUARDED_BY(mPrivateDnsLock);
-    android::sp<android::net::metrics::INetdEventListener>
-            mNetdEventListener GUARDED_BY(mPrivateDnsLock);
-} sPrivateDnsConfiguration;
+}
 
 bool allIPv6Only(const std::vector<std::string>& servers) {
     for (const auto& server : servers) {
@@ -402,18 +124,13 @@
     return -resolv_set_nameservers_for_net(netId, servers, numservers, searchDomains, params);
 }
 
-ResolverController::PrivateDnsStatus
-ResolverController::getPrivateDnsStatus(unsigned netId) const {
-    return sPrivateDnsConfiguration.getStatus(netId);
-}
-
 int ResolverController::clearDnsServers(unsigned netId) {
     resolv_set_nameservers_for_net(netId, nullptr, 0, "", nullptr);
     if (DBG) {
         ALOGD("clearDnsServers netId = %u\n", netId);
     }
     mDns64Configuration.stopPrefixDiscovery(netId);
-    sPrivateDnsConfiguration.clear(netId);
+    resolv_delete_private_dns_for_net(netId);
     return 0;
 }
 
@@ -512,6 +229,20 @@
         return -EINVAL;
     }
 
+    std::vector<const char*> server_ptrs;
+    size_t count = std::min<size_t>(MAXNS, tlsServers.size());
+    server_ptrs.reserve(count);
+    for (size_t i = 0; i < count; i++) {
+        server_ptrs.push_back(tlsServers[i].data());
+    }
+
+    std::vector<const uint8_t*> fingerprint_ptrs;
+    count = tlsFingerprints.size();
+    fingerprint_ptrs.reserve(count);
+    for (const auto& fp : tlsFingerprints) {
+        fingerprint_ptrs.push_back(fp.data());
+    }
+
     // At private DNS validation time, we only know the netId, so we have to guess/compute the
     // corresponding socket mark.
     Fwmark fwmark;
@@ -520,16 +251,19 @@
     fwmark.protectedFromVpn = true;
     fwmark.permission = PERMISSION_SYSTEM;
 
-    const int err = sPrivateDnsConfiguration.set(netId, fwmark.intValue, tlsServers, tlsName,
-                                                 tlsFingerprints);
+    const int err = resolv_set_private_dns_for_net(
+            netId, fwmark.intValue, server_ptrs.data(), server_ptrs.size(), tlsName.c_str(),
+            fingerprint_ptrs.data(), fingerprint_ptrs.size());
     if (err != 0) {
         return err;
     }
+    resolv_register_private_dns_callback(&onPrivateDnsValidation);
 
     // Convert network-assigned server list to bionic's format.
-    auto server_count = std::min<size_t>(MAXNS, servers.size());
-    std::vector<const char*> server_ptrs;
-    for (size_t i = 0 ; i < server_count ; ++i) {
+    server_ptrs.clear();
+    count = std::min<size_t>(MAXNS, servers.size());
+    server_ptrs.reserve(count);
+    for (size_t i = 0; i < count; ++i) {
         server_ptrs.push_back(servers[i].c_str());
     }
 
@@ -653,7 +387,24 @@
         }
 
         mDns64Configuration.dump(dw, netId);
-        sPrivateDnsConfiguration.dump(dw, netId);
+        ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}};
+        resolv_get_private_dns_status_for_net(netId, &privateDnsStatus);
+        dw.println("Private DNS mode: %s",
+                   getPrivateDnsModeString(static_cast<PrivateDnsMode>(privateDnsStatus.mode)));
+        if (!privateDnsStatus.numServers) {
+            dw.println("No Private DNS servers configured");
+        } else {
+            dw.println("Private DNS configuration (%u entries)", privateDnsStatus.numServers);
+            dw.incIndent();
+            for (int i = 0; i < privateDnsStatus.numServers; i++) {
+                dw.println("%s name{%s} status{%s}",
+                           addrToString(&(privateDnsStatus.serverStatus[i].ss)).c_str(),
+                           privateDnsStatus.serverStatus[i].hostname,
+                           validationStatusToString(static_cast<Validation>(
+                                   privateDnsStatus.serverStatus[i].validation)));
+            }
+            dw.decIndent();
+        }
     }
     dw.decIndent();
 }
