Support sending validation request to PrivateDnsConfiguration
Extend PrivateDnsConfiguration to support validation request.
The request is deniable. If the request is denied, no validation
starts. Callers can know if requests are accepted by the return
value of the call.
This change also extends DnsTlsServer to store the mark used by
validation, which helps on preventing running validation with
an unexpected socket mark and resulting in updating wrong validation
state.
Bug: 79727473
Test: cd packages/modules/DnsResolver && atest
Change-Id: Ib92f6b4dd94ed426bf28cb9756d1514e34f16140
diff --git a/PrivateDnsConfiguration.cpp b/PrivateDnsConfiguration.cpp
index 47969b3..8fbd573 100644
--- a/PrivateDnsConfiguration.cpp
+++ b/PrivateDnsConfiguration.cpp
@@ -70,6 +70,7 @@
DnsTlsServer server(parsed);
server.name = name;
server.certificate = caCert;
+ server.mark = mark;
tmp[ServerIdentity(server)] = server;
}
@@ -140,6 +141,37 @@
mPrivateDnsTransports.erase(netId);
}
+bool PrivateDnsConfiguration::requestValidation(unsigned netId, const DnsTlsServer& server,
+ uint32_t mark) {
+ std::lock_guard guard(mPrivateDnsLock);
+ auto netPair = mPrivateDnsTransports.find(netId);
+ if (netPair == mPrivateDnsTransports.end()) {
+ return false;
+ }
+
+ auto& tracker = netPair->second;
+ const ServerIdentity identity = ServerIdentity(server);
+ auto it = tracker.find(identity);
+ if (it == tracker.end()) {
+ return false;
+ }
+
+ const DnsTlsServer& target = it->second;
+
+ if (!target.active()) return false;
+
+ if (target.validationState() != Validation::success) return false;
+
+ // 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;
+
+ updateServerState(identity, Validation::in_process, netId);
+ startValidation(target, netId, mark);
+ return true;
+}
+
void PrivateDnsConfiguration::startValidation(const DnsTlsServer& server, unsigned netId,
uint32_t mark) REQUIRES(mPrivateDnsLock) {
// Note that capturing |server| and |netId| in this lambda create copies.