• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE;
20 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE;
21 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF;
22 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
23 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
24 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_SPECIFIER;
25 import static android.net.NetworkCapabilities.MAX_TRANSPORT;
26 import static android.net.NetworkCapabilities.MIN_TRANSPORT;
27 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
28 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
29 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE;
30 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS;
31 
32 import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
33 
34 import static org.junit.Assert.assertEquals;
35 import static org.junit.Assert.assertFalse;
36 import static org.junit.Assert.assertNotNull;
37 import static org.junit.Assert.assertNull;
38 import static org.junit.Assert.assertTrue;
39 import static org.mockito.Mockito.eq;
40 import static org.mockito.Mockito.reset;
41 import static org.mockito.Mockito.times;
42 import static org.mockito.Mockito.verify;
43 import static org.mockito.Mockito.when;
44 
45 import android.annotation.Nullable;
46 import android.content.Context;
47 import android.net.ConnectivitySettingsManager;
48 import android.net.IDnsResolver;
49 import android.net.IpPrefix;
50 import android.net.LinkAddress;
51 import android.net.LinkProperties;
52 import android.net.Network;
53 import android.net.NetworkCapabilities;
54 import android.net.ResolverOptionsParcel;
55 import android.net.ResolverParamsParcel;
56 import android.net.RouteInfo;
57 import android.net.shared.PrivateDnsConfig;
58 import android.os.Build;
59 import android.provider.Settings;
60 import android.test.mock.MockContentResolver;
61 import android.util.SparseArray;
62 
63 import androidx.test.filters.SmallTest;
64 
65 import com.android.internal.util.MessageUtils;
66 import com.android.internal.util.test.FakeSettingsProvider;
67 import com.android.testutils.DevSdkIgnoreRule;
68 import com.android.testutils.DevSdkIgnoreRunner;
69 
70 import libcore.net.InetAddressUtils;
71 
72 import org.junit.Before;
73 import org.junit.Test;
74 import org.junit.runner.RunWith;
75 import org.mockito.Mock;
76 import org.mockito.MockitoAnnotations;
77 
78 import java.net.InetAddress;
79 import java.util.Arrays;
80 
81 /**
82  * Tests for {@link DnsManager}.
83  *
84  * Build, install and run with:
85  *  runtest frameworks-net -c com.android.server.connectivity.DnsManagerTest
86  */
87 @RunWith(DevSdkIgnoreRunner.class)
88 @SmallTest
89 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
90 public class DnsManagerTest {
91     static final String TEST_IFACENAME = "test_wlan0";
92     static final int TEST_NETID = 100;
93     static final int TEST_NETID_ALTERNATE = 101;
94     static final int TEST_NETID_UNTRACKED = 102;
95     static final int TEST_DEFAULT_SAMPLE_VALIDITY_SECONDS = 1800;
96     static final int TEST_DEFAULT_SUCCESS_THRESHOLD_PERCENT = 25;
97     static final int TEST_DEFAULT_MIN_SAMPLES = 8;
98     static final int TEST_DEFAULT_MAX_SAMPLES = 64;
99     static final int[] TEST_TRANSPORT_TYPES = {TRANSPORT_WIFI, TRANSPORT_VPN};
100 
101     DnsManager mDnsManager;
102     MockContentResolver mContentResolver;
103 
104     @Mock Context mCtx;
105     @Mock IDnsResolver mMockDnsResolver;
106 
assertResolverOptionsEquals( @ullable ResolverOptionsParcel actual, @Nullable ResolverOptionsParcel expected)107     private void assertResolverOptionsEquals(
108             @Nullable ResolverOptionsParcel actual,
109             @Nullable ResolverOptionsParcel expected) {
110         if (actual == null) {
111             assertNull(expected);
112             return;
113         } else {
114             assertNotNull(expected);
115         }
116         assertEquals(actual.hosts, expected.hosts);
117         assertEquals(actual.tcMode, expected.tcMode);
118         assertEquals(actual.enforceDnsUid, expected.enforceDnsUid);
119         assertFieldCountEquals(3, ResolverOptionsParcel.class);
120     }
121 
122     @Before
setUp()123     public void setUp() throws Exception {
124         MockitoAnnotations.initMocks(this);
125         mContentResolver = new MockContentResolver();
126         mContentResolver.addProvider(Settings.AUTHORITY,
127                 new FakeSettingsProvider());
128         when(mCtx.getContentResolver()).thenReturn(mContentResolver);
129         mDnsManager = new DnsManager(mCtx, mMockDnsResolver);
130 
131         // Clear the private DNS settings
132         Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "");
133         Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, "");
134         Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "");
135     }
136 
137     @Test
testTrackedValidationUpdates()138     public void testTrackedValidationUpdates() throws Exception {
139         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
140                 mDnsManager.getPrivateDnsConfig());
141         mDnsManager.updatePrivateDns(new Network(TEST_NETID_ALTERNATE),
142                 mDnsManager.getPrivateDnsConfig());
143         LinkProperties lp = new LinkProperties();
144         lp.setInterfaceName(TEST_IFACENAME);
145         lp.addDnsServer(InetAddress.getByName("3.3.3.3"));
146         lp.addDnsServer(InetAddress.getByName("4.4.4.4"));
147 
148         // Send a validation event that is tracked on the alternate netId
149         final NetworkCapabilities nc = new NetworkCapabilities();
150         nc.setTransportTypes(TEST_TRANSPORT_TYPES);
151         mDnsManager.updateCapabilitiesForNetwork(TEST_NETID, nc);
152         mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp);
153         mDnsManager.flushVmDnsCache();
154         mDnsManager.updateCapabilitiesForNetwork(TEST_NETID_ALTERNATE, nc);
155         mDnsManager.noteDnsServersForNetwork(TEST_NETID_ALTERNATE, lp);
156         mDnsManager.flushVmDnsCache();
157         mDnsManager.updatePrivateDnsValidation(
158                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_ALTERNATE,
159                         InetAddress.parseNumericAddress("4.4.4.4"), "",
160                         VALIDATION_RESULT_SUCCESS));
161         LinkProperties fixedLp = new LinkProperties(lp);
162         mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
163         assertFalse(fixedLp.isPrivateDnsActive());
164         assertNull(fixedLp.getPrivateDnsServerName());
165         fixedLp = new LinkProperties(lp);
166         mDnsManager.updatePrivateDnsStatus(TEST_NETID_ALTERNATE, fixedLp);
167         assertTrue(fixedLp.isPrivateDnsActive());
168         assertNull(fixedLp.getPrivateDnsServerName());
169         assertEquals(Arrays.asList(InetAddress.getByName("4.4.4.4")),
170                 fixedLp.getValidatedPrivateDnsServers());
171 
172         // Set up addresses for strict mode and switch to it.
173         lp.addLinkAddress(new LinkAddress("192.0.2.4/24"));
174         lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"),
175                 TEST_IFACENAME));
176         lp.addLinkAddress(new LinkAddress("2001:db8:1::1/64"));
177         lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"),
178                 TEST_IFACENAME));
179 
180         ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
181         ConnectivitySettingsManager.setPrivateDnsHostname(mCtx, "strictmode.com");
182         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
183                 new PrivateDnsConfig("strictmode.com", new InetAddress[] {
184                     InetAddress.parseNumericAddress("6.6.6.6"),
185                     InetAddress.parseNumericAddress("2001:db8:66:66::1")
186                     }));
187         mDnsManager.updateCapabilitiesForNetwork(TEST_NETID, nc);
188         mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp);
189         mDnsManager.flushVmDnsCache();
190         fixedLp = new LinkProperties(lp);
191         mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
192         assertTrue(fixedLp.isPrivateDnsActive());
193         assertEquals("strictmode.com", fixedLp.getPrivateDnsServerName());
194         // No validation events yet.
195         assertEquals(Arrays.asList(new InetAddress[0]), fixedLp.getValidatedPrivateDnsServers());
196         // Validate one.
197         mDnsManager.updatePrivateDnsValidation(
198                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
199                         InetAddress.parseNumericAddress("6.6.6.6"), "strictmode.com",
200                         VALIDATION_RESULT_SUCCESS));
201         fixedLp = new LinkProperties(lp);
202         mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
203         assertEquals(Arrays.asList(InetAddress.parseNumericAddress("6.6.6.6")),
204                 fixedLp.getValidatedPrivateDnsServers());
205         // Validate the 2nd one.
206         mDnsManager.updatePrivateDnsValidation(
207                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
208                         InetAddress.parseNumericAddress("2001:db8:66:66::1"), "strictmode.com",
209                         VALIDATION_RESULT_SUCCESS));
210         fixedLp = new LinkProperties(lp);
211         mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
212         assertEquals(Arrays.asList(
213                         InetAddress.parseNumericAddress("2001:db8:66:66::1"),
214                         InetAddress.parseNumericAddress("6.6.6.6")),
215                 fixedLp.getValidatedPrivateDnsServers());
216     }
217 
218     @Test
testIgnoreUntrackedValidationUpdates()219     public void testIgnoreUntrackedValidationUpdates() throws Exception {
220         // The PrivateDnsConfig map is empty, so no validation events will
221         // be tracked.
222         LinkProperties lp = new LinkProperties();
223         lp.addDnsServer(InetAddress.getByName("3.3.3.3"));
224         final NetworkCapabilities nc = new NetworkCapabilities();
225         nc.setTransportTypes(TEST_TRANSPORT_TYPES);
226         mDnsManager.updateCapabilitiesForNetwork(TEST_NETID, nc);
227         mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp);
228         mDnsManager.flushVmDnsCache();
229         mDnsManager.updatePrivateDnsValidation(
230                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
231                         InetAddress.parseNumericAddress("3.3.3.3"), "",
232                         VALIDATION_RESULT_SUCCESS));
233         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
234         assertFalse(lp.isPrivateDnsActive());
235         assertNull(lp.getPrivateDnsServerName());
236 
237         // Validation event has untracked netId
238         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
239                 mDnsManager.getPrivateDnsConfig());
240         mDnsManager.updateCapabilitiesForNetwork(TEST_NETID, nc);
241         mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp);
242         mDnsManager.flushVmDnsCache();
243         mDnsManager.updatePrivateDnsValidation(
244                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_UNTRACKED,
245                         InetAddress.parseNumericAddress("3.3.3.3"), "",
246                         VALIDATION_RESULT_SUCCESS));
247         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
248         assertFalse(lp.isPrivateDnsActive());
249         assertNull(lp.getPrivateDnsServerName());
250 
251         // Validation event has untracked ipAddress
252         mDnsManager.updatePrivateDnsValidation(
253                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
254                         InetAddress.parseNumericAddress("4.4.4.4"), "",
255                         VALIDATION_RESULT_SUCCESS));
256         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
257         assertFalse(lp.isPrivateDnsActive());
258         assertNull(lp.getPrivateDnsServerName());
259 
260         // Validation event has untracked hostname
261         mDnsManager.updatePrivateDnsValidation(
262                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
263                         InetAddress.parseNumericAddress("3.3.3.3"), "hostname",
264                         VALIDATION_RESULT_SUCCESS));
265         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
266         assertFalse(lp.isPrivateDnsActive());
267         assertNull(lp.getPrivateDnsServerName());
268 
269         // Validation event failed
270         mDnsManager.updatePrivateDnsValidation(
271                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
272                         InetAddress.parseNumericAddress("3.3.3.3"), "",
273                         VALIDATION_RESULT_FAILURE));
274         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
275         assertFalse(lp.isPrivateDnsActive());
276         assertNull(lp.getPrivateDnsServerName());
277 
278         // Network removed
279         mDnsManager.removeNetwork(new Network(TEST_NETID));
280         mDnsManager.updatePrivateDnsValidation(
281                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
282                         InetAddress.parseNumericAddress("3.3.3.3"), "", VALIDATION_RESULT_SUCCESS));
283         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
284         assertFalse(lp.isPrivateDnsActive());
285         assertNull(lp.getPrivateDnsServerName());
286 
287         // Turn private DNS mode off
288         ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_OFF);
289         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
290                 mDnsManager.getPrivateDnsConfig());
291         mDnsManager.updateCapabilitiesForNetwork(TEST_NETID, nc);
292         mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp);
293         mDnsManager.flushVmDnsCache();
294         mDnsManager.updatePrivateDnsValidation(
295                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
296                         InetAddress.parseNumericAddress("3.3.3.3"), "",
297                         VALIDATION_RESULT_SUCCESS));
298         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
299         assertFalse(lp.isPrivateDnsActive());
300         assertNull(lp.getPrivateDnsServerName());
301     }
302 
303     @Test
testOverrideDefaultMode()304     public void testOverrideDefaultMode() throws Exception {
305         // Hard-coded default is opportunistic mode.
306         final PrivateDnsConfig cfgAuto = DnsManager.getPrivateDnsConfig(mCtx);
307         assertEquals(PRIVATE_DNS_MODE_OPPORTUNISTIC, cfgAuto.mode);
308         assertEquals("", cfgAuto.hostname);
309         assertEquals(new InetAddress[0], cfgAuto.ips);
310 
311         // Pretend a gservices push sets the default to "off".
312         ConnectivitySettingsManager.setPrivateDnsDefaultMode(mCtx, PRIVATE_DNS_MODE_OFF);
313         final PrivateDnsConfig cfgOff = DnsManager.getPrivateDnsConfig(mCtx);
314         assertEquals(PRIVATE_DNS_MODE_OFF, cfgOff.mode);
315         assertEquals("", cfgOff.hostname);
316         assertEquals(new InetAddress[0], cfgOff.ips);
317 
318         // Strict mode still works.
319         ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
320         ConnectivitySettingsManager.setPrivateDnsHostname(mCtx, "strictmode.com");
321         final PrivateDnsConfig cfgStrict = DnsManager.getPrivateDnsConfig(mCtx);
322         assertEquals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, cfgStrict.mode);
323         assertEquals("strictmode.com", cfgStrict.hostname);
324         assertEquals(new InetAddress[0], cfgStrict.ips);
325     }
326 
327     @Test
testSendDnsConfiguration()328     public void testSendDnsConfiguration() throws Exception {
329         reset(mMockDnsResolver);
330         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
331                 mDnsManager.getPrivateDnsConfig());
332         final LinkProperties lp = new LinkProperties();
333         lp.setInterfaceName(TEST_IFACENAME);
334         lp.addDnsServer(InetAddress.getByName("3.3.3.3"));
335         lp.addDnsServer(InetAddress.getByName("4.4.4.4"));
336         final NetworkCapabilities nc = new NetworkCapabilities();
337         nc.setTransportTypes(TEST_TRANSPORT_TYPES);
338         mDnsManager.updateCapabilitiesForNetwork(TEST_NETID, nc);
339         mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp);
340         mDnsManager.flushVmDnsCache();
341 
342         final ResolverParamsParcel expectedParams = new ResolverParamsParcel();
343         expectedParams.netId = TEST_NETID;
344         expectedParams.sampleValiditySeconds = TEST_DEFAULT_SAMPLE_VALIDITY_SECONDS;
345         expectedParams.successThreshold = TEST_DEFAULT_SUCCESS_THRESHOLD_PERCENT;
346         expectedParams.minSamples = TEST_DEFAULT_MIN_SAMPLES;
347         expectedParams.maxSamples = TEST_DEFAULT_MAX_SAMPLES;
348         expectedParams.servers = new String[]{"3.3.3.3", "4.4.4.4"};
349         expectedParams.domains = new String[]{};
350         expectedParams.tlsName = "";
351         expectedParams.tlsServers = new String[]{"3.3.3.3", "4.4.4.4"};
352         expectedParams.transportTypes = TEST_TRANSPORT_TYPES;
353         expectedParams.resolverOptions = null;
354         expectedParams.meteredNetwork = true;
355         expectedParams.dohParams = null;
356         expectedParams.interfaceNames = new String[]{TEST_IFACENAME};
357         verify(mMockDnsResolver, times(1)).setResolverConfiguration(eq(expectedParams));
358     }
359 
360     @Test
testTransportTypesEqual()361     public void testTransportTypesEqual() throws Exception {
362         SparseArray<String> ncTransTypes = MessageUtils.findMessageNames(
363                 new Class[] { NetworkCapabilities.class }, new String[]{ "TRANSPORT_" });
364         SparseArray<String> dnsTransTypes = MessageUtils.findMessageNames(
365                 new Class[] { IDnsResolver.class }, new String[]{ "TRANSPORT_" });
366         assertEquals(0, MIN_TRANSPORT);
367         assertEquals(MAX_TRANSPORT + 1, ncTransTypes.size());
368         // TRANSPORT_UNKNOWN in IDnsResolver is defined to -1 and only for resolver.
369         assertEquals("TRANSPORT_UNKNOWN", dnsTransTypes.get(-1));
370         assertEquals(ncTransTypes.size(), dnsTransTypes.size() - 1);
371         for (int i = MIN_TRANSPORT; i < MAX_TRANSPORT; i++) {
372             String name = ncTransTypes.get(i, null);
373             assertNotNull("Could not find NetworkCapabilies.TRANSPORT_* constant equal to "
374                     + i, name);
375             assertEquals(name, dnsTransTypes.get(i));
376         }
377     }
378 
379     @Test
testGetPrivateDnsConfigForNetwork()380     public void testGetPrivateDnsConfigForNetwork() throws Exception {
381         final Network network = new Network(TEST_NETID);
382         final InetAddress dnsAddr = InetAddressUtils.parseNumericAddress("3.3.3.3");
383         final InetAddress[] tlsAddrs = new InetAddress[]{
384             InetAddressUtils.parseNumericAddress("6.6.6.6"),
385             InetAddressUtils.parseNumericAddress("2001:db8:66:66::1")
386         };
387         final String tlsName = "strictmode.com";
388         LinkProperties lp = new LinkProperties();
389         lp.addDnsServer(dnsAddr);
390 
391         // The PrivateDnsConfig map is empty, so the default PRIVATE_DNS_OFF is returned.
392         PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
393         assertEquals(PRIVATE_DNS_MODE_OFF, privateDnsCfg.mode);
394         assertEquals("", privateDnsCfg.hostname);
395         assertEquals(new InetAddress[0], privateDnsCfg.ips);
396 
397         // An entry with default PrivateDnsConfig is added to the PrivateDnsConfig map.
398         mDnsManager.updatePrivateDns(network, mDnsManager.getPrivateDnsConfig());
399         mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp);
400         mDnsManager.updatePrivateDnsValidation(
401                 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, dnsAddr, "",
402                         VALIDATION_RESULT_SUCCESS));
403         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
404         privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
405         assertEquals(PRIVATE_DNS_MODE_OPPORTUNISTIC, privateDnsCfg.mode);
406         assertEquals("", privateDnsCfg.hostname);
407         assertEquals(new InetAddress[0], privateDnsCfg.ips);
408 
409         // The original entry is overwritten by a new PrivateDnsConfig.
410         mDnsManager.updatePrivateDns(network, new PrivateDnsConfig(tlsName, tlsAddrs));
411         mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
412         privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
413         assertEquals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, privateDnsCfg.mode);
414         assertEquals(tlsName, privateDnsCfg.hostname);
415         assertEquals(tlsAddrs, privateDnsCfg.ips);
416 
417         // The network is removed, so the PrivateDnsConfig map becomes empty again.
418         mDnsManager.removeNetwork(network);
419         privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
420         assertEquals(PRIVATE_DNS_MODE_OFF, privateDnsCfg.mode);
421         assertEquals("", privateDnsCfg.hostname);
422         assertEquals(new InetAddress[0], privateDnsCfg.ips);
423     }
424 }
425