Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f0f364f2 authored by Chalard Jean's avatar Chalard Jean
Browse files

Let DnsManager fill in LinkProperties for private DNSes

Test: new tests pass
Bug: 73641539
Change-Id: I971ef4d27b22a435d7459e1c4b31a8715ef6e610
parent cf893ac4
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -211,6 +212,8 @@ public class DnsManager {
        }

        // Validation statuses of <hostname, ipAddress> pairs for a single netId
        // Caution : not thread-safe. As mentioned in the top file comment, all
        // methods of this class must only be called on ConnectivityService's thread.
        private Map<Pair<String, InetAddress>, ValidationStatus> mValidationMap;

        private PrivateDnsValidationStatuses() {
@@ -262,6 +265,16 @@ public class DnsManager {
                mValidationMap.put(p, ValidationStatus.FAILED);
            }
        }

        private LinkProperties fillInValidatedPrivateDns(LinkProperties lp) {
            lp.setValidatedPrivateDnsServers(Collections.EMPTY_LIST);
            mValidationMap.forEach((key, value) -> {
                    if (value == ValidationStatus.SUCCEEDED) {
                        lp.addValidatedPrivateDnsServer(key.second);
                    }
                });
            return lp;
        }
    }

    private final Context mContext;
@@ -315,23 +328,19 @@ public class DnsManager {
                PRIVATE_DNS_OFF);

        final boolean useTls = privateDnsCfg.useTls;
        final PrivateDnsValidationStatuses statuses =
                useTls ? mPrivateDnsValidationMap.get(netId) : null;
        final boolean validated = (null != statuses) && statuses.hasValidatedServer();
        final boolean strictMode = privateDnsCfg.inStrictMode();
        final String tlsHostname = strictMode ? privateDnsCfg.hostname : "";
        final String tlsHostname = strictMode ? privateDnsCfg.hostname : null;
        final boolean usingPrivateDns = strictMode || validated;

        if (strictMode) {
            lp.setUsePrivateDns(true);
        lp.setUsePrivateDns(usingPrivateDns);
        lp.setPrivateDnsServerName(tlsHostname);
        } else if (useTls) {
            // We are in opportunistic mode. Private DNS should be used if there
            // is a known DNS-over-TLS validated server.
            boolean validated = mPrivateDnsValidationMap.containsKey(netId) &&
                    mPrivateDnsValidationMap.get(netId).hasValidatedServer();
            lp.setUsePrivateDns(validated);
            lp.setPrivateDnsServerName(null);
        if (usingPrivateDns && null != statuses) {
            statuses.fillInValidatedPrivateDns(lp);
        } else {
            // Private DNS is disabled.
            lp.setUsePrivateDns(false);
            lp.setPrivateDnsServerName(null);
            lp.setValidatedPrivateDnsServers(Collections.EMPTY_LIST);
        }
    }

+40 −4
Original line number Diff line number Diff line
@@ -28,8 +28,11 @@ import static org.mockito.Mockito.when;

import android.content.ContentResolver;
import android.content.Context;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.RouteInfo;
import android.os.INetworkManagementService;
import android.provider.Settings;
import android.support.test.filters.SmallTest;
@@ -40,6 +43,7 @@ import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.connectivity.MockableSystemProperties;

import java.net.InetAddress;
import java.util.Arrays;

import org.junit.runner.RunWith;
import org.junit.Before;
@@ -56,6 +60,7 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class DnsManagerTest {
    static final String TEST_IFACENAME = "test_wlan0";
    static final int TEST_NETID = 100;
    static final int TEST_NETID_ALTERNATE = 101;
    static final int TEST_NETID_UNTRACKED = 102;
@@ -92,6 +97,7 @@ public class DnsManagerTest {
        mDnsManager.updatePrivateDns(new Network(TEST_NETID_ALTERNATE),
                mDnsManager.getPrivateDnsConfig());
        LinkProperties lp = new LinkProperties();
        lp.setInterfaceName(TEST_IFACENAME);
        lp.addDnsServer(InetAddress.getByName("3.3.3.3"));
        lp.addDnsServer(InetAddress.getByName("4.4.4.4"));

@@ -109,21 +115,51 @@ public class DnsManagerTest {
        mDnsManager.updatePrivateDnsStatus(TEST_NETID_ALTERNATE, fixedLp);
        assertTrue(fixedLp.isPrivateDnsActive());
        assertNull(fixedLp.getPrivateDnsServerName());
        assertEquals(Arrays.asList(InetAddress.getByName("4.4.4.4")),
                fixedLp.getValidatedPrivateDnsServers());

        // Set up addresses for strict mode and switch to it.
        lp.addLinkAddress(new LinkAddress("192.0.2.4/24"));
        lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"),
                TEST_IFACENAME));
        lp.addLinkAddress(new LinkAddress("2001:db8:1::1/64"));
        lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"),
                TEST_IFACENAME));

        // Switch to strict mode
        Settings.Global.putString(mContentResolver,
                Settings.Global.PRIVATE_DNS_MODE,
                PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
                Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
        Settings.Global.putString(mContentResolver,
                Settings.Global.PRIVATE_DNS_SPECIFIER, "strictmode.com");
        mDnsManager.updatePrivateDns(new Network(TEST_NETID),
                mDnsManager.getPrivateDnsConfig());
                new DnsManager.PrivateDnsConfig("strictmode.com", new InetAddress[] {
                    InetAddress.parseNumericAddress("6.6.6.6"),
                    InetAddress.parseNumericAddress("2001:db8:66:66::1")
                    }));
        mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
        fixedLp = new LinkProperties(lp);
        mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
        assertTrue(fixedLp.isPrivateDnsActive());
        assertEquals("strictmode.com", fixedLp.getPrivateDnsServerName());
        // No validation events yet.
        assertEquals(Arrays.asList(new InetAddress[0]), fixedLp.getValidatedPrivateDnsServers());
        // Validate one.
        mDnsManager.updatePrivateDnsValidation(
                new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
                InetAddress.parseNumericAddress("6.6.6.6"), "strictmode.com", true));
        fixedLp = new LinkProperties(lp);
        mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
        assertEquals(Arrays.asList(InetAddress.parseNumericAddress("6.6.6.6")),
                fixedLp.getValidatedPrivateDnsServers());
        // Validate the 2nd one.
        mDnsManager.updatePrivateDnsValidation(
                new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
                InetAddress.parseNumericAddress("2001:db8:66:66::1"), "strictmode.com", true));
        fixedLp = new LinkProperties(lp);
        mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
        assertEquals(Arrays.asList(
                        InetAddress.parseNumericAddress("2001:db8:66:66::1"),
                        InetAddress.parseNumericAddress("6.6.6.6")),
                fixedLp.getValidatedPrivateDnsServers());
    }

    @Test