Drop the dependency of Fwmark

The resolver used to generate the desired network mark for
DoT sockets. Now, change to get the network mark from netd.

Bug: 151895202
Test: Private DNS works as usual (even on VPN)
Merged-In: Ibb3e3e1ce0b43cb74962dd4436a47e9b458fa19a
Change-Id: I9698b3c73e410fce79dac044919f874768fc6a04
(cherry picked from commit ab43958ef7dbdf10b5ba310bc436173a0785f58f)
diff --git a/DnsTlsDispatcher.cpp b/DnsTlsDispatcher.cpp
index 8747e46..1fa4001 100644
--- a/DnsTlsDispatcher.cpp
+++ b/DnsTlsDispatcher.cpp
@@ -147,6 +147,10 @@
                                                   const Slice query, const Slice ans, int* resplen,
                                                   bool* connectTriggered) {
     int connectCounter;
+
+    // TODO: This can cause the resolver to create multiple connections to the same DoT server
+    // merely due to different mark, such as the bit explicitlySelected unset.
+    // See if we can save them and just create one connection for one DoT server.
     const Key key = std::make_pair(mark, server);
     Transport* xport;
     {
diff --git a/ResolverController.cpp b/ResolverController.cpp
index 13600b8..be0b989 100644
--- a/ResolverController.cpp
+++ b/ResolverController.cpp
@@ -24,7 +24,6 @@
 
 #include <netdb.h>
 
-#include <Fwmark.h>
 #include <aidl/android/net/IDnsResolver.h>
 #include <android-base/logging.h>
 #include <android-base/strings.h>
@@ -202,21 +201,22 @@
 int ResolverController::setResolverConfiguration(const ResolverParamsParcel& resolverParams) {
     using aidl::android::net::IDnsResolver;
 
-    // At private DNS validation time, we only know the netId, so we have to guess/compute the
-    // corresponding socket mark.
-    Fwmark fwmark;
-    fwmark.netId = resolverParams.netId;
-    fwmark.explicitlySelected = true;
-    fwmark.protectedFromVpn = true;
-    fwmark.permission = PERMISSION_SYSTEM;
+    // Expect to get the mark with system permission.
+    android_net_context netcontext;
+    gResNetdCallbacks.get_network_context(resolverParams.netId, 0 /* uid */, &netcontext);
 
     // Allow at most MAXNS private DNS servers in a network to prevent too many broken servers.
     std::vector<std::string> tlsServers = resolverParams.tlsServers;
     if (tlsServers.size() > MAXNS) {
         tlsServers.resize(MAXNS);
     }
+
+    // Use app_mark for DoT connection. Using dns_mark might result in reaching the DoT servers
+    // through a different network. For example, on a VPN with no DNS servers (Do53), if the VPN
+    // applies to UID 0, dns_mark is assigned for default network rathan the VPN. (note that it's
+    // possible that a VPN doesn't have any DNS servers but DoT servers in DNS strict mode)
     const int err =
-            gPrivateDnsConfiguration.set(resolverParams.netId, fwmark.intValue, tlsServers,
+            gPrivateDnsConfiguration.set(resolverParams.netId, netcontext.app_mark, tlsServers,
                                          resolverParams.tlsName, resolverParams.caCertificate);
 
     if (err != 0) {