Loading DnsTlsDispatcher.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -214,8 +214,8 @@ DnsTlsTransport::Response DnsTlsDispatcher::query(const DnsTlsServer& server, un // 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 // a new xport will be created. const auto result = PrivateDnsConfiguration::getInstance().requestValidation(netId, server, mark); const auto result = PrivateDnsConfiguration::getInstance().requestValidation( netId, PrivateDnsConfiguration::ServerIdentity{server}, mark); LOG(WARNING) << "Requested validation for " << server.toIpString() << " with mark 0x" << std::hex << mark << ", " << (result.ok() ? "succeeded" : "failed: " + result.error().message()); Loading DnsTlsServer.h +15 −6 Original line number Diff line number Diff line Loading @@ -24,14 +24,14 @@ #include <params.h> #include "PrivateDnsCommon.h" #include "IPrivateDnsServer.h" namespace android { namespace net { // DnsTlsServer represents a recursive resolver that supports, or may support, a // secure protocol. struct DnsTlsServer { struct DnsTlsServer : public IPrivateDnsServer { // Default constructor. DnsTlsServer() {} Loading Loading @@ -63,8 +63,17 @@ struct DnsTlsServer { bool wasExplicitlyConfigured() const; std::string toIpString() const; Validation validationState() const { return mValidation; } void setValidationState(Validation val) { mValidation = val; } PrivateDnsTransport transport() const override { return PrivateDnsTransport::kDot; } std::string provider() const override { return name; } netdutils::IPSockAddr addr() const override { return netdutils::IPSockAddr::toIPSockAddr(ss); } uint32_t validationMark() const override { return mark; } Validation validationState() const override { return mValidation; } void setValidationState(Validation val) override { mValidation = val; } bool probe() override { // TODO: implement it. return false; } // The socket mark used for validation. // Note that the mark of a connection to which the DnsResolver sends app's DNS requests can Loading @@ -74,8 +83,8 @@ struct DnsTlsServer { // Return whether or not the server can be used for a network. It depends on // the resolver configuration. bool active() const { return mActive; } void setActive(bool val) { mActive = val; } bool active() const override { return mActive; } void setActive(bool val) override { mActive = val; } private: // State, unrelated to the comparison of DnsTlsServer objects. Loading IPrivateDnsServer.h 0 → 100644 +60 −0 Original line number 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 PrivateDnsCommon.h +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,11 @@ namespace android::net { enum class PrivateDnsTransport : uint8_t { kDot, // DNS over TLS. kDoh, // DNS over HTTPS. }; // Validation status of a private DNS server on a specific netId. enum class Validation : uint8_t { in_process, Loading PrivateDnsConfiguration.cpp +79 −63 Original line number Diff line number Diff line Loading @@ -70,11 +70,11 @@ int PrivateDnsConfiguration::set(int32_t netId, uint32_t mark, if (!parseServer(s.c_str(), &parsed)) { return -EINVAL; } DnsTlsServer server(parsed); server.name = name; server.certificate = caCert; server.mark = mark; tmp[ServerIdentity(server)] = server; auto server = std::make_unique<DnsTlsServer>(parsed); server->name = name; server->certificate = caCert; server->mark = mark; tmp[ServerIdentity(*server)] = std::move(server); } std::lock_guard guard(mPrivateDnsLock); Loading @@ -93,24 +93,24 @@ int PrivateDnsConfiguration::set(int32_t netId, uint32_t mark, auto& tracker = mPrivateDnsTransports[netId]; // Add the servers if not contained in tracker. for (const auto& [identity, server] : tmp) { for (auto& [identity, server] : tmp) { if (tracker.find(identity) == tracker.end()) { tracker[identity] = server; tracker[identity] = std::move(server); } } for (auto& [identity, server] : tracker) { 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. if (!server.active() && server.validationState() == Validation::success) { if (!server->active() && server->validationState() == Validation::success) { updateServerState(identity, Validation::success_but_expired, netId); } if (needsValidation(server)) { if (needsValidation(*server)) { updateServerState(identity, Validation::in_process, netId); startValidation(server, netId, false); startValidation(identity, netId, false); } } Loading @@ -128,9 +128,11 @@ PrivateDnsStatus PrivateDnsConfiguration::getStatus(unsigned netId) const { const auto netPair = mPrivateDnsTransports.find(netId); if (netPair != mPrivateDnsTransports.end()) { for (const auto& [_, server] : netPair->second) { if (server.active()) { status.serversMap.emplace(server, server.validationState()); if (server->isDot() && server->active()) { DnsTlsServer& dotServer = *static_cast<DnsTlsServer*>(server.get()); status.serversMap.emplace(dotServer, server->validationState()); } // TODO: also add DoH server to the map. } } Loading @@ -145,7 +147,7 @@ void PrivateDnsConfiguration::clear(unsigned netId) { } base::Result<void> PrivateDnsConfiguration::requestValidation(unsigned netId, const DnsTlsServer& server, const ServerIdentity& identity, uint32_t mark) { std::lock_guard guard(mPrivateDnsLock); Loading @@ -159,40 +161,39 @@ base::Result<void> PrivateDnsConfiguration::requestValidation(unsigned netId, return Errorf("Private DNS setting is not opportunistic mode"); } auto netPair = mPrivateDnsTransports.find(netId); if (netPair == mPrivateDnsTransports.end()) { return Errorf("NetId not found in mPrivateDnsTransports"); auto result = getPrivateDnsLocked(identity, netId); if (!result.ok()) { return result.error(); } auto& tracker = netPair->second; const ServerIdentity identity = ServerIdentity(server); auto it = tracker.find(identity); if (it == tracker.end()) { return Errorf("Server was removed"); } const IPrivateDnsServer* server = result.value(); const DnsTlsServer& target = it->second; if (!server->active()) return Errorf("Server is not active"); if (!target.active()) return Errorf("Server is not active"); if (target.validationState() != Validation::success) { if (server->validationState() != Validation::success) { return Errorf("Server validation state mismatched"); } // 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. // Validation should be associated with a mark gotten by system permission. if (target.mark != mark) return Errorf("Socket mark mismatched"); if (server->validationMark() != mark) return Errorf("Socket mark mismatched"); updateServerState(identity, Validation::in_process, netId); startValidation(target, netId, true); startValidation(identity, netId, true); return {}; } void PrivateDnsConfiguration::startValidation(const DnsTlsServer& server, unsigned netId, bool isRevalidation) REQUIRES(mPrivateDnsLock) { // Note that capturing |server|, |netId|, and |isRevalidation| in this lambda create copies. std::thread validate_thread([this, server, netId, isRevalidation] { void PrivateDnsConfiguration::startValidation(const ServerIdentity& identity, unsigned netId, bool isRevalidation) { // This ensures that the thread sends probe at least once in case // the server is removed before the thread starts running. // TODO: consider moving these code to the thread. const auto result = getPrivateDnsLocked(identity, netId); if (!result.ok()) return; DnsTlsServer server = *static_cast<const DnsTlsServer*>(result.value()); std::thread validate_thread([this, identity, server, netId, isRevalidation] { setThreadName(StringPrintf("TlsVerify_%u", netId).c_str()); // cat /proc/sys/net/ipv4/tcp_syn_retries yields "6". Loading @@ -217,13 +218,13 @@ void PrivateDnsConfiguration::startValidation(const DnsTlsServer& server, unsign // ::validate() is a blocking call that performs network operations. // It can take milliseconds to minutes, up to the SYN retry limit. LOG(WARNING) << "Validating DnsTlsServer " << server.toIpString() << " with mark 0x" << std::hex << server.mark; const bool success = DnsTlsTransport::validate(server, server.mark); << std::hex << server.validationMark(); const bool success = DnsTlsTransport::validate(server, server.validationMark()); LOG(WARNING) << "validateDnsTlsServer returned " << success << " for " << server.toIpString(); const bool needs_reeval = this->recordPrivateDnsValidation(server, netId, success, isRevalidation); this->recordPrivateDnsValidation(identity, netId, success, isRevalidation); if (!needs_reeval) { break; Loading @@ -240,11 +241,11 @@ void PrivateDnsConfiguration::startValidation(const DnsTlsServer& server, unsign validate_thread.detach(); } void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const DnsTlsServer& server, void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const ServerIdentity& identity, unsigned netId, bool success) { LOG(DEBUG) << "Sending validation " << (success ? "success" : "failure") << " event on netId " << netId << " for " << server.toIpString() << " with hostname {" << server.name << "}"; << netId << " for " << identity.sockaddr.ip().toString() << " with hostname {" << identity.provider << "}"; // Send a validation event to NetdEventListenerService. const auto& listeners = ResolverEventReporter::getInstance().getListeners(); if (listeners.empty()) { Loading @@ -252,15 +253,16 @@ void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const DnsTlsServer& << "Validation event not sent since no INetdEventListener receiver is available."; } for (const auto& it : listeners) { it->onPrivateDnsValidationEvent(netId, server.toIpString(), server.name, success); it->onPrivateDnsValidationEvent(netId, identity.sockaddr.ip().toString(), identity.provider, success); } // Send a validation event to unsolicited event listeners. const auto& unsolEventListeners = ResolverEventReporter::getInstance().getUnsolEventListeners(); const PrivateDnsValidationEventParcel validationEvent = { .netId = static_cast<int32_t>(netId), .ipAddress = server.toIpString(), .hostname = server.name, .ipAddress = identity.sockaddr.ip().toString(), .hostname = identity.provider, .validation = success ? IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_SUCCESS : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE, }; Loading @@ -269,11 +271,11 @@ void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const DnsTlsServer& } } bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool success, bool isRevalidation) { bool PrivateDnsConfiguration::recordPrivateDnsValidation(const ServerIdentity& identity, unsigned netId, bool success, bool isRevalidation) { constexpr bool NEEDS_REEVALUATION = true; constexpr bool DONT_REEVALUATE = false; const ServerIdentity identity = ServerIdentity(server); std::lock_guard guard(mPrivateDnsLock); Loading Loading @@ -303,23 +305,19 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& ser auto& tracker = netPair->second; auto serverPair = tracker.find(identity); if (serverPair == tracker.end()) { LOG(WARNING) << "Server " << server.toIpString() LOG(WARNING) << "Server " << identity.sockaddr.ip().toString() << " was removed during private DNS validation"; success = false; reevaluationStatus = DONT_REEVALUATE; } else if (!(serverPair->second == server)) { LOG(WARNING) << "Server " << server.toIpString() << " was changed during private DNS validation"; success = false; reevaluationStatus = DONT_REEVALUATE; } else if (!serverPair->second.active()) { LOG(WARNING) << "Server " << server.toIpString() << " was removed from the configuration"; } else if (!serverPair->second->active()) { LOG(WARNING) << "Server " << identity.sockaddr.ip().toString() << " was removed from the configuration"; success = false; reevaluationStatus = DONT_REEVALUATE; } // Send private dns validation result to listeners. sendPrivateDnsValidationEvent(server, netId, success); sendPrivateDnsValidationEvent(identity, netId, success); if (success) { updateServerState(identity, Validation::success, netId); Loading @@ -338,26 +336,22 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& ser void PrivateDnsConfiguration::updateServerState(const ServerIdentity& identity, Validation state, uint32_t netId) { auto netPair = mPrivateDnsTransports.find(netId); if (netPair == mPrivateDnsTransports.end()) { const auto result = getPrivateDnsLocked(identity, netId); if (!result.ok()) { notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); return; } auto& tracker = netPair->second; if (tracker.find(identity) == tracker.end()) { notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); return; } auto* server = result.value(); tracker[identity].setValidationState(state); server->setValidationState(state); notifyValidationStateUpdate(identity.sockaddr, state, netId); RecordEntry record(netId, identity, state); mPrivateDnsLog.push(std::move(record)); } bool PrivateDnsConfiguration::needsValidation(const DnsTlsServer& server) { bool PrivateDnsConfiguration::needsValidation(const IPrivateDnsServer& server) const { // The server is not expected to be used on the network. if (!server.active()) return false; Loading @@ -373,6 +367,28 @@ bool PrivateDnsConfiguration::needsValidation(const DnsTlsServer& server) { return false; } base::Result<IPrivateDnsServer*> PrivateDnsConfiguration::getPrivateDns( const ServerIdentity& identity, unsigned netId) { std::lock_guard guard(mPrivateDnsLock); return getPrivateDnsLocked(identity, netId); } base::Result<IPrivateDnsServer*> PrivateDnsConfiguration::getPrivateDnsLocked( const ServerIdentity& identity, unsigned netId) { auto netPair = mPrivateDnsTransports.find(netId); if (netPair == mPrivateDnsTransports.end()) { return Errorf("Failed to get private DNS: netId {} not found", netId); } auto iter = netPair->second.find(identity); if (iter == netPair->second.end()) { return Errorf("Failed to get private DNS: server {{{}/{}}} not found", identity.sockaddr, identity.provider); } return iter->second.get(); } void PrivateDnsConfiguration::setObserver(PrivateDnsValidationObserver* observer) { std::lock_guard guard(mPrivateDnsLock); mObserver = observer; Loading Loading
DnsTlsDispatcher.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -214,8 +214,8 @@ DnsTlsTransport::Response DnsTlsDispatcher::query(const DnsTlsServer& server, un // 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 // a new xport will be created. const auto result = PrivateDnsConfiguration::getInstance().requestValidation(netId, server, mark); const auto result = PrivateDnsConfiguration::getInstance().requestValidation( netId, PrivateDnsConfiguration::ServerIdentity{server}, mark); LOG(WARNING) << "Requested validation for " << server.toIpString() << " with mark 0x" << std::hex << mark << ", " << (result.ok() ? "succeeded" : "failed: " + result.error().message()); Loading
DnsTlsServer.h +15 −6 Original line number Diff line number Diff line Loading @@ -24,14 +24,14 @@ #include <params.h> #include "PrivateDnsCommon.h" #include "IPrivateDnsServer.h" namespace android { namespace net { // DnsTlsServer represents a recursive resolver that supports, or may support, a // secure protocol. struct DnsTlsServer { struct DnsTlsServer : public IPrivateDnsServer { // Default constructor. DnsTlsServer() {} Loading Loading @@ -63,8 +63,17 @@ struct DnsTlsServer { bool wasExplicitlyConfigured() const; std::string toIpString() const; Validation validationState() const { return mValidation; } void setValidationState(Validation val) { mValidation = val; } PrivateDnsTransport transport() const override { return PrivateDnsTransport::kDot; } std::string provider() const override { return name; } netdutils::IPSockAddr addr() const override { return netdutils::IPSockAddr::toIPSockAddr(ss); } uint32_t validationMark() const override { return mark; } Validation validationState() const override { return mValidation; } void setValidationState(Validation val) override { mValidation = val; } bool probe() override { // TODO: implement it. return false; } // The socket mark used for validation. // Note that the mark of a connection to which the DnsResolver sends app's DNS requests can Loading @@ -74,8 +83,8 @@ struct DnsTlsServer { // Return whether or not the server can be used for a network. It depends on // the resolver configuration. bool active() const { return mActive; } void setActive(bool val) { mActive = val; } bool active() const override { return mActive; } void setActive(bool val) override { mActive = val; } private: // State, unrelated to the comparison of DnsTlsServer objects. Loading
IPrivateDnsServer.h 0 → 100644 +60 −0 Original line number 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
PrivateDnsCommon.h +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,11 @@ namespace android::net { enum class PrivateDnsTransport : uint8_t { kDot, // DNS over TLS. kDoh, // DNS over HTTPS. }; // Validation status of a private DNS server on a specific netId. enum class Validation : uint8_t { in_process, Loading
PrivateDnsConfiguration.cpp +79 −63 Original line number Diff line number Diff line Loading @@ -70,11 +70,11 @@ int PrivateDnsConfiguration::set(int32_t netId, uint32_t mark, if (!parseServer(s.c_str(), &parsed)) { return -EINVAL; } DnsTlsServer server(parsed); server.name = name; server.certificate = caCert; server.mark = mark; tmp[ServerIdentity(server)] = server; auto server = std::make_unique<DnsTlsServer>(parsed); server->name = name; server->certificate = caCert; server->mark = mark; tmp[ServerIdentity(*server)] = std::move(server); } std::lock_guard guard(mPrivateDnsLock); Loading @@ -93,24 +93,24 @@ int PrivateDnsConfiguration::set(int32_t netId, uint32_t mark, auto& tracker = mPrivateDnsTransports[netId]; // Add the servers if not contained in tracker. for (const auto& [identity, server] : tmp) { for (auto& [identity, server] : tmp) { if (tracker.find(identity) == tracker.end()) { tracker[identity] = server; tracker[identity] = std::move(server); } } for (auto& [identity, server] : tracker) { 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. if (!server.active() && server.validationState() == Validation::success) { if (!server->active() && server->validationState() == Validation::success) { updateServerState(identity, Validation::success_but_expired, netId); } if (needsValidation(server)) { if (needsValidation(*server)) { updateServerState(identity, Validation::in_process, netId); startValidation(server, netId, false); startValidation(identity, netId, false); } } Loading @@ -128,9 +128,11 @@ PrivateDnsStatus PrivateDnsConfiguration::getStatus(unsigned netId) const { const auto netPair = mPrivateDnsTransports.find(netId); if (netPair != mPrivateDnsTransports.end()) { for (const auto& [_, server] : netPair->second) { if (server.active()) { status.serversMap.emplace(server, server.validationState()); if (server->isDot() && server->active()) { DnsTlsServer& dotServer = *static_cast<DnsTlsServer*>(server.get()); status.serversMap.emplace(dotServer, server->validationState()); } // TODO: also add DoH server to the map. } } Loading @@ -145,7 +147,7 @@ void PrivateDnsConfiguration::clear(unsigned netId) { } base::Result<void> PrivateDnsConfiguration::requestValidation(unsigned netId, const DnsTlsServer& server, const ServerIdentity& identity, uint32_t mark) { std::lock_guard guard(mPrivateDnsLock); Loading @@ -159,40 +161,39 @@ base::Result<void> PrivateDnsConfiguration::requestValidation(unsigned netId, return Errorf("Private DNS setting is not opportunistic mode"); } auto netPair = mPrivateDnsTransports.find(netId); if (netPair == mPrivateDnsTransports.end()) { return Errorf("NetId not found in mPrivateDnsTransports"); auto result = getPrivateDnsLocked(identity, netId); if (!result.ok()) { return result.error(); } auto& tracker = netPair->second; const ServerIdentity identity = ServerIdentity(server); auto it = tracker.find(identity); if (it == tracker.end()) { return Errorf("Server was removed"); } const IPrivateDnsServer* server = result.value(); const DnsTlsServer& target = it->second; if (!server->active()) return Errorf("Server is not active"); if (!target.active()) return Errorf("Server is not active"); if (target.validationState() != Validation::success) { if (server->validationState() != Validation::success) { return Errorf("Server validation state mismatched"); } // 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. // Validation should be associated with a mark gotten by system permission. if (target.mark != mark) return Errorf("Socket mark mismatched"); if (server->validationMark() != mark) return Errorf("Socket mark mismatched"); updateServerState(identity, Validation::in_process, netId); startValidation(target, netId, true); startValidation(identity, netId, true); return {}; } void PrivateDnsConfiguration::startValidation(const DnsTlsServer& server, unsigned netId, bool isRevalidation) REQUIRES(mPrivateDnsLock) { // Note that capturing |server|, |netId|, and |isRevalidation| in this lambda create copies. std::thread validate_thread([this, server, netId, isRevalidation] { void PrivateDnsConfiguration::startValidation(const ServerIdentity& identity, unsigned netId, bool isRevalidation) { // This ensures that the thread sends probe at least once in case // the server is removed before the thread starts running. // TODO: consider moving these code to the thread. const auto result = getPrivateDnsLocked(identity, netId); if (!result.ok()) return; DnsTlsServer server = *static_cast<const DnsTlsServer*>(result.value()); std::thread validate_thread([this, identity, server, netId, isRevalidation] { setThreadName(StringPrintf("TlsVerify_%u", netId).c_str()); // cat /proc/sys/net/ipv4/tcp_syn_retries yields "6". Loading @@ -217,13 +218,13 @@ void PrivateDnsConfiguration::startValidation(const DnsTlsServer& server, unsign // ::validate() is a blocking call that performs network operations. // It can take milliseconds to minutes, up to the SYN retry limit. LOG(WARNING) << "Validating DnsTlsServer " << server.toIpString() << " with mark 0x" << std::hex << server.mark; const bool success = DnsTlsTransport::validate(server, server.mark); << std::hex << server.validationMark(); const bool success = DnsTlsTransport::validate(server, server.validationMark()); LOG(WARNING) << "validateDnsTlsServer returned " << success << " for " << server.toIpString(); const bool needs_reeval = this->recordPrivateDnsValidation(server, netId, success, isRevalidation); this->recordPrivateDnsValidation(identity, netId, success, isRevalidation); if (!needs_reeval) { break; Loading @@ -240,11 +241,11 @@ void PrivateDnsConfiguration::startValidation(const DnsTlsServer& server, unsign validate_thread.detach(); } void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const DnsTlsServer& server, void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const ServerIdentity& identity, unsigned netId, bool success) { LOG(DEBUG) << "Sending validation " << (success ? "success" : "failure") << " event on netId " << netId << " for " << server.toIpString() << " with hostname {" << server.name << "}"; << netId << " for " << identity.sockaddr.ip().toString() << " with hostname {" << identity.provider << "}"; // Send a validation event to NetdEventListenerService. const auto& listeners = ResolverEventReporter::getInstance().getListeners(); if (listeners.empty()) { Loading @@ -252,15 +253,16 @@ void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const DnsTlsServer& << "Validation event not sent since no INetdEventListener receiver is available."; } for (const auto& it : listeners) { it->onPrivateDnsValidationEvent(netId, server.toIpString(), server.name, success); it->onPrivateDnsValidationEvent(netId, identity.sockaddr.ip().toString(), identity.provider, success); } // Send a validation event to unsolicited event listeners. const auto& unsolEventListeners = ResolverEventReporter::getInstance().getUnsolEventListeners(); const PrivateDnsValidationEventParcel validationEvent = { .netId = static_cast<int32_t>(netId), .ipAddress = server.toIpString(), .hostname = server.name, .ipAddress = identity.sockaddr.ip().toString(), .hostname = identity.provider, .validation = success ? IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_SUCCESS : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE, }; Loading @@ -269,11 +271,11 @@ void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const DnsTlsServer& } } bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool success, bool isRevalidation) { bool PrivateDnsConfiguration::recordPrivateDnsValidation(const ServerIdentity& identity, unsigned netId, bool success, bool isRevalidation) { constexpr bool NEEDS_REEVALUATION = true; constexpr bool DONT_REEVALUATE = false; const ServerIdentity identity = ServerIdentity(server); std::lock_guard guard(mPrivateDnsLock); Loading Loading @@ -303,23 +305,19 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& ser auto& tracker = netPair->second; auto serverPair = tracker.find(identity); if (serverPair == tracker.end()) { LOG(WARNING) << "Server " << server.toIpString() LOG(WARNING) << "Server " << identity.sockaddr.ip().toString() << " was removed during private DNS validation"; success = false; reevaluationStatus = DONT_REEVALUATE; } else if (!(serverPair->second == server)) { LOG(WARNING) << "Server " << server.toIpString() << " was changed during private DNS validation"; success = false; reevaluationStatus = DONT_REEVALUATE; } else if (!serverPair->second.active()) { LOG(WARNING) << "Server " << server.toIpString() << " was removed from the configuration"; } else if (!serverPair->second->active()) { LOG(WARNING) << "Server " << identity.sockaddr.ip().toString() << " was removed from the configuration"; success = false; reevaluationStatus = DONT_REEVALUATE; } // Send private dns validation result to listeners. sendPrivateDnsValidationEvent(server, netId, success); sendPrivateDnsValidationEvent(identity, netId, success); if (success) { updateServerState(identity, Validation::success, netId); Loading @@ -338,26 +336,22 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& ser void PrivateDnsConfiguration::updateServerState(const ServerIdentity& identity, Validation state, uint32_t netId) { auto netPair = mPrivateDnsTransports.find(netId); if (netPair == mPrivateDnsTransports.end()) { const auto result = getPrivateDnsLocked(identity, netId); if (!result.ok()) { notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); return; } auto& tracker = netPair->second; if (tracker.find(identity) == tracker.end()) { notifyValidationStateUpdate(identity.sockaddr, Validation::fail, netId); return; } auto* server = result.value(); tracker[identity].setValidationState(state); server->setValidationState(state); notifyValidationStateUpdate(identity.sockaddr, state, netId); RecordEntry record(netId, identity, state); mPrivateDnsLog.push(std::move(record)); } bool PrivateDnsConfiguration::needsValidation(const DnsTlsServer& server) { bool PrivateDnsConfiguration::needsValidation(const IPrivateDnsServer& server) const { // The server is not expected to be used on the network. if (!server.active()) return false; Loading @@ -373,6 +367,28 @@ bool PrivateDnsConfiguration::needsValidation(const DnsTlsServer& server) { return false; } base::Result<IPrivateDnsServer*> PrivateDnsConfiguration::getPrivateDns( const ServerIdentity& identity, unsigned netId) { std::lock_guard guard(mPrivateDnsLock); return getPrivateDnsLocked(identity, netId); } base::Result<IPrivateDnsServer*> PrivateDnsConfiguration::getPrivateDnsLocked( const ServerIdentity& identity, unsigned netId) { auto netPair = mPrivateDnsTransports.find(netId); if (netPair == mPrivateDnsTransports.end()) { return Errorf("Failed to get private DNS: netId {} not found", netId); } auto iter = netPair->second.find(identity); if (iter == netPair->second.end()) { return Errorf("Failed to get private DNS: server {{{}/{}}} not found", identity.sockaddr, identity.provider); } return iter->second.get(); } void PrivateDnsConfiguration::setObserver(PrivateDnsValidationObserver* observer) { std::lock_guard guard(mPrivateDnsLock); mObserver = observer; Loading