Merge "Trigger NetworkCallback events when private DNS usage has changed." am: fa1f79ac66
am: bf7f517c51
Change-Id: I1e6c54ba016f6a165a302bd135a29d9332aaa235
This commit is contained in:
@@ -161,6 +161,7 @@ import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
@@ -879,6 +880,10 @@ public class ConnectivityServiceTest {
|
||||
return mMetricsService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerNetdEventCallback() {
|
||||
}
|
||||
|
||||
public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() {
|
||||
return mLastCreatedNetworkMonitor;
|
||||
}
|
||||
@@ -3777,6 +3782,11 @@ public class ConnectivityServiceTest {
|
||||
// The default on Android is opportunistic mode ("Automatic").
|
||||
setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
|
||||
|
||||
final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
|
||||
final NetworkRequest cellRequest = new NetworkRequest.Builder()
|
||||
.addTransportType(TRANSPORT_CELLULAR).build();
|
||||
mCm.requestNetwork(cellRequest, cellNetworkCallback);
|
||||
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
waitForIdle();
|
||||
// CS tells netd about the empty DNS config for this network.
|
||||
@@ -3812,6 +3822,14 @@ public class ConnectivityServiceTest {
|
||||
assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
|
||||
new String[]{"2001:db8::1", "192.0.2.1"}));
|
||||
reset(mNetworkManagementService);
|
||||
cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
|
||||
cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES,
|
||||
mCellNetworkAgent);
|
||||
CallbackInfo cbi = cellNetworkCallback.expectCallback(
|
||||
CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
|
||||
assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
|
||||
|
||||
setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com");
|
||||
verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork(
|
||||
@@ -3821,6 +3839,7 @@ public class ConnectivityServiceTest {
|
||||
assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
|
||||
new String[]{"2001:db8::1", "192.0.2.1"}));
|
||||
reset(mNetworkManagementService);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
|
||||
setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
|
||||
verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
|
||||
@@ -3833,8 +3852,112 @@ public class ConnectivityServiceTest {
|
||||
assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
|
||||
new String[]{"2001:db8::1", "192.0.2.1"}));
|
||||
reset(mNetworkManagementService);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
|
||||
// Can't test strict mode without properly mocking out the DNS lookups.
|
||||
setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com");
|
||||
// Can't test dns configuration for strict mode without properly mocking
|
||||
// out the DNS lookups, but can test that LinkProperties is updated.
|
||||
cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
|
||||
mCellNetworkAgent);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive());
|
||||
assertEquals("strict.example.com", ((LinkProperties)cbi.arg).getPrivateDnsServerName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception {
|
||||
// The default on Android is opportunistic mode ("Automatic").
|
||||
setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
|
||||
|
||||
final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
|
||||
final NetworkRequest cellRequest = new NetworkRequest.Builder()
|
||||
.addTransportType(TRANSPORT_CELLULAR).build();
|
||||
mCm.requestNetwork(cellRequest, cellNetworkCallback);
|
||||
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
waitForIdle();
|
||||
LinkProperties lp = new LinkProperties();
|
||||
mCellNetworkAgent.sendLinkProperties(lp);
|
||||
mCellNetworkAgent.connect(false);
|
||||
waitForIdle();
|
||||
cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
|
||||
cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES,
|
||||
mCellNetworkAgent);
|
||||
CallbackInfo cbi = cellNetworkCallback.expectCallback(
|
||||
CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
|
||||
assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
|
||||
Set<InetAddress> dnsServers = new HashSet<>();
|
||||
checkDnsServers(cbi.arg, dnsServers);
|
||||
|
||||
// Send a validation event for a server that is not part of the current
|
||||
// resolver config. The validation event should be ignored.
|
||||
mService.mNetdEventCallback.onPrivateDnsValidationEvent(
|
||||
mCellNetworkAgent.getNetwork().netId, "", "145.100.185.18", true);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
|
||||
// Add a dns server to the LinkProperties.
|
||||
LinkProperties lp2 = new LinkProperties(lp);
|
||||
lp2.addDnsServer(InetAddress.getByName("145.100.185.16"));
|
||||
mCellNetworkAgent.sendLinkProperties(lp2);
|
||||
cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
|
||||
mCellNetworkAgent);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
|
||||
assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
|
||||
dnsServers.add(InetAddress.getByName("145.100.185.16"));
|
||||
checkDnsServers(cbi.arg, dnsServers);
|
||||
|
||||
// Send a validation event containing a hostname that is not part of
|
||||
// the current resolver config. The validation event should be ignored.
|
||||
mService.mNetdEventCallback.onPrivateDnsValidationEvent(
|
||||
mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "hostname", true);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
|
||||
// Send a validation event where validation failed.
|
||||
mService.mNetdEventCallback.onPrivateDnsValidationEvent(
|
||||
mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", false);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
|
||||
// Send a validation event where validation succeeded for a server in
|
||||
// the current resolver config. A LinkProperties callback with updated
|
||||
// private dns fields should be sent.
|
||||
mService.mNetdEventCallback.onPrivateDnsValidationEvent(
|
||||
mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", true);
|
||||
cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
|
||||
mCellNetworkAgent);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive());
|
||||
assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
|
||||
checkDnsServers(cbi.arg, dnsServers);
|
||||
|
||||
// The private dns fields in LinkProperties should be preserved when
|
||||
// the network agent sends unrelated changes.
|
||||
LinkProperties lp3 = new LinkProperties(lp2);
|
||||
lp3.setMtu(1300);
|
||||
mCellNetworkAgent.sendLinkProperties(lp3);
|
||||
cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
|
||||
mCellNetworkAgent);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive());
|
||||
assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
|
||||
checkDnsServers(cbi.arg, dnsServers);
|
||||
assertEquals(1300, ((LinkProperties)cbi.arg).getMtu());
|
||||
|
||||
// Removing the only validated server should affect the private dns
|
||||
// fields in LinkProperties.
|
||||
LinkProperties lp4 = new LinkProperties(lp3);
|
||||
lp4.removeDnsServer(InetAddress.getByName("145.100.185.16"));
|
||||
mCellNetworkAgent.sendLinkProperties(lp4);
|
||||
cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
|
||||
mCellNetworkAgent);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
|
||||
assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
|
||||
dnsServers.remove(InetAddress.getByName("145.100.185.16"));
|
||||
checkDnsServers(cbi.arg, dnsServers);
|
||||
assertEquals(1300, ((LinkProperties)cbi.arg).getMtu());
|
||||
}
|
||||
|
||||
private void checkDirectlyConnectedRoutes(Object callbackObj,
|
||||
@@ -3854,6 +3977,13 @@ public class ConnectivityServiceTest {
|
||||
assertTrue(observedRoutes.containsAll(expectedRoutes));
|
||||
}
|
||||
|
||||
private static void checkDnsServers(Object callbackObj, Set<InetAddress> dnsServers) {
|
||||
assertTrue(callbackObj instanceof LinkProperties);
|
||||
LinkProperties lp = (LinkProperties) callbackObj;
|
||||
assertEquals(dnsServers.size(), lp.getDnsServers().size());
|
||||
assertTrue(lp.getDnsServers().containsAll(dnsServers));
|
||||
}
|
||||
|
||||
private static <T> void assertEmpty(T[] ts) {
|
||||
int length = ts.length;
|
||||
assertEquals("expected empty array, but length was " + length, 0, length);
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (C) 2018, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.connectivity;
|
||||
|
||||
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
|
||||
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
|
||||
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.mock.MockContentResolver;
|
||||
|
||||
import com.android.internal.util.test.FakeSettingsProvider;
|
||||
import com.android.server.connectivity.MockableSystemProperties;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
/**
|
||||
* Tests for {@link DnsManager}.
|
||||
*
|
||||
* Build, install and run with:
|
||||
* runtest frameworks-net -c com.android.server.connectivity.DnsManagerTest
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class DnsManagerTest {
|
||||
static final int TEST_NETID = 100;
|
||||
static final int TEST_NETID_ALTERNATE = 101;
|
||||
static final int TEST_NETID_UNTRACKED = 102;
|
||||
final boolean IS_DEFAULT = true;
|
||||
final boolean NOT_DEFAULT = false;
|
||||
|
||||
DnsManager mDnsManager;
|
||||
MockContentResolver mContentResolver;
|
||||
|
||||
@Mock Context mCtx;
|
||||
@Mock INetworkManagementService mNMService;
|
||||
@Mock MockableSystemProperties mSystemProperties;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContentResolver = new MockContentResolver();
|
||||
mContentResolver.addProvider(Settings.AUTHORITY,
|
||||
new FakeSettingsProvider());
|
||||
when(mCtx.getContentResolver()).thenReturn(mContentResolver);
|
||||
mDnsManager = new DnsManager(mCtx, mNMService, mSystemProperties);
|
||||
|
||||
// Clear the private DNS settings
|
||||
Settings.Global.putString(mContentResolver,
|
||||
Settings.Global.PRIVATE_DNS_MODE, "");
|
||||
Settings.Global.putString(mContentResolver,
|
||||
Settings.Global.PRIVATE_DNS_SPECIFIER, "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrackedValidationUpdates() throws Exception {
|
||||
mDnsManager.updatePrivateDns(new Network(TEST_NETID),
|
||||
mDnsManager.getPrivateDnsConfig());
|
||||
mDnsManager.updatePrivateDns(new Network(TEST_NETID_ALTERNATE),
|
||||
mDnsManager.getPrivateDnsConfig());
|
||||
LinkProperties lp = new LinkProperties();
|
||||
lp.addDnsServer(InetAddress.getByName("3.3.3.3"));
|
||||
lp.addDnsServer(InetAddress.getByName("4.4.4.4"));
|
||||
|
||||
// Send a validation event that is tracked on the alternate netId
|
||||
mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
|
||||
mDnsManager.setDnsConfigurationForNetwork(TEST_NETID_ALTERNATE, lp, NOT_DEFAULT);
|
||||
mDnsManager.updatePrivateDnsValidation(
|
||||
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_ALTERNATE,
|
||||
InetAddress.parseNumericAddress("4.4.4.4"), "", true));
|
||||
LinkProperties fixedLp = new LinkProperties(lp);
|
||||
mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
|
||||
assertFalse(fixedLp.isPrivateDnsActive());
|
||||
assertNull(fixedLp.getPrivateDnsServerName());
|
||||
fixedLp = new LinkProperties(lp);
|
||||
mDnsManager.updatePrivateDnsStatus(TEST_NETID_ALTERNATE, fixedLp);
|
||||
assertTrue(fixedLp.isPrivateDnsActive());
|
||||
assertNull(fixedLp.getPrivateDnsServerName());
|
||||
|
||||
// Switch to strict mode
|
||||
Settings.Global.putString(mContentResolver,
|
||||
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());
|
||||
mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
|
||||
fixedLp = new LinkProperties(lp);
|
||||
mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
|
||||
assertTrue(fixedLp.isPrivateDnsActive());
|
||||
assertEquals("strictmode.com", fixedLp.getPrivateDnsServerName());
|
||||
fixedLp = new LinkProperties(lp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIgnoreUntrackedValidationUpdates() throws Exception {
|
||||
// The PrivateDnsConfig map is empty, so no validation events will
|
||||
// be tracked.
|
||||
LinkProperties lp = new LinkProperties();
|
||||
lp.addDnsServer(InetAddress.getByName("3.3.3.3"));
|
||||
mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
|
||||
mDnsManager.updatePrivateDnsValidation(
|
||||
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
|
||||
InetAddress.parseNumericAddress("3.3.3.3"), "", true));
|
||||
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
|
||||
assertFalse(lp.isPrivateDnsActive());
|
||||
assertNull(lp.getPrivateDnsServerName());
|
||||
|
||||
// Validation event has untracked netId
|
||||
mDnsManager.updatePrivateDns(new Network(TEST_NETID),
|
||||
mDnsManager.getPrivateDnsConfig());
|
||||
mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
|
||||
mDnsManager.updatePrivateDnsValidation(
|
||||
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_UNTRACKED,
|
||||
InetAddress.parseNumericAddress("3.3.3.3"), "", true));
|
||||
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
|
||||
assertFalse(lp.isPrivateDnsActive());
|
||||
assertNull(lp.getPrivateDnsServerName());
|
||||
|
||||
// Validation event has untracked ipAddress
|
||||
mDnsManager.updatePrivateDnsValidation(
|
||||
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
|
||||
InetAddress.parseNumericAddress("4.4.4.4"), "", true));
|
||||
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
|
||||
assertFalse(lp.isPrivateDnsActive());
|
||||
assertNull(lp.getPrivateDnsServerName());
|
||||
|
||||
// Validation event has untracked hostname
|
||||
mDnsManager.updatePrivateDnsValidation(
|
||||
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
|
||||
InetAddress.parseNumericAddress("3.3.3.3"), "hostname",
|
||||
true));
|
||||
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
|
||||
assertFalse(lp.isPrivateDnsActive());
|
||||
assertNull(lp.getPrivateDnsServerName());
|
||||
|
||||
// Validation event failed
|
||||
mDnsManager.updatePrivateDnsValidation(
|
||||
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
|
||||
InetAddress.parseNumericAddress("3.3.3.3"), "", false));
|
||||
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
|
||||
assertFalse(lp.isPrivateDnsActive());
|
||||
assertNull(lp.getPrivateDnsServerName());
|
||||
|
||||
// Network removed
|
||||
mDnsManager.removeNetwork(new Network(TEST_NETID));
|
||||
mDnsManager.updatePrivateDnsValidation(
|
||||
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
|
||||
InetAddress.parseNumericAddress("3.3.3.3"), "", true));
|
||||
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
|
||||
assertFalse(lp.isPrivateDnsActive());
|
||||
assertNull(lp.getPrivateDnsServerName());
|
||||
|
||||
// Turn private DNS mode off
|
||||
Settings.Global.putString(mContentResolver,
|
||||
Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OFF);
|
||||
mDnsManager.updatePrivateDns(new Network(TEST_NETID),
|
||||
mDnsManager.getPrivateDnsConfig());
|
||||
mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
|
||||
mDnsManager.updatePrivateDnsValidation(
|
||||
new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
|
||||
InetAddress.parseNumericAddress("3.3.3.3"), "", true));
|
||||
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
|
||||
assertFalse(lp.isPrivateDnsActive());
|
||||
assertNull(lp.getPrivateDnsServerName());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user