Loading DnsTlsDispatcher.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -229,7 +229,7 @@ DnsTlsTransport::Response DnsTlsDispatcher::query(const DnsTlsServer& server, un // happens, the xport will be marked as unusable and DoT queries won't be sent to // happens, the xport will be marked as unusable and DoT queries won't be sent to // it anymore. Eventually, after IDLE_TIMEOUT, the xport will be destroyed, and // it anymore. Eventually, after IDLE_TIMEOUT, the xport will be destroyed, and // a new xport will be created. // a new xport will be created. const auto result = PrivateDnsConfiguration::getInstance().requestValidation( const auto result = PrivateDnsConfiguration::getInstance().requestDotValidation( netId, PrivateDnsConfiguration::ServerIdentity{server}, mark); netId, PrivateDnsConfiguration::ServerIdentity{server}, mark); LOG(WARNING) << "Requested validation for " << server.toIpString() << " with mark 0x" LOG(WARNING) << "Requested validation for " << server.toIpString() << " with mark 0x" << std::hex << mark << ", " << std::hex << mark << ", " Loading DnsTlsServer.h +11 −16 Original line number Original line Diff line number Diff line Loading @@ -20,23 +20,23 @@ #include <string> #include <string> #include <vector> #include <vector> #include <netdutils/InternetAddresses.h> #include <netinet/in.h> #include <netinet/in.h> #include <params.h> #include <params.h> #include "IPrivateDnsServer.h" #include "PrivateDnsCommon.h" namespace android { namespace android { namespace net { namespace net { // DnsTlsServer represents a recursive resolver that supports, or may support, a // DnsTlsServer represents a recursive resolver that supports, or may support, a // secure protocol. // secure protocol. struct DnsTlsServer : public IPrivateDnsServer { struct DnsTlsServer { // Default constructor. // Default constructor. DnsTlsServer() {} DnsTlsServer() {} explicit DnsTlsServer(const netdutils::IPAddress& ip) explicit DnsTlsServer(const netdutils::IPAddress& ip) : DnsTlsServer(netdutils::IPSockAddr(ip, 853)) {} : DnsTlsServer(netdutils::IPSockAddr(ip, kDotPort)) {} explicit DnsTlsServer(const netdutils::IPSockAddr& addr) : ss(addr) {} explicit DnsTlsServer(const netdutils::IPSockAddr& addr) : ss(addr) {} // The server location, including IP and port. // The server location, including IP and port. Loading Loading @@ -64,17 +64,12 @@ struct DnsTlsServer : public IPrivateDnsServer { bool wasExplicitlyConfigured() const; bool wasExplicitlyConfigured() const; std::string toIpString() const; std::string toIpString() const; PrivateDnsTransport transport() const override { return PrivateDnsTransport::kDot; } std::string provider() const { return name; } std::string provider() const override { return name; } netdutils::IPSockAddr addr() const { return netdutils::IPSockAddr::toIPSockAddr(ss); } netdutils::IPSockAddr addr() const override { return netdutils::IPSockAddr::toIPSockAddr(ss); } uint32_t validationMark() const { return mark; } uint32_t validationMark() const override { return mark; } Validation validationState() const override { return mValidation; } Validation validationState() const { return mValidation; } void setValidationState(Validation val) override { mValidation = val; } void setValidationState(Validation val) { mValidation = val; } bool probe() override { // TODO: implement it. return false; } // The socket mark used for validation. // The socket mark used for validation. // Note that the mark of a connection to which the DnsResolver sends app's DNS requests can // Note that the mark of a connection to which the DnsResolver sends app's DNS requests can Loading @@ -84,8 +79,8 @@ struct DnsTlsServer : public IPrivateDnsServer { // Return whether or not the server can be used for a network. It depends on // Return whether or not the server can be used for a network. It depends on // the resolver configuration. // the resolver configuration. bool active() const override { return mActive; } bool active() const { return mActive; } void setActive(bool val) override { mActive = val; } void setActive(bool val) { mActive = val; } private: private: // State, unrelated to the comparison of DnsTlsServer objects. // State, unrelated to the comparison of DnsTlsServer objects. Loading IPrivateDnsServer.hdeleted 100644 → 0 +0 −60 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <string> #include <netdutils/InternetAddresses.h> #include "PrivateDnsCommon.h" namespace android::net { class IPrivateDnsServer { public: virtual ~IPrivateDnsServer(){}; virtual PrivateDnsTransport transport() const = 0; bool isDot() const { return transport() == PrivateDnsTransport::kDot; } bool isDoh() const { return transport() == PrivateDnsTransport::kDoh; } // Returns the provider name of the server. virtual std::string provider() const = 0; // Returns the IP address of the server. virtual netdutils::IPSockAddr addr() const = 0; // Returns the socket mark used for probe. virtual uint32_t validationMark() const = 0; // Sets the validation state. virtual void setValidationState(Validation val) = 0; // Returns the validation state. virtual Validation validationState() const = 0; // Checks the server supports private DNS. virtual bool probe() = 0; // Sets if the server should be active. virtual void setActive(bool val) = 0; // Returns if the server is active. virtual bool active() const = 0; }; } // namespace android::net PrivateDnsConfiguration.cpp +49 −51 Original line number Original line Diff line number Diff line Loading @@ -96,38 +96,38 @@ int PrivateDnsConfiguration::setDot(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, const std::vector<std::string>& servers, const std::string& name, const std::string& caCert) { const std::string& name, const std::string& caCert) { // Parse the list of servers that has been passed in // Parse the list of servers that has been passed in PrivateDnsTracker tmp; std::map<ServerIdentity, DnsTlsServer> tmp; for (const auto& s : servers) { for (const auto& s : servers) { // The IP addresses are guaranteed to be valid. // The IP addresses are guaranteed to be valid. auto server = std::make_unique<DnsTlsServer>(IPAddress::forString(s)); DnsTlsServer server(IPAddress::forString(s)); server->name = name; server.name = name; server->certificate = caCert; server.certificate = caCert; server->mark = mark; server.mark = mark; tmp[ServerIdentity(*server)] = std::move(server); tmp[ServerIdentity(server)] = server; } } // Create the tracker if it was not present // Create the tracker if it was not present auto& tracker = mPrivateDnsTransports[netId]; auto& tracker = mDotTracker[netId]; // Add the servers if not contained in tracker. // Add the servers if not contained in tracker. for (auto& [identity, server] : tmp) { for (const auto& [identity, server] : tmp) { if (tracker.find(identity) == tracker.end()) { if (tracker.find(identity) == tracker.end()) { tracker[identity] = std::move(server); tracker[identity] = server; } } } } for (auto& [identity, server] : tracker) { for (auto& [identity, server] : tracker) { const bool active = tmp.find(identity) != tmp.end(); const bool active = tmp.find(identity) != tmp.end(); server->setActive(active); server.setActive(active); // For simplicity, deem the validation result of inactive servers as unreliable. // For simplicity, deem the validation result of inactive servers as unreliable. if (!server->active() && server->validationState() == Validation::success) { if (!server.active() && server.validationState() == Validation::success) { updateServerState(identity, Validation::success_but_expired, netId); updateServerState(identity, Validation::success_but_expired, netId); } } if (needsValidation(*server)) { if (needsValidation(server)) { updateServerState(identity, Validation::in_process, netId); updateServerState(identity, Validation::in_process, netId); startValidation(identity, netId, false); startDotValidation(identity, netId, false); } } } } Loading @@ -135,7 +135,7 @@ int PrivateDnsConfiguration::setDot(int32_t netId, uint32_t mark, } } void PrivateDnsConfiguration::clearDot(int32_t netId) { void PrivateDnsConfiguration::clearDot(int32_t netId) { mPrivateDnsTransports.erase(netId); mDotTracker.erase(netId); resolv_stats_set_addrs(netId, PROTO_DOT, {}, kDotPort); resolv_stats_set_addrs(netId, PROTO_DOT, {}, kDotPort); } } Loading @@ -151,12 +151,11 @@ PrivateDnsStatus PrivateDnsConfiguration::getStatus(unsigned netId) const { if (mode == mPrivateDnsModes.end()) return status; if (mode == mPrivateDnsModes.end()) return status; status.mode = mode->second; status.mode = mode->second; const auto netPair = mPrivateDnsTransports.find(netId); const auto netPair = mDotTracker.find(netId); if (netPair != mPrivateDnsTransports.end()) { if (netPair != mDotTracker.end()) { for (const auto& [_, server] : netPair->second) { for (const auto& [_, server] : netPair->second) { if (server->isDot() && server->active()) { if (server.active()) { DnsTlsServer& dotServer = *static_cast<DnsTlsServer*>(server.get()); status.dotServersMap.emplace(server, server.validationState()); status.dotServersMap.emplace(dotServer, server->validationState()); } } } } } } Loading @@ -182,7 +181,7 @@ void PrivateDnsConfiguration::clear(unsigned netId) { mCv.notify_all(); mCv.notify_all(); } } base::Result<void> PrivateDnsConfiguration::requestValidation(unsigned netId, base::Result<void> PrivateDnsConfiguration::requestDotValidation(unsigned netId, const ServerIdentity& identity, const ServerIdentity& identity, uint32_t mark) { uint32_t mark) { std::lock_guard guard(mPrivateDnsLock); std::lock_guard guard(mPrivateDnsLock); Loading @@ -197,37 +196,37 @@ base::Result<void> PrivateDnsConfiguration::requestValidation(unsigned netId, return Errorf("Private DNS setting is not opportunistic mode"); return Errorf("Private DNS setting is not opportunistic mode"); } } auto result = getPrivateDnsLocked(identity, netId); auto result = getDotServerLocked(identity, netId); if (!result.ok()) { if (!result.ok()) { return result.error(); return result.error(); } } const IPrivateDnsServer* server = result.value(); const DnsTlsServer* target = result.value(); if (!server->active()) return Errorf("Server is not active"); if (!target->active()) return Errorf("Server is not active"); if (server->validationState() != Validation::success) { if (target->validationState() != Validation::success) { return Errorf("Server validation state mismatched"); return Errorf("Server validation state mismatched"); } } // Don't run the validation if |mark| (from android_net_context.dns_mark) is different. // Don't run the validation if |mark| (from android_net_context.dns_mark) is different. // This is to protect validation from running on unexpected marks. // This is to protect validation from running on unexpected marks. // Validation should be associated with a mark gotten by system permission. // Validation should be associated with a mark gotten by system permission. if (server->validationMark() != mark) return Errorf("Socket mark mismatched"); if (target->validationMark() != mark) return Errorf("Socket mark mismatched"); updateServerState(identity, Validation::in_process, netId); updateServerState(identity, Validation::in_process, netId); startValidation(identity, netId, true); startDotValidation(identity, netId, true); return {}; return {}; } } void PrivateDnsConfiguration::startValidation(const ServerIdentity& identity, unsigned netId, void PrivateDnsConfiguration::startDotValidation(const ServerIdentity& identity, unsigned netId, bool isRevalidation) { bool isRevalidation) { // This ensures that the thread sends probe at least once in case // This ensures that the thread sends probe at least once in case // the server is removed before the thread starts running. // the server is removed before the thread starts running. // TODO: consider moving these code to the thread. // TODO: consider moving these code to the thread. const auto result = getPrivateDnsLocked(identity, netId); const auto result = getDotServerLocked(identity, netId); if (!result.ok()) return; if (!result.ok()) return; DnsTlsServer server = *static_cast<const DnsTlsServer*>(result.value()); DnsTlsServer server = *result.value(); std::thread validate_thread([this, identity, server, netId, isRevalidation] { std::thread validate_thread([this, identity, server, netId, isRevalidation] { setThreadName(fmt::format("TlsVerify_{}", netId)); setThreadName(fmt::format("TlsVerify_{}", netId)); Loading Loading @@ -257,7 +256,7 @@ void PrivateDnsConfiguration::startValidation(const ServerIdentity& identity, un << server.toIpString(); << server.toIpString(); const bool needs_reeval = const bool needs_reeval = this->recordPrivateDnsValidation(identity, netId, success, isRevalidation); this->recordDotValidation(identity, netId, success, isRevalidation); if (!needs_reeval || !backoff.hasNextTimeout()) { if (!needs_reeval || !backoff.hasNextTimeout()) { break; break; Loading Loading @@ -310,16 +309,15 @@ void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const ServerIdentity } } } } bool PrivateDnsConfiguration::recordPrivateDnsValidation(const ServerIdentity& identity, bool PrivateDnsConfiguration::recordDotValidation(const ServerIdentity& identity, unsigned netId, unsigned netId, bool success, bool success, bool isRevalidation) { bool isRevalidation) { constexpr bool NEEDS_REEVALUATION = true; constexpr bool NEEDS_REEVALUATION = true; constexpr bool DONT_REEVALUATE = false; constexpr bool DONT_REEVALUATE = false; std::lock_guard guard(mPrivateDnsLock); std::lock_guard guard(mPrivateDnsLock); auto netPair = mPrivateDnsTransports.find(netId); auto netPair = mDotTracker.find(netId); if (netPair == mPrivateDnsTransports.end()) { if (netPair == mDotTracker.end()) { LOG(WARNING) << "netId " << netId << " was erased during private DNS validation"; LOG(WARNING) << "netId " << netId << " was erased during private DNS validation"; notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); return DONT_REEVALUATE; return DONT_REEVALUATE; Loading @@ -345,7 +343,7 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const ServerIdentity& i << " was removed during private DNS validation"; << " was removed during private DNS validation"; success = false; success = false; reevaluationStatus = DONT_REEVALUATE; reevaluationStatus = DONT_REEVALUATE; } else if (!serverPair->second->active()) { } else if (!serverPair->second.active()) { LOG(WARNING) << "Server " << identity.sockaddr.ip().toString() LOG(WARNING) << "Server " << identity.sockaddr.ip().toString() << " was removed from the configuration"; << " was removed from the configuration"; success = false; success = false; Loading Loading @@ -374,7 +372,7 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const ServerIdentity& i void PrivateDnsConfiguration::updateServerState(const ServerIdentity& identity, Validation state, void PrivateDnsConfiguration::updateServerState(const ServerIdentity& identity, Validation state, uint32_t netId) { uint32_t netId) { const auto result = getPrivateDnsLocked(identity, netId); const auto result = getDotServerLocked(identity, netId); if (!result.ok()) { if (!result.ok()) { notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); return; return; Loading @@ -389,7 +387,7 @@ void PrivateDnsConfiguration::updateServerState(const ServerIdentity& identity, mPrivateDnsLog.push(std::move(record)); mPrivateDnsLog.push(std::move(record)); } } bool PrivateDnsConfiguration::needsValidation(const IPrivateDnsServer& server) const { bool PrivateDnsConfiguration::needsValidation(const DnsTlsServer& server) const { // The server is not expected to be used on the network. // The server is not expected to be used on the network. if (!server.active()) return false; if (!server.active()) return false; Loading @@ -405,16 +403,16 @@ bool PrivateDnsConfiguration::needsValidation(const IPrivateDnsServer& server) c return false; return false; } } base::Result<IPrivateDnsServer*> PrivateDnsConfiguration::getPrivateDns( base::Result<DnsTlsServer*> PrivateDnsConfiguration::getDotServer(const ServerIdentity& identity, const ServerIdentity& identity, unsigned netId) { unsigned netId) { std::lock_guard guard(mPrivateDnsLock); std::lock_guard guard(mPrivateDnsLock); return getPrivateDnsLocked(identity, netId); return getDotServerLocked(identity, netId); } } base::Result<IPrivateDnsServer*> PrivateDnsConfiguration::getPrivateDnsLocked( base::Result<DnsTlsServer*> PrivateDnsConfiguration::getDotServerLocked( const ServerIdentity& identity, unsigned netId) { const ServerIdentity& identity, unsigned netId) { auto netPair = mPrivateDnsTransports.find(netId); auto netPair = mDotTracker.find(netId); if (netPair == mPrivateDnsTransports.end()) { if (netPair == mDotTracker.end()) { return Errorf("Failed to get private DNS: netId {} not found", netId); return Errorf("Failed to get private DNS: netId {} not found", netId); } } Loading @@ -424,7 +422,7 @@ base::Result<IPrivateDnsServer*> PrivateDnsConfiguration::getPrivateDnsLocked( identity.provider); identity.provider); } } return iter->second.get(); return &iter->second; } } void PrivateDnsConfiguration::setObserver(PrivateDnsValidationObserver* observer) { void PrivateDnsConfiguration::setObserver(PrivateDnsValidationObserver* observer) { Loading Loading @@ -606,12 +604,12 @@ bool PrivateDnsConfiguration::needReportEvent(uint32_t netId, ServerIdentity ide switch (identity.sockaddr.port()) { switch (identity.sockaddr.port()) { // DoH // DoH case kDohPort: { case kDohPort: { auto netPair = mPrivateDnsTransports.find(netId); auto netPair = mDotTracker.find(netId); if (netPair == mPrivateDnsTransports.end()) return true; if (netPair == mDotTracker.end()) return true; for (const auto& [id, server] : netPair->second) { for (const auto& [id, server] : netPair->second) { if ((identity.sockaddr.ip() == id.sockaddr.ip()) && if ((identity.sockaddr.ip() == id.sockaddr.ip()) && (identity.sockaddr.port() != id.sockaddr.port()) && (identity.sockaddr.port() != id.sockaddr.port()) && (server->validationState() == Validation::success)) { (server.validationState() == Validation::success)) { LOG(DEBUG) << __func__ LOG(DEBUG) << __func__ << ": Skip reporting DoH validation failure event, server addr: " << ": Skip reporting DoH validation failure event, server addr: " << identity.sockaddr.ip().toString(); << identity.sockaddr.ip().toString(); Loading PrivateDnsConfiguration.h +17 −19 Original line number Original line Diff line number Diff line Loading @@ -39,7 +39,6 @@ namespace android { namespace android { namespace net { namespace net { // TODO: decouple the dependency of DnsTlsServer. struct PrivateDnsStatus { struct PrivateDnsStatus { PrivateDnsMode mode; PrivateDnsMode mode; Loading Loading @@ -81,7 +80,7 @@ class PrivateDnsConfiguration { const netdutils::IPSockAddr sockaddr; const netdutils::IPSockAddr sockaddr; const std::string provider; const std::string provider; explicit ServerIdentity(const IPrivateDnsServer& server) explicit ServerIdentity(const DnsTlsServer& server) : sockaddr(server.addr()), provider(server.provider()) {} : sockaddr(server.addr()), provider(server.provider()) {} ServerIdentity(const netdutils::IPSockAddr& addr, const std::string& host) ServerIdentity(const netdutils::IPSockAddr& addr, const std::string& host) : sockaddr(addr), provider(host) {} : sockaddr(addr), provider(host) {} Loading Loading @@ -114,7 +113,7 @@ class PrivateDnsConfiguration { // Request the server to be revalidated on a connection tagged with |mark|. // Request the server to be revalidated on a connection tagged with |mark|. // Returns a Result to indicate if the request is accepted. // Returns a Result to indicate if the request is accepted. base::Result<void> requestValidation(unsigned netId, const ServerIdentity& identity, base::Result<void> requestDotValidation(unsigned netId, const ServerIdentity& identity, uint32_t mark) EXCLUDES(mPrivateDnsLock); uint32_t mark) EXCLUDES(mPrivateDnsLock); void setObserver(PrivateDnsValidationObserver* observer); void setObserver(PrivateDnsValidationObserver* observer); Loading @@ -128,8 +127,6 @@ class PrivateDnsConfiguration { EXCLUDES(mPrivateDnsLock); EXCLUDES(mPrivateDnsLock); private: private: typedef std::map<ServerIdentity, std::unique_ptr<IPrivateDnsServer>> PrivateDnsTracker; PrivateDnsConfiguration() = default; PrivateDnsConfiguration() = default; int setDot(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, int setDot(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, Loading @@ -137,12 +134,19 @@ class PrivateDnsConfiguration { void clearDot(int32_t netId) REQUIRES(mPrivateDnsLock); void clearDot(int32_t netId) REQUIRES(mPrivateDnsLock); // Launchs a thread to run the validation for |server| on the network |netId|. // For testing. base::Result<DnsTlsServer*> getDotServer(const ServerIdentity& identity, unsigned netId) EXCLUDES(mPrivateDnsLock); base::Result<DnsTlsServer*> getDotServerLocked(const ServerIdentity& identity, unsigned netId) REQUIRES(mPrivateDnsLock); // Launchs a thread to run the validation for the DoT server |server| on the network |netId|. // |isRevalidation| is true if this call is due to a revalidation request. // |isRevalidation| is true if this call is due to a revalidation request. void startValidation(const ServerIdentity& identity, unsigned netId, bool isRevalidation) void startDotValidation(const ServerIdentity& identity, unsigned netId, bool isRevalidation) REQUIRES(mPrivateDnsLock); REQUIRES(mPrivateDnsLock); bool recordPrivateDnsValidation(const ServerIdentity& identity, unsigned netId, bool success, bool recordDotValidation(const ServerIdentity& identity, unsigned netId, bool success, bool isRevalidation) EXCLUDES(mPrivateDnsLock); bool isRevalidation) EXCLUDES(mPrivateDnsLock); void sendPrivateDnsValidationEvent(const ServerIdentity& identity, unsigned netId, void sendPrivateDnsValidationEvent(const ServerIdentity& identity, unsigned netId, Loading @@ -151,18 +155,11 @@ class PrivateDnsConfiguration { // Decide if a validation for |server| is needed. Note that servers that have failed // Decide if a validation for |server| is needed. Note that servers that have failed // multiple validation attempts but for which there is still a validating // multiple validation attempts but for which there is still a validating // thread running are marked as being Validation::in_process. // thread running are marked as being Validation::in_process. bool needsValidation(const IPrivateDnsServer& server) const REQUIRES(mPrivateDnsLock); bool needsValidation(const DnsTlsServer& server) const REQUIRES(mPrivateDnsLock); void updateServerState(const ServerIdentity& identity, Validation state, uint32_t netId) void updateServerState(const ServerIdentity& identity, Validation state, uint32_t netId) REQUIRES(mPrivateDnsLock); REQUIRES(mPrivateDnsLock); // For testing. base::Result<IPrivateDnsServer*> getPrivateDns(const ServerIdentity& identity, unsigned netId) EXCLUDES(mPrivateDnsLock); base::Result<IPrivateDnsServer*> getPrivateDnsLocked(const ServerIdentity& identity, unsigned netId) REQUIRES(mPrivateDnsLock); void initDohLocked() REQUIRES(mPrivateDnsLock); void initDohLocked() REQUIRES(mPrivateDnsLock); int setDoh(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, int setDoh(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, const std::string& name, const std::string& caCert) REQUIRES(mPrivateDnsLock); const std::string& name, const std::string& caCert) REQUIRES(mPrivateDnsLock); Loading @@ -175,7 +172,8 @@ class PrivateDnsConfiguration { // In case a server is removed due to a configuration change, it remains in this map, // In case a server is removed due to a configuration change, it remains in this map, // but is marked inactive. // but is marked inactive. // Any pending validation threads will continue running because we have no way to cancel them. // Any pending validation threads will continue running because we have no way to cancel them. std::map<unsigned, PrivateDnsTracker> mPrivateDnsTransports GUARDED_BY(mPrivateDnsLock); std::map<unsigned, std::map<ServerIdentity, DnsTlsServer>> mDotTracker GUARDED_BY(mPrivateDnsLock); void notifyValidationStateUpdate(const netdutils::IPSockAddr& sockaddr, Validation validation, void notifyValidationStateUpdate(const netdutils::IPSockAddr& sockaddr, Validation validation, uint32_t netId) const REQUIRES(mPrivateDnsLock); uint32_t netId) const REQUIRES(mPrivateDnsLock); Loading Loading
DnsTlsDispatcher.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -229,7 +229,7 @@ DnsTlsTransport::Response DnsTlsDispatcher::query(const DnsTlsServer& server, un // happens, the xport will be marked as unusable and DoT queries won't be sent to // happens, the xport will be marked as unusable and DoT queries won't be sent to // it anymore. Eventually, after IDLE_TIMEOUT, the xport will be destroyed, and // it anymore. Eventually, after IDLE_TIMEOUT, the xport will be destroyed, and // a new xport will be created. // a new xport will be created. const auto result = PrivateDnsConfiguration::getInstance().requestValidation( const auto result = PrivateDnsConfiguration::getInstance().requestDotValidation( netId, PrivateDnsConfiguration::ServerIdentity{server}, mark); netId, PrivateDnsConfiguration::ServerIdentity{server}, mark); LOG(WARNING) << "Requested validation for " << server.toIpString() << " with mark 0x" LOG(WARNING) << "Requested validation for " << server.toIpString() << " with mark 0x" << std::hex << mark << ", " << std::hex << mark << ", " Loading
DnsTlsServer.h +11 −16 Original line number Original line Diff line number Diff line Loading @@ -20,23 +20,23 @@ #include <string> #include <string> #include <vector> #include <vector> #include <netdutils/InternetAddresses.h> #include <netinet/in.h> #include <netinet/in.h> #include <params.h> #include <params.h> #include "IPrivateDnsServer.h" #include "PrivateDnsCommon.h" namespace android { namespace android { namespace net { namespace net { // DnsTlsServer represents a recursive resolver that supports, or may support, a // DnsTlsServer represents a recursive resolver that supports, or may support, a // secure protocol. // secure protocol. struct DnsTlsServer : public IPrivateDnsServer { struct DnsTlsServer { // Default constructor. // Default constructor. DnsTlsServer() {} DnsTlsServer() {} explicit DnsTlsServer(const netdutils::IPAddress& ip) explicit DnsTlsServer(const netdutils::IPAddress& ip) : DnsTlsServer(netdutils::IPSockAddr(ip, 853)) {} : DnsTlsServer(netdutils::IPSockAddr(ip, kDotPort)) {} explicit DnsTlsServer(const netdutils::IPSockAddr& addr) : ss(addr) {} explicit DnsTlsServer(const netdutils::IPSockAddr& addr) : ss(addr) {} // The server location, including IP and port. // The server location, including IP and port. Loading Loading @@ -64,17 +64,12 @@ struct DnsTlsServer : public IPrivateDnsServer { bool wasExplicitlyConfigured() const; bool wasExplicitlyConfigured() const; std::string toIpString() const; std::string toIpString() const; PrivateDnsTransport transport() const override { return PrivateDnsTransport::kDot; } std::string provider() const { return name; } std::string provider() const override { return name; } netdutils::IPSockAddr addr() const { return netdutils::IPSockAddr::toIPSockAddr(ss); } netdutils::IPSockAddr addr() const override { return netdutils::IPSockAddr::toIPSockAddr(ss); } uint32_t validationMark() const { return mark; } uint32_t validationMark() const override { return mark; } Validation validationState() const override { return mValidation; } Validation validationState() const { return mValidation; } void setValidationState(Validation val) override { mValidation = val; } void setValidationState(Validation val) { mValidation = val; } bool probe() override { // TODO: implement it. return false; } // The socket mark used for validation. // The socket mark used for validation. // Note that the mark of a connection to which the DnsResolver sends app's DNS requests can // Note that the mark of a connection to which the DnsResolver sends app's DNS requests can Loading @@ -84,8 +79,8 @@ struct DnsTlsServer : public IPrivateDnsServer { // Return whether or not the server can be used for a network. It depends on // Return whether or not the server can be used for a network. It depends on // the resolver configuration. // the resolver configuration. bool active() const override { return mActive; } bool active() const { return mActive; } void setActive(bool val) override { mActive = val; } void setActive(bool val) { mActive = val; } private: private: // State, unrelated to the comparison of DnsTlsServer objects. // State, unrelated to the comparison of DnsTlsServer objects. Loading
IPrivateDnsServer.hdeleted 100644 → 0 +0 −60 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <string> #include <netdutils/InternetAddresses.h> #include "PrivateDnsCommon.h" namespace android::net { class IPrivateDnsServer { public: virtual ~IPrivateDnsServer(){}; virtual PrivateDnsTransport transport() const = 0; bool isDot() const { return transport() == PrivateDnsTransport::kDot; } bool isDoh() const { return transport() == PrivateDnsTransport::kDoh; } // Returns the provider name of the server. virtual std::string provider() const = 0; // Returns the IP address of the server. virtual netdutils::IPSockAddr addr() const = 0; // Returns the socket mark used for probe. virtual uint32_t validationMark() const = 0; // Sets the validation state. virtual void setValidationState(Validation val) = 0; // Returns the validation state. virtual Validation validationState() const = 0; // Checks the server supports private DNS. virtual bool probe() = 0; // Sets if the server should be active. virtual void setActive(bool val) = 0; // Returns if the server is active. virtual bool active() const = 0; }; } // namespace android::net
PrivateDnsConfiguration.cpp +49 −51 Original line number Original line Diff line number Diff line Loading @@ -96,38 +96,38 @@ int PrivateDnsConfiguration::setDot(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, const std::vector<std::string>& servers, const std::string& name, const std::string& caCert) { const std::string& name, const std::string& caCert) { // Parse the list of servers that has been passed in // Parse the list of servers that has been passed in PrivateDnsTracker tmp; std::map<ServerIdentity, DnsTlsServer> tmp; for (const auto& s : servers) { for (const auto& s : servers) { // The IP addresses are guaranteed to be valid. // The IP addresses are guaranteed to be valid. auto server = std::make_unique<DnsTlsServer>(IPAddress::forString(s)); DnsTlsServer server(IPAddress::forString(s)); server->name = name; server.name = name; server->certificate = caCert; server.certificate = caCert; server->mark = mark; server.mark = mark; tmp[ServerIdentity(*server)] = std::move(server); tmp[ServerIdentity(server)] = server; } } // Create the tracker if it was not present // Create the tracker if it was not present auto& tracker = mPrivateDnsTransports[netId]; auto& tracker = mDotTracker[netId]; // Add the servers if not contained in tracker. // Add the servers if not contained in tracker. for (auto& [identity, server] : tmp) { for (const auto& [identity, server] : tmp) { if (tracker.find(identity) == tracker.end()) { if (tracker.find(identity) == tracker.end()) { tracker[identity] = std::move(server); tracker[identity] = server; } } } } for (auto& [identity, server] : tracker) { for (auto& [identity, server] : tracker) { const bool active = tmp.find(identity) != tmp.end(); const bool active = tmp.find(identity) != tmp.end(); server->setActive(active); server.setActive(active); // For simplicity, deem the validation result of inactive servers as unreliable. // For simplicity, deem the validation result of inactive servers as unreliable. if (!server->active() && server->validationState() == Validation::success) { if (!server.active() && server.validationState() == Validation::success) { updateServerState(identity, Validation::success_but_expired, netId); updateServerState(identity, Validation::success_but_expired, netId); } } if (needsValidation(*server)) { if (needsValidation(server)) { updateServerState(identity, Validation::in_process, netId); updateServerState(identity, Validation::in_process, netId); startValidation(identity, netId, false); startDotValidation(identity, netId, false); } } } } Loading @@ -135,7 +135,7 @@ int PrivateDnsConfiguration::setDot(int32_t netId, uint32_t mark, } } void PrivateDnsConfiguration::clearDot(int32_t netId) { void PrivateDnsConfiguration::clearDot(int32_t netId) { mPrivateDnsTransports.erase(netId); mDotTracker.erase(netId); resolv_stats_set_addrs(netId, PROTO_DOT, {}, kDotPort); resolv_stats_set_addrs(netId, PROTO_DOT, {}, kDotPort); } } Loading @@ -151,12 +151,11 @@ PrivateDnsStatus PrivateDnsConfiguration::getStatus(unsigned netId) const { if (mode == mPrivateDnsModes.end()) return status; if (mode == mPrivateDnsModes.end()) return status; status.mode = mode->second; status.mode = mode->second; const auto netPair = mPrivateDnsTransports.find(netId); const auto netPair = mDotTracker.find(netId); if (netPair != mPrivateDnsTransports.end()) { if (netPair != mDotTracker.end()) { for (const auto& [_, server] : netPair->second) { for (const auto& [_, server] : netPair->second) { if (server->isDot() && server->active()) { if (server.active()) { DnsTlsServer& dotServer = *static_cast<DnsTlsServer*>(server.get()); status.dotServersMap.emplace(server, server.validationState()); status.dotServersMap.emplace(dotServer, server->validationState()); } } } } } } Loading @@ -182,7 +181,7 @@ void PrivateDnsConfiguration::clear(unsigned netId) { mCv.notify_all(); mCv.notify_all(); } } base::Result<void> PrivateDnsConfiguration::requestValidation(unsigned netId, base::Result<void> PrivateDnsConfiguration::requestDotValidation(unsigned netId, const ServerIdentity& identity, const ServerIdentity& identity, uint32_t mark) { uint32_t mark) { std::lock_guard guard(mPrivateDnsLock); std::lock_guard guard(mPrivateDnsLock); Loading @@ -197,37 +196,37 @@ base::Result<void> PrivateDnsConfiguration::requestValidation(unsigned netId, return Errorf("Private DNS setting is not opportunistic mode"); return Errorf("Private DNS setting is not opportunistic mode"); } } auto result = getPrivateDnsLocked(identity, netId); auto result = getDotServerLocked(identity, netId); if (!result.ok()) { if (!result.ok()) { return result.error(); return result.error(); } } const IPrivateDnsServer* server = result.value(); const DnsTlsServer* target = result.value(); if (!server->active()) return Errorf("Server is not active"); if (!target->active()) return Errorf("Server is not active"); if (server->validationState() != Validation::success) { if (target->validationState() != Validation::success) { return Errorf("Server validation state mismatched"); return Errorf("Server validation state mismatched"); } } // Don't run the validation if |mark| (from android_net_context.dns_mark) is different. // Don't run the validation if |mark| (from android_net_context.dns_mark) is different. // This is to protect validation from running on unexpected marks. // This is to protect validation from running on unexpected marks. // Validation should be associated with a mark gotten by system permission. // Validation should be associated with a mark gotten by system permission. if (server->validationMark() != mark) return Errorf("Socket mark mismatched"); if (target->validationMark() != mark) return Errorf("Socket mark mismatched"); updateServerState(identity, Validation::in_process, netId); updateServerState(identity, Validation::in_process, netId); startValidation(identity, netId, true); startDotValidation(identity, netId, true); return {}; return {}; } } void PrivateDnsConfiguration::startValidation(const ServerIdentity& identity, unsigned netId, void PrivateDnsConfiguration::startDotValidation(const ServerIdentity& identity, unsigned netId, bool isRevalidation) { bool isRevalidation) { // This ensures that the thread sends probe at least once in case // This ensures that the thread sends probe at least once in case // the server is removed before the thread starts running. // the server is removed before the thread starts running. // TODO: consider moving these code to the thread. // TODO: consider moving these code to the thread. const auto result = getPrivateDnsLocked(identity, netId); const auto result = getDotServerLocked(identity, netId); if (!result.ok()) return; if (!result.ok()) return; DnsTlsServer server = *static_cast<const DnsTlsServer*>(result.value()); DnsTlsServer server = *result.value(); std::thread validate_thread([this, identity, server, netId, isRevalidation] { std::thread validate_thread([this, identity, server, netId, isRevalidation] { setThreadName(fmt::format("TlsVerify_{}", netId)); setThreadName(fmt::format("TlsVerify_{}", netId)); Loading Loading @@ -257,7 +256,7 @@ void PrivateDnsConfiguration::startValidation(const ServerIdentity& identity, un << server.toIpString(); << server.toIpString(); const bool needs_reeval = const bool needs_reeval = this->recordPrivateDnsValidation(identity, netId, success, isRevalidation); this->recordDotValidation(identity, netId, success, isRevalidation); if (!needs_reeval || !backoff.hasNextTimeout()) { if (!needs_reeval || !backoff.hasNextTimeout()) { break; break; Loading Loading @@ -310,16 +309,15 @@ void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const ServerIdentity } } } } bool PrivateDnsConfiguration::recordPrivateDnsValidation(const ServerIdentity& identity, bool PrivateDnsConfiguration::recordDotValidation(const ServerIdentity& identity, unsigned netId, unsigned netId, bool success, bool success, bool isRevalidation) { bool isRevalidation) { constexpr bool NEEDS_REEVALUATION = true; constexpr bool NEEDS_REEVALUATION = true; constexpr bool DONT_REEVALUATE = false; constexpr bool DONT_REEVALUATE = false; std::lock_guard guard(mPrivateDnsLock); std::lock_guard guard(mPrivateDnsLock); auto netPair = mPrivateDnsTransports.find(netId); auto netPair = mDotTracker.find(netId); if (netPair == mPrivateDnsTransports.end()) { if (netPair == mDotTracker.end()) { LOG(WARNING) << "netId " << netId << " was erased during private DNS validation"; LOG(WARNING) << "netId " << netId << " was erased during private DNS validation"; notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); return DONT_REEVALUATE; return DONT_REEVALUATE; Loading @@ -345,7 +343,7 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const ServerIdentity& i << " was removed during private DNS validation"; << " was removed during private DNS validation"; success = false; success = false; reevaluationStatus = DONT_REEVALUATE; reevaluationStatus = DONT_REEVALUATE; } else if (!serverPair->second->active()) { } else if (!serverPair->second.active()) { LOG(WARNING) << "Server " << identity.sockaddr.ip().toString() LOG(WARNING) << "Server " << identity.sockaddr.ip().toString() << " was removed from the configuration"; << " was removed from the configuration"; success = false; success = false; Loading Loading @@ -374,7 +372,7 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const ServerIdentity& i void PrivateDnsConfiguration::updateServerState(const ServerIdentity& identity, Validation state, void PrivateDnsConfiguration::updateServerState(const ServerIdentity& identity, Validation state, uint32_t netId) { uint32_t netId) { const auto result = getPrivateDnsLocked(identity, netId); const auto result = getDotServerLocked(identity, netId); if (!result.ok()) { if (!result.ok()) { notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); return; return; Loading @@ -389,7 +387,7 @@ void PrivateDnsConfiguration::updateServerState(const ServerIdentity& identity, mPrivateDnsLog.push(std::move(record)); mPrivateDnsLog.push(std::move(record)); } } bool PrivateDnsConfiguration::needsValidation(const IPrivateDnsServer& server) const { bool PrivateDnsConfiguration::needsValidation(const DnsTlsServer& server) const { // The server is not expected to be used on the network. // The server is not expected to be used on the network. if (!server.active()) return false; if (!server.active()) return false; Loading @@ -405,16 +403,16 @@ bool PrivateDnsConfiguration::needsValidation(const IPrivateDnsServer& server) c return false; return false; } } base::Result<IPrivateDnsServer*> PrivateDnsConfiguration::getPrivateDns( base::Result<DnsTlsServer*> PrivateDnsConfiguration::getDotServer(const ServerIdentity& identity, const ServerIdentity& identity, unsigned netId) { unsigned netId) { std::lock_guard guard(mPrivateDnsLock); std::lock_guard guard(mPrivateDnsLock); return getPrivateDnsLocked(identity, netId); return getDotServerLocked(identity, netId); } } base::Result<IPrivateDnsServer*> PrivateDnsConfiguration::getPrivateDnsLocked( base::Result<DnsTlsServer*> PrivateDnsConfiguration::getDotServerLocked( const ServerIdentity& identity, unsigned netId) { const ServerIdentity& identity, unsigned netId) { auto netPair = mPrivateDnsTransports.find(netId); auto netPair = mDotTracker.find(netId); if (netPair == mPrivateDnsTransports.end()) { if (netPair == mDotTracker.end()) { return Errorf("Failed to get private DNS: netId {} not found", netId); return Errorf("Failed to get private DNS: netId {} not found", netId); } } Loading @@ -424,7 +422,7 @@ base::Result<IPrivateDnsServer*> PrivateDnsConfiguration::getPrivateDnsLocked( identity.provider); identity.provider); } } return iter->second.get(); return &iter->second; } } void PrivateDnsConfiguration::setObserver(PrivateDnsValidationObserver* observer) { void PrivateDnsConfiguration::setObserver(PrivateDnsValidationObserver* observer) { Loading Loading @@ -606,12 +604,12 @@ bool PrivateDnsConfiguration::needReportEvent(uint32_t netId, ServerIdentity ide switch (identity.sockaddr.port()) { switch (identity.sockaddr.port()) { // DoH // DoH case kDohPort: { case kDohPort: { auto netPair = mPrivateDnsTransports.find(netId); auto netPair = mDotTracker.find(netId); if (netPair == mPrivateDnsTransports.end()) return true; if (netPair == mDotTracker.end()) return true; for (const auto& [id, server] : netPair->second) { for (const auto& [id, server] : netPair->second) { if ((identity.sockaddr.ip() == id.sockaddr.ip()) && if ((identity.sockaddr.ip() == id.sockaddr.ip()) && (identity.sockaddr.port() != id.sockaddr.port()) && (identity.sockaddr.port() != id.sockaddr.port()) && (server->validationState() == Validation::success)) { (server.validationState() == Validation::success)) { LOG(DEBUG) << __func__ LOG(DEBUG) << __func__ << ": Skip reporting DoH validation failure event, server addr: " << ": Skip reporting DoH validation failure event, server addr: " << identity.sockaddr.ip().toString(); << identity.sockaddr.ip().toString(); Loading
PrivateDnsConfiguration.h +17 −19 Original line number Original line Diff line number Diff line Loading @@ -39,7 +39,6 @@ namespace android { namespace android { namespace net { namespace net { // TODO: decouple the dependency of DnsTlsServer. struct PrivateDnsStatus { struct PrivateDnsStatus { PrivateDnsMode mode; PrivateDnsMode mode; Loading Loading @@ -81,7 +80,7 @@ class PrivateDnsConfiguration { const netdutils::IPSockAddr sockaddr; const netdutils::IPSockAddr sockaddr; const std::string provider; const std::string provider; explicit ServerIdentity(const IPrivateDnsServer& server) explicit ServerIdentity(const DnsTlsServer& server) : sockaddr(server.addr()), provider(server.provider()) {} : sockaddr(server.addr()), provider(server.provider()) {} ServerIdentity(const netdutils::IPSockAddr& addr, const std::string& host) ServerIdentity(const netdutils::IPSockAddr& addr, const std::string& host) : sockaddr(addr), provider(host) {} : sockaddr(addr), provider(host) {} Loading Loading @@ -114,7 +113,7 @@ class PrivateDnsConfiguration { // Request the server to be revalidated on a connection tagged with |mark|. // Request the server to be revalidated on a connection tagged with |mark|. // Returns a Result to indicate if the request is accepted. // Returns a Result to indicate if the request is accepted. base::Result<void> requestValidation(unsigned netId, const ServerIdentity& identity, base::Result<void> requestDotValidation(unsigned netId, const ServerIdentity& identity, uint32_t mark) EXCLUDES(mPrivateDnsLock); uint32_t mark) EXCLUDES(mPrivateDnsLock); void setObserver(PrivateDnsValidationObserver* observer); void setObserver(PrivateDnsValidationObserver* observer); Loading @@ -128,8 +127,6 @@ class PrivateDnsConfiguration { EXCLUDES(mPrivateDnsLock); EXCLUDES(mPrivateDnsLock); private: private: typedef std::map<ServerIdentity, std::unique_ptr<IPrivateDnsServer>> PrivateDnsTracker; PrivateDnsConfiguration() = default; PrivateDnsConfiguration() = default; int setDot(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, int setDot(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, Loading @@ -137,12 +134,19 @@ class PrivateDnsConfiguration { void clearDot(int32_t netId) REQUIRES(mPrivateDnsLock); void clearDot(int32_t netId) REQUIRES(mPrivateDnsLock); // Launchs a thread to run the validation for |server| on the network |netId|. // For testing. base::Result<DnsTlsServer*> getDotServer(const ServerIdentity& identity, unsigned netId) EXCLUDES(mPrivateDnsLock); base::Result<DnsTlsServer*> getDotServerLocked(const ServerIdentity& identity, unsigned netId) REQUIRES(mPrivateDnsLock); // Launchs a thread to run the validation for the DoT server |server| on the network |netId|. // |isRevalidation| is true if this call is due to a revalidation request. // |isRevalidation| is true if this call is due to a revalidation request. void startValidation(const ServerIdentity& identity, unsigned netId, bool isRevalidation) void startDotValidation(const ServerIdentity& identity, unsigned netId, bool isRevalidation) REQUIRES(mPrivateDnsLock); REQUIRES(mPrivateDnsLock); bool recordPrivateDnsValidation(const ServerIdentity& identity, unsigned netId, bool success, bool recordDotValidation(const ServerIdentity& identity, unsigned netId, bool success, bool isRevalidation) EXCLUDES(mPrivateDnsLock); bool isRevalidation) EXCLUDES(mPrivateDnsLock); void sendPrivateDnsValidationEvent(const ServerIdentity& identity, unsigned netId, void sendPrivateDnsValidationEvent(const ServerIdentity& identity, unsigned netId, Loading @@ -151,18 +155,11 @@ class PrivateDnsConfiguration { // Decide if a validation for |server| is needed. Note that servers that have failed // Decide if a validation for |server| is needed. Note that servers that have failed // multiple validation attempts but for which there is still a validating // multiple validation attempts but for which there is still a validating // thread running are marked as being Validation::in_process. // thread running are marked as being Validation::in_process. bool needsValidation(const IPrivateDnsServer& server) const REQUIRES(mPrivateDnsLock); bool needsValidation(const DnsTlsServer& server) const REQUIRES(mPrivateDnsLock); void updateServerState(const ServerIdentity& identity, Validation state, uint32_t netId) void updateServerState(const ServerIdentity& identity, Validation state, uint32_t netId) REQUIRES(mPrivateDnsLock); REQUIRES(mPrivateDnsLock); // For testing. base::Result<IPrivateDnsServer*> getPrivateDns(const ServerIdentity& identity, unsigned netId) EXCLUDES(mPrivateDnsLock); base::Result<IPrivateDnsServer*> getPrivateDnsLocked(const ServerIdentity& identity, unsigned netId) REQUIRES(mPrivateDnsLock); void initDohLocked() REQUIRES(mPrivateDnsLock); void initDohLocked() REQUIRES(mPrivateDnsLock); int setDoh(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, int setDoh(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, const std::string& name, const std::string& caCert) REQUIRES(mPrivateDnsLock); const std::string& name, const std::string& caCert) REQUIRES(mPrivateDnsLock); Loading @@ -175,7 +172,8 @@ class PrivateDnsConfiguration { // In case a server is removed due to a configuration change, it remains in this map, // In case a server is removed due to a configuration change, it remains in this map, // but is marked inactive. // but is marked inactive. // Any pending validation threads will continue running because we have no way to cancel them. // Any pending validation threads will continue running because we have no way to cancel them. std::map<unsigned, PrivateDnsTracker> mPrivateDnsTransports GUARDED_BY(mPrivateDnsLock); std::map<unsigned, std::map<ServerIdentity, DnsTlsServer>> mDotTracker GUARDED_BY(mPrivateDnsLock); void notifyValidationStateUpdate(const netdutils::IPSockAddr& sockaddr, Validation validation, void notifyValidationStateUpdate(const netdutils::IPSockAddr& sockaddr, Validation validation, uint32_t netId) const REQUIRES(mPrivateDnsLock); uint32_t netId) const REQUIRES(mPrivateDnsLock); Loading