Home | History | Annotate | Download | only in connectivity
      1 /*
      2  * Copyright (C) 2018, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.connectivity;
     18 
     19 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
     20 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
     21 import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE;
     22 import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
     23 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
     24 
     25 import static org.junit.Assert.assertEquals;
     26 import static org.junit.Assert.assertFalse;
     27 import static org.junit.Assert.assertNull;
     28 import static org.junit.Assert.assertTrue;
     29 import static org.mockito.Mockito.when;
     30 
     31 import android.content.Context;
     32 import android.net.IDnsResolver;
     33 import android.net.IpPrefix;
     34 import android.net.LinkAddress;
     35 import android.net.LinkProperties;
     36 import android.net.Network;
     37 import android.net.RouteInfo;
     38 import android.net.shared.PrivateDnsConfig;
     39 import android.provider.Settings;
     40 import android.test.mock.MockContentResolver;
     41 
     42 import androidx.test.filters.SmallTest;
     43 import androidx.test.runner.AndroidJUnit4;
     44 
     45 import com.android.internal.util.test.FakeSettingsProvider;
     46 
     47 import org.junit.Before;
     48 import org.junit.Test;
     49 import org.junit.runner.RunWith;
     50 import org.mockito.Mock;
     51 import org.mockito.MockitoAnnotations;
     52 
     53 import java.net.InetAddress;
     54 import java.util.Arrays;
     55 
     56 /**
     57  * Tests for {@link DnsManager}.
     58  *
     59  * Build, install and run with:
     60  *  runtest frameworks-net -c com.android.server.connectivity.DnsManagerTest
     61  */
     62 @RunWith(AndroidJUnit4.class)
     63 @SmallTest
     64 public class DnsManagerTest {
     65     static final String TEST_IFACENAME = "test_wlan0";
     66     static final int TEST_NETID = 100;
     67     static final int TEST_NETID_ALTERNATE = 101;
     68     static final int TEST_NETID_UNTRACKED = 102;
     69     final boolean IS_DEFAULT = true;
     70     final boolean NOT_DEFAULT = false;
     71 
     72     DnsManager mDnsManager;
     73     MockContentResolver mContentResolver;
     74 
     75     @Mock Context mCtx;
     76     @Mock IDnsResolver mMockDnsResolver;
     77     @Mock MockableSystemProperties mSystemProperties;
     78 
     79     @Before
     80     public void setUp() throws Exception {
     81         MockitoAnnotations.initMocks(this);
     82         mContentResolver = new MockContentResolver();
     83         mContentResolver.addProvider(Settings.AUTHORITY,
     84                 new FakeSettingsProvider());
     85         when(mCtx.getContentResolver()).thenReturn(mContentResolver);
     86         mDnsManager = new DnsManager(mCtx, mMockDnsResolver, mSystemProperties);
     87 
     88         // Clear the private DNS settings
     89         Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "");
     90         Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, "");
     91         Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "");
     92     }
     93 
     94     @Test
     95     public void testTrackedValidationUpdates() throws Exception {
     96         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
     97                 mDnsManager.getPrivateDnsConfig());
     98         mDnsManager.updatePrivateDns(new Network(TEST_NETID_ALTERNATE),
     99                 mDnsManager.getPrivateDnsConfig());
    100         LinkProperties lp = new LinkProperties();
    101         lp.setInterfaceName(TEST_IFACENAME);
    102         lp.addDnsServer(InetAddress.getByName("3.3.3.3"));
    103         lp.addDnsServer(InetAddress.getByName("4.4.4.4"));
    104 
    105         // Send a validation event that is tracked on the alternate netId
    106         mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
    107         mDnsManager.setDnsConfigurationForNetwork(TEST_NETID_ALTERNATE, lp, NOT_DEFAULT);
    108         mDnsManager.updatePrivateDnsValidation(
    109                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_ALTERNATE,
    110                 InetAddress.parseNumericAddress("4.4.4.4"), "", true));
    111         LinkProperties fixedLp = new LinkProperties(lp);
    112         mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
    113         assertFalse(fixedLp.isPrivateDnsActive());
    114         assertNull(fixedLp.getPrivateDnsServerName());
    115         fixedLp = new LinkProperties(lp);
    116         mDnsManager.updatePrivateDnsStatus(TEST_NETID_ALTERNATE, fixedLp);
    117         assertTrue(fixedLp.isPrivateDnsActive());
    118         assertNull(fixedLp.getPrivateDnsServerName());
    119         assertEquals(Arrays.asList(InetAddress.getByName("4.4.4.4")),
    120                 fixedLp.getValidatedPrivateDnsServers());
    121 
    122         // Set up addresses for strict mode and switch to it.
    123         lp.addLinkAddress(new LinkAddress("192.0.2.4/24"));
    124         lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"),
    125                 TEST_IFACENAME));
    126         lp.addLinkAddress(new LinkAddress("2001:db8:1::1/64"));
    127         lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"),
    128                 TEST_IFACENAME));
    129 
    130         Settings.Global.putString(mContentResolver,
    131                 PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
    132         Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com");
    133         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
    134                 new PrivateDnsConfig("strictmode.com", new InetAddress[] {
    135                     InetAddress.parseNumericAddress("6.6.6.6"),
    136                     InetAddress.parseNumericAddress("2001:db8:66:66::1")
    137                     }));
    138         mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
    139         fixedLp = new LinkProperties(lp);
    140         mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
    141         assertTrue(fixedLp.isPrivateDnsActive());
    142         assertEquals("strictmode.com", fixedLp.getPrivateDnsServerName());
    143         // No validation events yet.
    144         assertEquals(Arrays.asList(new InetAddress[0]), fixedLp.getValidatedPrivateDnsServers());
    145         // Validate one.
    146         mDnsManager.updatePrivateDnsValidation(
    147                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
    148                 InetAddress.parseNumericAddress("6.6.6.6"), "strictmode.com", true));
    149         fixedLp = new LinkProperties(lp);
    150         mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
    151         assertEquals(Arrays.asList(InetAddress.parseNumericAddress("6.6.6.6")),
    152                 fixedLp.getValidatedPrivateDnsServers());
    153         // Validate the 2nd one.
    154         mDnsManager.updatePrivateDnsValidation(
    155                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
    156                 InetAddress.parseNumericAddress("2001:db8:66:66::1"), "strictmode.com", true));
    157         fixedLp = new LinkProperties(lp);
    158         mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
    159         assertEquals(Arrays.asList(
    160                         InetAddress.parseNumericAddress("2001:db8:66:66::1"),
    161                         InetAddress.parseNumericAddress("6.6.6.6")),
    162                 fixedLp.getValidatedPrivateDnsServers());
    163     }
    164 
    165     @Test
    166     public void testIgnoreUntrackedValidationUpdates() throws Exception {
    167         // The PrivateDnsConfig map is empty, so no validation events will
    168         // be tracked.
    169         LinkProperties lp = new LinkProperties();
    170         lp.addDnsServer(InetAddress.getByName("3.3.3.3"));
    171         mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
    172         mDnsManager.updatePrivateDnsValidation(
    173                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
    174                 InetAddress.parseNumericAddress("3.3.3.3"), "", true));
    175         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
    176         assertFalse(lp.isPrivateDnsActive());
    177         assertNull(lp.getPrivateDnsServerName());
    178 
    179         // Validation event has untracked netId
    180         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
    181                 mDnsManager.getPrivateDnsConfig());
    182         mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
    183         mDnsManager.updatePrivateDnsValidation(
    184                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_UNTRACKED,
    185                 InetAddress.parseNumericAddress("3.3.3.3"), "", true));
    186         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
    187         assertFalse(lp.isPrivateDnsActive());
    188         assertNull(lp.getPrivateDnsServerName());
    189 
    190         // Validation event has untracked ipAddress
    191         mDnsManager.updatePrivateDnsValidation(
    192                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
    193                 InetAddress.parseNumericAddress("4.4.4.4"), "", true));
    194         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
    195         assertFalse(lp.isPrivateDnsActive());
    196         assertNull(lp.getPrivateDnsServerName());
    197 
    198         // Validation event has untracked hostname
    199         mDnsManager.updatePrivateDnsValidation(
    200                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
    201                 InetAddress.parseNumericAddress("3.3.3.3"), "hostname",
    202                 true));
    203         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
    204         assertFalse(lp.isPrivateDnsActive());
    205         assertNull(lp.getPrivateDnsServerName());
    206 
    207         // Validation event failed
    208         mDnsManager.updatePrivateDnsValidation(
    209                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
    210                 InetAddress.parseNumericAddress("3.3.3.3"), "", false));
    211         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
    212         assertFalse(lp.isPrivateDnsActive());
    213         assertNull(lp.getPrivateDnsServerName());
    214 
    215         // Network removed
    216         mDnsManager.removeNetwork(new Network(TEST_NETID));
    217         mDnsManager.updatePrivateDnsValidation(
    218                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
    219                 InetAddress.parseNumericAddress("3.3.3.3"), "", true));
    220         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
    221         assertFalse(lp.isPrivateDnsActive());
    222         assertNull(lp.getPrivateDnsServerName());
    223 
    224         // Turn private DNS mode off
    225         Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OFF);
    226         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
    227                 mDnsManager.getPrivateDnsConfig());
    228         mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
    229         mDnsManager.updatePrivateDnsValidation(
    230                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
    231                 InetAddress.parseNumericAddress("3.3.3.3"), "", true));
    232         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
    233         assertFalse(lp.isPrivateDnsActive());
    234         assertNull(lp.getPrivateDnsServerName());
    235     }
    236 
    237     @Test
    238     public void testOverrideDefaultMode() throws Exception {
    239         // Hard-coded default is opportunistic mode.
    240         final PrivateDnsConfig cfgAuto = DnsManager.getPrivateDnsConfig(mContentResolver);
    241         assertTrue(cfgAuto.useTls);
    242         assertEquals("", cfgAuto.hostname);
    243         assertEquals(new InetAddress[0], cfgAuto.ips);
    244 
    245         // Pretend a gservices push sets the default to "off".
    246         Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "off");
    247         final PrivateDnsConfig cfgOff = DnsManager.getPrivateDnsConfig(mContentResolver);
    248         assertFalse(cfgOff.useTls);
    249         assertEquals("", cfgOff.hostname);
    250         assertEquals(new InetAddress[0], cfgOff.ips);
    251 
    252         // Strict mode still works.
    253         Settings.Global.putString(
    254                 mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
    255         Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com");
    256         final PrivateDnsConfig cfgStrict = DnsManager.getPrivateDnsConfig(mContentResolver);
    257         assertTrue(cfgStrict.useTls);
    258         assertEquals("strictmode.com", cfgStrict.hostname);
    259         assertEquals(new InetAddress[0], cfgStrict.ips);
    260     }
    261 }
    262