Loading services/core/java/com/android/server/ConnectivityService.java +30 −43 Original line number Diff line number Diff line Loading @@ -142,10 +142,13 @@ import android.net.UnderlyingNetworkInfo; import android.net.Uri; import android.net.VpnManager; import android.net.VpnTransportInfo; import android.net.metrics.INetdEventListener; import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; import android.net.netlink.InetDiagMessage; import android.net.resolv.aidl.DnsHealthEventParcel; import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener; import android.net.resolv.aidl.Nat64PrefixEventParcel; import android.net.resolv.aidl.PrivateDnsValidationEventParcel; import android.net.shared.PrivateDnsConfig; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; Loading Loading @@ -2037,25 +2040,24 @@ public class ConnectivityService extends IConnectivityManager.Stub return true; } private class NetdEventCallback extends INetdEventListener.Stub { class DnsResolverUnsolicitedEventCallback extends IDnsResolverUnsolicitedEventListener.Stub { @Override public void onPrivateDnsValidationEvent(int netId, String ipAddress, String hostname, boolean validated) { public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) { try { mHandler.sendMessage(mHandler.obtainMessage( EVENT_PRIVATE_DNS_VALIDATION_UPDATE, new PrivateDnsValidationUpdate(netId, InetAddresses.parseNumericAddress(ipAddress), hostname, validated))); new PrivateDnsValidationUpdate(event.netId, InetAddresses.parseNumericAddress(event.ipAddress), event.hostname, event.validation))); } catch (IllegalArgumentException e) { loge("Error parsing ip address in validation event"); } } @Override public void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs, String hostname, String[] ipAddresses, int ipAddressesCount, int uid) { NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); public void onDnsHealthEvent(final DnsHealthEventParcel event) { NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId); // Netd event only allow registrants from system. Each NetworkMonitor thread is under // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd // event callback for certain nai. e.g. cellular. Register here to pass to Loading @@ -2064,34 +2066,18 @@ public class ConnectivityService extends IConnectivityManager.Stub // callback from each caller type. Need to re-factor NetdEventListenerService to allow // multiple NetworkMonitor registrants. if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) { nai.networkMonitor().notifyDnsResponse(returnCode); nai.networkMonitor().notifyDnsResponse(event.healthResult); } } @Override public void onNat64PrefixEvent(int netId, boolean added, String prefixString, int prefixLength) { mHandler.post(() -> handleNat64PrefixEvent(netId, added, prefixString, prefixLength)); public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) { mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation, event.prefixAddress, event.prefixLength)); } @Override public void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port, int uid) { } @Override public void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader, byte[] dstHw, String srcIp, String dstIp, int srcPort, int dstPort, long timestampNs) { } @Override public void onTcpSocketStatsEvent(int[] networkIds, int[] sentPackets, int[] lostPackets, int[] rttsUs, int[] sentAckDiffsMs) { } @Override public int getInterfaceVersion() throws RemoteException { public int getInterfaceVersion() { return this.VERSION; } Loading @@ -2099,16 +2085,17 @@ public class ConnectivityService extends IConnectivityManager.Stub public String getInterfaceHash() { return this.HASH; } }; } @VisibleForTesting protected final INetdEventListener mNetdEventCallback = new NetdEventCallback(); protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback = new DnsResolverUnsolicitedEventCallback(); private void registerNetdEventCallback() { private void registerDnsResolverUnsolicitedEventListener() { try { mDnsResolver.registerEventListener(mNetdEventCallback); mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback); } catch (Exception e) { loge("Error registering DnsResolver callback: " + e); loge("Error registering DnsResolver unsolicited event callback: " + e); } } Loading Loading @@ -2439,7 +2426,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // to ensure the tracking will be initialized correctly. mPermissionMonitor.startMonitoring(); mProxyTracker.loadGlobalProxy(); registerNetdEventCallback(); registerDnsResolverUnsolicitedEventListener(); synchronized (this) { mSystemReady = true; Loading Loading @@ -3370,21 +3357,21 @@ public class ConnectivityService extends IConnectivityManager.Stub handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); } private void handleNat64PrefixEvent(int netId, boolean added, String prefixString, private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress, int prefixLength) { NetworkAgentInfo nai = mNetworkForNetId.get(netId); if (nai == null) return; log(String.format("NAT64 prefix %s on netId %d: %s/%d", (added ? "added" : "removed"), netId, prefixString, prefixLength)); log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d", netId, operation, prefixAddress, prefixLength)); IpPrefix prefix = null; if (added) { if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) { try { prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixString), prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress), prefixLength); } catch (IllegalArgumentException e) { loge("Invalid NAT64 prefix " + prefixString + "/" + prefixLength); loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength); return; } } Loading services/core/java/com/android/server/connectivity/DnsManager.java +14 −8 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.server.connectivity; import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE_FALLBACK; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; import static android.provider.Settings.Global.DNS_RESOLVER_MAX_SAMPLES; import static android.provider.Settings.Global.DNS_RESOLVER_MIN_SAMPLES; import static android.provider.Settings.Global.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS; Loading Loading @@ -147,17 +149,18 @@ public class DnsManager { } public static class PrivateDnsValidationUpdate { final public int netId; final public InetAddress ipAddress; final public String hostname; final public boolean validated; public final int netId; public final InetAddress ipAddress; public final String hostname; // Refer to IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_*. public final int validationResult; public PrivateDnsValidationUpdate(int netId, InetAddress ipAddress, String hostname, boolean validated) { String hostname, int validationResult) { this.netId = netId; this.ipAddress = ipAddress; this.hostname = hostname; this.validated = validated; this.validationResult = validationResult; } } Loading Loading @@ -216,10 +219,13 @@ public class DnsManager { if (!mValidationMap.containsKey(p)) { return; } if (update.validated) { if (update.validationResult == VALIDATION_RESULT_SUCCESS) { mValidationMap.put(p, ValidationStatus.SUCCEEDED); } else { } else if (update.validationResult == VALIDATION_RESULT_FAILURE) { mValidationMap.put(p, ValidationStatus.FAILED); } else { Log.e(TAG, "Unknown private dns validation operation=" + update.validationResult); } } Loading tests/net/java/com/android/server/ConnectivityServiceTest.java +54 −24 Original line number Diff line number Diff line Loading @@ -90,6 +90,10 @@ import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; import static android.net.RouteInfo.RTN_UNREACHABLE; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; import static android.os.Process.INVALID_UID; import static android.system.OsConstants.IPPROTO_TCP; Loading Loading @@ -217,6 +221,8 @@ import android.net.Uri; import android.net.VpnManager; import android.net.VpnTransportInfo; import android.net.metrics.IpConnectivityLog; import android.net.resolv.aidl.Nat64PrefixEventParcel; import android.net.resolv.aidl.PrivateDnsValidationEventParcel; import android.net.shared.NetworkMonitorUtils; import android.net.shared.PrivateDnsConfig; import android.net.util.MultinetworkPolicyTracker; Loading Loading @@ -5919,6 +5925,16 @@ public class ConnectivityServiceTest { assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName()); } private PrivateDnsValidationEventParcel makePrivateDnsValidationEvent( final int netId, final String ipAddress, final String hostname, final int validation) { final PrivateDnsValidationEventParcel event = new PrivateDnsValidationEventParcel(); event.netId = netId; event.ipAddress = ipAddress; event.hostname = hostname; event.validation = validation; return event; } @Test public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception { // The default on Android is opportunistic mode ("Automatic"). Loading Loading @@ -5949,8 +5965,9 @@ public class ConnectivityServiceTest { // 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); mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "", "145.100.185.18", VALIDATION_RESULT_SUCCESS)); cellNetworkCallback.assertNoCallback(); // Add a dns server to the LinkProperties. Loading @@ -5967,20 +5984,23 @@ public class ConnectivityServiceTest { // 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); mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "hostname", VALIDATION_RESULT_SUCCESS)); cellNetworkCallback.assertNoCallback(); // Send a validation event where validation failed. mService.mNetdEventCallback.onPrivateDnsValidationEvent( mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", false); mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", VALIDATION_RESULT_FAILURE)); 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); mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", VALIDATION_RESULT_SUCCESS)); cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); cellNetworkCallback.assertNoCallback(); Loading Loading @@ -7824,6 +7844,16 @@ public class ConnectivityServiceTest { return stacked; } private Nat64PrefixEventParcel makeNat64PrefixEvent(final int netId, final int prefixOperation, final String prefixAddress, final int prefixLength) { final Nat64PrefixEventParcel event = new Nat64PrefixEventParcel(); event.netId = netId; event.prefixOperation = prefixOperation; event.prefixAddress = prefixAddress; event.prefixLength = prefixLength; return event; } @Test public void testStackedLinkProperties() throws Exception { final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24"); Loading Loading @@ -7908,8 +7938,8 @@ public class ConnectivityServiceTest { // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started. Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent); assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix()); mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, kNat64PrefixString, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent( makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); LinkProperties lpBeforeClat = networkCallback.expectCallback( CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp(); assertEquals(0, lpBeforeClat.getStackedLinks().size()); Loading Loading @@ -7949,8 +7979,8 @@ public class ConnectivityServiceTest { .thenReturn(getClatInterfaceConfigParcel(myIpv4)); // Change the NAT64 prefix without first removing it. // Expect clatd to be stopped and started with the new prefix. mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, kOtherNat64PrefixString, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( cellNetId, PREFIX_OPERATION_ADDED, kOtherNat64PrefixString, 96)); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getStackedLinks().size() == 0); verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); Loading Loading @@ -7998,8 +8028,8 @@ public class ConnectivityServiceTest { .thenReturn(getClatInterfaceConfigParcel(myIpv4)); // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone. mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */, kOtherNat64PrefixString, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( cellNetId, PREFIX_OPERATION_REMOVED, kOtherNat64PrefixString, 96)); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getNat64Prefix() == null); Loading @@ -8011,8 +8041,8 @@ public class ConnectivityServiceTest { networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added. verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, kNat64PrefixString, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString()); Loading @@ -8024,8 +8054,8 @@ public class ConnectivityServiceTest { verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); // NAT64 prefix is removed. Expect that clat is stopped. mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */, kNat64PrefixString, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( cellNetId, PREFIX_OPERATION_REMOVED, kNat64PrefixString, 96)); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null); assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault); Loading Loading @@ -8113,8 +8143,8 @@ public class ConnectivityServiceTest { inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */, pref64FromDnsStr, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent( makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); Loading Loading @@ -8147,8 +8177,8 @@ public class ConnectivityServiceTest { inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); // Stopping prefix discovery results in a prefix removed notification. mService.mNetdEventCallback.onNat64PrefixEvent(netId, false /* added */, pref64FromDnsStr, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent( makeNat64PrefixEvent(netId, PREFIX_OPERATION_REMOVED, pref64FromDnsStr, 96)); inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); Loading Loading @@ -8186,8 +8216,8 @@ public class ConnectivityServiceTest { inOrder.verify(mMockNetd).clatdStop(iface); inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */, pref64FromDnsStr, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent( makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any()); Loading tests/net/java/com/android/server/connectivity/DnsManagerTest.java +23 −12 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/ConnectivityService.java +30 −43 Original line number Diff line number Diff line Loading @@ -142,10 +142,13 @@ import android.net.UnderlyingNetworkInfo; import android.net.Uri; import android.net.VpnManager; import android.net.VpnTransportInfo; import android.net.metrics.INetdEventListener; import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; import android.net.netlink.InetDiagMessage; import android.net.resolv.aidl.DnsHealthEventParcel; import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener; import android.net.resolv.aidl.Nat64PrefixEventParcel; import android.net.resolv.aidl.PrivateDnsValidationEventParcel; import android.net.shared.PrivateDnsConfig; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; Loading Loading @@ -2037,25 +2040,24 @@ public class ConnectivityService extends IConnectivityManager.Stub return true; } private class NetdEventCallback extends INetdEventListener.Stub { class DnsResolverUnsolicitedEventCallback extends IDnsResolverUnsolicitedEventListener.Stub { @Override public void onPrivateDnsValidationEvent(int netId, String ipAddress, String hostname, boolean validated) { public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) { try { mHandler.sendMessage(mHandler.obtainMessage( EVENT_PRIVATE_DNS_VALIDATION_UPDATE, new PrivateDnsValidationUpdate(netId, InetAddresses.parseNumericAddress(ipAddress), hostname, validated))); new PrivateDnsValidationUpdate(event.netId, InetAddresses.parseNumericAddress(event.ipAddress), event.hostname, event.validation))); } catch (IllegalArgumentException e) { loge("Error parsing ip address in validation event"); } } @Override public void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs, String hostname, String[] ipAddresses, int ipAddressesCount, int uid) { NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); public void onDnsHealthEvent(final DnsHealthEventParcel event) { NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId); // Netd event only allow registrants from system. Each NetworkMonitor thread is under // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd // event callback for certain nai. e.g. cellular. Register here to pass to Loading @@ -2064,34 +2066,18 @@ public class ConnectivityService extends IConnectivityManager.Stub // callback from each caller type. Need to re-factor NetdEventListenerService to allow // multiple NetworkMonitor registrants. if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) { nai.networkMonitor().notifyDnsResponse(returnCode); nai.networkMonitor().notifyDnsResponse(event.healthResult); } } @Override public void onNat64PrefixEvent(int netId, boolean added, String prefixString, int prefixLength) { mHandler.post(() -> handleNat64PrefixEvent(netId, added, prefixString, prefixLength)); public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) { mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation, event.prefixAddress, event.prefixLength)); } @Override public void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port, int uid) { } @Override public void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader, byte[] dstHw, String srcIp, String dstIp, int srcPort, int dstPort, long timestampNs) { } @Override public void onTcpSocketStatsEvent(int[] networkIds, int[] sentPackets, int[] lostPackets, int[] rttsUs, int[] sentAckDiffsMs) { } @Override public int getInterfaceVersion() throws RemoteException { public int getInterfaceVersion() { return this.VERSION; } Loading @@ -2099,16 +2085,17 @@ public class ConnectivityService extends IConnectivityManager.Stub public String getInterfaceHash() { return this.HASH; } }; } @VisibleForTesting protected final INetdEventListener mNetdEventCallback = new NetdEventCallback(); protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback = new DnsResolverUnsolicitedEventCallback(); private void registerNetdEventCallback() { private void registerDnsResolverUnsolicitedEventListener() { try { mDnsResolver.registerEventListener(mNetdEventCallback); mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback); } catch (Exception e) { loge("Error registering DnsResolver callback: " + e); loge("Error registering DnsResolver unsolicited event callback: " + e); } } Loading Loading @@ -2439,7 +2426,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // to ensure the tracking will be initialized correctly. mPermissionMonitor.startMonitoring(); mProxyTracker.loadGlobalProxy(); registerNetdEventCallback(); registerDnsResolverUnsolicitedEventListener(); synchronized (this) { mSystemReady = true; Loading Loading @@ -3370,21 +3357,21 @@ public class ConnectivityService extends IConnectivityManager.Stub handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); } private void handleNat64PrefixEvent(int netId, boolean added, String prefixString, private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress, int prefixLength) { NetworkAgentInfo nai = mNetworkForNetId.get(netId); if (nai == null) return; log(String.format("NAT64 prefix %s on netId %d: %s/%d", (added ? "added" : "removed"), netId, prefixString, prefixLength)); log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d", netId, operation, prefixAddress, prefixLength)); IpPrefix prefix = null; if (added) { if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) { try { prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixString), prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress), prefixLength); } catch (IllegalArgumentException e) { loge("Invalid NAT64 prefix " + prefixString + "/" + prefixLength); loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength); return; } } Loading
services/core/java/com/android/server/connectivity/DnsManager.java +14 −8 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.server.connectivity; import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE_FALLBACK; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; import static android.provider.Settings.Global.DNS_RESOLVER_MAX_SAMPLES; import static android.provider.Settings.Global.DNS_RESOLVER_MIN_SAMPLES; import static android.provider.Settings.Global.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS; Loading Loading @@ -147,17 +149,18 @@ public class DnsManager { } public static class PrivateDnsValidationUpdate { final public int netId; final public InetAddress ipAddress; final public String hostname; final public boolean validated; public final int netId; public final InetAddress ipAddress; public final String hostname; // Refer to IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_*. public final int validationResult; public PrivateDnsValidationUpdate(int netId, InetAddress ipAddress, String hostname, boolean validated) { String hostname, int validationResult) { this.netId = netId; this.ipAddress = ipAddress; this.hostname = hostname; this.validated = validated; this.validationResult = validationResult; } } Loading Loading @@ -216,10 +219,13 @@ public class DnsManager { if (!mValidationMap.containsKey(p)) { return; } if (update.validated) { if (update.validationResult == VALIDATION_RESULT_SUCCESS) { mValidationMap.put(p, ValidationStatus.SUCCEEDED); } else { } else if (update.validationResult == VALIDATION_RESULT_FAILURE) { mValidationMap.put(p, ValidationStatus.FAILED); } else { Log.e(TAG, "Unknown private dns validation operation=" + update.validationResult); } } Loading
tests/net/java/com/android/server/ConnectivityServiceTest.java +54 −24 Original line number Diff line number Diff line Loading @@ -90,6 +90,10 @@ import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; import static android.net.RouteInfo.RTN_UNREACHABLE; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; import static android.os.Process.INVALID_UID; import static android.system.OsConstants.IPPROTO_TCP; Loading Loading @@ -217,6 +221,8 @@ import android.net.Uri; import android.net.VpnManager; import android.net.VpnTransportInfo; import android.net.metrics.IpConnectivityLog; import android.net.resolv.aidl.Nat64PrefixEventParcel; import android.net.resolv.aidl.PrivateDnsValidationEventParcel; import android.net.shared.NetworkMonitorUtils; import android.net.shared.PrivateDnsConfig; import android.net.util.MultinetworkPolicyTracker; Loading Loading @@ -5919,6 +5925,16 @@ public class ConnectivityServiceTest { assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName()); } private PrivateDnsValidationEventParcel makePrivateDnsValidationEvent( final int netId, final String ipAddress, final String hostname, final int validation) { final PrivateDnsValidationEventParcel event = new PrivateDnsValidationEventParcel(); event.netId = netId; event.ipAddress = ipAddress; event.hostname = hostname; event.validation = validation; return event; } @Test public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception { // The default on Android is opportunistic mode ("Automatic"). Loading Loading @@ -5949,8 +5965,9 @@ public class ConnectivityServiceTest { // 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); mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "", "145.100.185.18", VALIDATION_RESULT_SUCCESS)); cellNetworkCallback.assertNoCallback(); // Add a dns server to the LinkProperties. Loading @@ -5967,20 +5984,23 @@ public class ConnectivityServiceTest { // 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); mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "hostname", VALIDATION_RESULT_SUCCESS)); cellNetworkCallback.assertNoCallback(); // Send a validation event where validation failed. mService.mNetdEventCallback.onPrivateDnsValidationEvent( mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", false); mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", VALIDATION_RESULT_FAILURE)); 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); mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", VALIDATION_RESULT_SUCCESS)); cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); cellNetworkCallback.assertNoCallback(); Loading Loading @@ -7824,6 +7844,16 @@ public class ConnectivityServiceTest { return stacked; } private Nat64PrefixEventParcel makeNat64PrefixEvent(final int netId, final int prefixOperation, final String prefixAddress, final int prefixLength) { final Nat64PrefixEventParcel event = new Nat64PrefixEventParcel(); event.netId = netId; event.prefixOperation = prefixOperation; event.prefixAddress = prefixAddress; event.prefixLength = prefixLength; return event; } @Test public void testStackedLinkProperties() throws Exception { final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24"); Loading Loading @@ -7908,8 +7938,8 @@ public class ConnectivityServiceTest { // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started. Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent); assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix()); mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, kNat64PrefixString, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent( makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); LinkProperties lpBeforeClat = networkCallback.expectCallback( CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp(); assertEquals(0, lpBeforeClat.getStackedLinks().size()); Loading Loading @@ -7949,8 +7979,8 @@ public class ConnectivityServiceTest { .thenReturn(getClatInterfaceConfigParcel(myIpv4)); // Change the NAT64 prefix without first removing it. // Expect clatd to be stopped and started with the new prefix. mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, kOtherNat64PrefixString, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( cellNetId, PREFIX_OPERATION_ADDED, kOtherNat64PrefixString, 96)); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getStackedLinks().size() == 0); verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); Loading Loading @@ -7998,8 +8028,8 @@ public class ConnectivityServiceTest { .thenReturn(getClatInterfaceConfigParcel(myIpv4)); // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone. mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */, kOtherNat64PrefixString, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( cellNetId, PREFIX_OPERATION_REMOVED, kOtherNat64PrefixString, 96)); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getNat64Prefix() == null); Loading @@ -8011,8 +8041,8 @@ public class ConnectivityServiceTest { networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added. verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, kNat64PrefixString, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString()); Loading @@ -8024,8 +8054,8 @@ public class ConnectivityServiceTest { verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); // NAT64 prefix is removed. Expect that clat is stopped. mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */, kNat64PrefixString, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( cellNetId, PREFIX_OPERATION_REMOVED, kNat64PrefixString, 96)); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null); assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault); Loading Loading @@ -8113,8 +8143,8 @@ public class ConnectivityServiceTest { inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */, pref64FromDnsStr, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent( makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); Loading Loading @@ -8147,8 +8177,8 @@ public class ConnectivityServiceTest { inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); // Stopping prefix discovery results in a prefix removed notification. mService.mNetdEventCallback.onNat64PrefixEvent(netId, false /* added */, pref64FromDnsStr, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent( makeNat64PrefixEvent(netId, PREFIX_OPERATION_REMOVED, pref64FromDnsStr, 96)); inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); Loading Loading @@ -8186,8 +8216,8 @@ public class ConnectivityServiceTest { inOrder.verify(mMockNetd).clatdStop(iface); inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */, pref64FromDnsStr, 96); mService.mResolverUnsolEventCallback.onNat64PrefixEvent( makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any()); Loading
tests/net/java/com/android/server/connectivity/DnsManagerTest.java +23 −12 File changed.Preview size limit exceeded, changes collapsed. Show changes