aboutsummaryrefslogtreecommitdiff
path: root/PrivateDnsConfiguration.cpp
diff options
context:
space:
mode:
authorMike Yu <yumike@google.com>2020-12-02 21:04:40 +0800
committerMike Yu <yumike@google.com>2021-04-26 03:10:44 +0000
commit82ae84b9490e898eb839d0b807de23da27437c5b (patch)
treef356d3612e202044d1c5fb7d0080978e9f770c2c /PrivateDnsConfiguration.cpp
parent9310ca2278d55dc53b7173ed21b85d1b523057da (diff)
downloadDnsResolver-82ae84b9490e898eb839d0b807de23da27437c5b.tar.gz
Implement DoT revalidation
The revalidation starts from DnsTlsDispatcher which uses a counter for counting the number of continuous network_error failures of a DoT server. The mechanics works for private DNS opportunistic mode. - Once the counter reaches dot_revalidation_threshold, DnsTlsDispatcher sends a revalidation request to PrivateDnsConfiguration to validate the DoT server. - Once the counter reaches dot_xport_unusable_threshold, DnsTlsDispatcher marks the transport of the DoT server as unusable. The DoT server won't be used for at least 5 minutes. DoT revalidation runs when the followings are met: [1] the private DNS setting is opportunistic mode [2] the requested DoT server is valid to be used on the network [3] the requested DoT server is currently marked as Validation::success The above mechanics runs when the feature flag "dot_revalidation_threshold" is a positive and zon-zero value, and is -1 when the mechanics is disabled. Bug: 79727473 Test: atest when all the flags off dot_revalidation_threshold: -1 dot_async_handshake: 0 dot_xport_unusable_threshold: -1 dot_maxtries: 3 parallel_lookup_sleep_time: 2 dot_connect_timeout_ms: 127000 parallel_lookup_release: 0 sort_nameservers: 0 keep_listening_udp: 0 Test: atest when all the flags on dot_revalidation_threshold: 10 dot_async_handshake: 1 dot_xport_unusable_threshold: 20 dot_maxtries: 1 parallel_lookup_sleep_time: 2 dot_connect_timeout_ms: 10000 parallel_lookup_release: 1 sort_nameservers: 1 keep_listening_udp: 1 Change-Id: Id442529468d63156a9aebf30ea5f142dfa689a97
Diffstat (limited to 'PrivateDnsConfiguration.cpp')
-rw-r--r--PrivateDnsConfiguration.cpp61
1 files changed, 41 insertions, 20 deletions
diff --git a/PrivateDnsConfiguration.cpp b/PrivateDnsConfiguration.cpp
index c8b070a2..610d55b2 100644
--- a/PrivateDnsConfiguration.cpp
+++ b/PrivateDnsConfiguration.cpp
@@ -110,14 +110,14 @@ int PrivateDnsConfiguration::set(int32_t netId, uint32_t mark,
if (needsValidation(server)) {
updateServerState(identity, Validation::in_process, netId);
- startValidation(server, netId);
+ startValidation(server, netId, false);
}
}
return 0;
}
-PrivateDnsStatus PrivateDnsConfiguration::getStatus(unsigned netId) {
+PrivateDnsStatus PrivateDnsConfiguration::getStatus(unsigned netId) const {
PrivateDnsStatus status{PrivateDnsMode::OFF, {}};
std::lock_guard guard(mPrivateDnsLock);
@@ -144,41 +144,55 @@ void PrivateDnsConfiguration::clear(unsigned netId) {
mPrivateDnsTransports.erase(netId);
}
-bool PrivateDnsConfiguration::requestValidation(unsigned netId, const DnsTlsServer& server,
- uint32_t mark) {
+base::Result<void> PrivateDnsConfiguration::requestValidation(unsigned netId,
+ const DnsTlsServer& server,
+ uint32_t mark) {
std::lock_guard guard(mPrivateDnsLock);
+
+ // Running revalidation requires to mark the server as in_process, which means the server
+ // won't be used until the validation passes. It's necessary and safe to run revalidation
+ // when in private DNS opportunistic mode, because there's a fallback mechanics even if
+ // all of the private DNS servers are in in_process state.
+ if (auto it = mPrivateDnsModes.find(netId); it == mPrivateDnsModes.end()) {
+ return Errorf("NetId not found in mPrivateDnsModes");
+ } else if (it->second != PrivateDnsMode::OPPORTUNISTIC) {
+ return Errorf("Private DNS setting is not opportunistic mode");
+ }
+
auto netPair = mPrivateDnsTransports.find(netId);
if (netPair == mPrivateDnsTransports.end()) {
- return false;
+ return Errorf("NetId not found in mPrivateDnsTransports");
}
auto& tracker = netPair->second;
const ServerIdentity identity = ServerIdentity(server);
auto it = tracker.find(identity);
if (it == tracker.end()) {
- return false;
+ return Errorf("Server was removed");
}
const DnsTlsServer& target = it->second;
- if (!target.active()) return false;
+ if (!target.active()) return Errorf("Server is not active");
- if (target.validationState() != Validation::success) return false;
+ if (target.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 false;
+ if (target.mark != mark) return Errorf("Socket mark mismatched");
updateServerState(identity, Validation::in_process, netId);
- startValidation(target, netId);
- return true;
+ startValidation(target, netId, true);
+ return {};
}
-void PrivateDnsConfiguration::startValidation(const DnsTlsServer& server, unsigned netId)
- REQUIRES(mPrivateDnsLock) {
- // Note that capturing |server| and |netId| in this lambda create copies.
- std::thread validate_thread([this, server, netId] {
+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] {
setThreadName(StringPrintf("TlsVerify_%u", netId).c_str());
// cat /proc/sys/net/ipv4/tcp_syn_retries yields "6".
@@ -208,7 +222,9 @@ void PrivateDnsConfiguration::startValidation(const DnsTlsServer& server, unsign
LOG(WARNING) << "validateDnsTlsServer returned " << success << " for "
<< server.toIpString();
- const bool needs_reeval = this->recordPrivateDnsValidation(server, netId, success);
+ const bool needs_reeval =
+ this->recordPrivateDnsValidation(server, netId, success, isRevalidation);
+
if (!needs_reeval) {
break;
}
@@ -254,7 +270,7 @@ void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const DnsTlsServer&
}
bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId,
- bool success) {
+ bool success, bool isRevalidation) {
constexpr bool NEEDS_REEVALUATION = true;
constexpr bool DONT_REEVALUATE = false;
const ServerIdentity identity = ServerIdentity(server);
@@ -274,10 +290,15 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& ser
notifyValidationStateUpdate(identity.ip.toString(), Validation::fail, netId);
return DONT_REEVALUATE;
}
- const bool modeDoesReevaluation = (mode->second == PrivateDnsMode::STRICT);
- bool reevaluationStatus =
- (success || !modeDoesReevaluation) ? DONT_REEVALUATE : NEEDS_REEVALUATION;
+ bool reevaluationStatus = NEEDS_REEVALUATION;
+ if (success) {
+ reevaluationStatus = DONT_REEVALUATE;
+ } else if (mode->second == PrivateDnsMode::OFF) {
+ reevaluationStatus = DONT_REEVALUATE;
+ } else if (mode->second == PrivateDnsMode::OPPORTUNISTIC && !isRevalidation) {
+ reevaluationStatus = DONT_REEVALUATE;
+ }
auto& tracker = netPair->second;
auto serverPair = tracker.find(identity);