diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index ccda9c503e..770e6fb043 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -10052,36 +10052,37 @@ public class ConnectivityService extends IConnectivityManager.Stub return; } - final CompareResult result = - LinkPropertiesUtils.compareAllAddresses(oldLp, newLp); - - if (!result.added.isEmpty()) { - for (LinkAddress la : result.added) { - if (la.getAddress() instanceof Inet6Address - && la.getAddress().isLinkLocalAddress()) { - // Some NetworkAgents may not report IPv6 link local address to CS, thus socket - // destruction on the address will be done at handling RTM_DELADDR and the - // address doesn't need to be added to mIpToNetworksMap. - continue; - } - mIpToNetworksMap.computeIfAbsent(la.getAddress(), k -> new ArraySet<>()).add(nai); - } + if (!nai.isCreated()) { + return; } - if (!result.removed.isEmpty()) { - for (LinkAddress la : result.removed) { - if (la.getAddress() instanceof Inet6Address - && la.getAddress().isLinkLocalAddress()) { - continue; - } - final Set networks = mIpToNetworksMap.get(la.getAddress()); - destroySocketsForRemovedAddress(la.getAddress(), nai, networks); - if (networks != null) { - networks.remove(nai); - if (networks.isEmpty()) { - mIpToNetworksMap.remove(la.getAddress()); - } - } + final CompareResult result = + LinkPropertiesUtils.compareAllAddresses(oldLp, newLp); + + for (InetAddress address : result.added) { + if (address instanceof Inet6Address && address.isLinkLocalAddress()) { + // Some NetworkAgents may not report IPv6 link local address to CS, thus socket + // destruction on the address will be done at handling RTM_DELADDR and the + // address doesn't need to be added to mIpToNetworksMap. + continue; + } + mIpToNetworksMap.computeIfAbsent(address, k -> new ArraySet<>()).add(nai); + } + + for (InetAddress address : result.removed) { + if (address instanceof Inet6Address && address.isLinkLocalAddress()) { + continue; + } + final Set networks = mIpToNetworksMap.get(address); + if (networks == null) { + loge("No matched network for " + address); + mIpToNetworksMap.remove(address); + continue; + } + destroySocketsForRemovedAddress(address, nai, networks); + networks.remove(nai); + if (networks.isEmpty()) { + mIpToNetworksMap.remove(address); } } } diff --git a/staticlibs/framework/com/android/net/module/util/LinkPropertiesUtils.java b/staticlibs/framework/com/android/net/module/util/LinkPropertiesUtils.java index 4760dfca5f..669566b8a5 100644 --- a/staticlibs/framework/com/android/net/module/util/LinkPropertiesUtils.java +++ b/staticlibs/framework/com/android/net/module/util/LinkPropertiesUtils.java @@ -147,20 +147,25 @@ public final class LinkPropertiesUtils { } /** - * Compares the all addresses including stacked addresses in {@code left} LinkProperties with - * {@code right} LinkProperties, examining only addresses on the base link. + * Compares the all addresses {@link InetAddress} including stacked addresses in {@code left} + * LinkProperties with {@code right} LinkProperties, examining only addresses on the base link. * * @param left A LinkProperties with the old list of all addresses. * @param right A LinkProperties with the new list of all addresses. * @return the differences between the addresses. */ - public static @NonNull CompareResult compareAllAddresses( + public static @NonNull CompareResult compareAllAddresses( @Nullable LinkProperties left, @Nullable LinkProperties right) { + final List leftAddresses = left != null + ? CollectionUtils.map(left.getAllLinkAddresses(), LinkAddress::getAddress) + : null; + final List rightAddresses = right != null + ? CollectionUtils.map(right.getAllLinkAddresses(), LinkAddress::getAddress) + : null; /* * Same logic as compareAddresses() */ - return new CompareResult<>(left != null ? left.getAllLinkAddresses() : null, - right != null ? right.getAllLinkAddresses() : null); + return new CompareResult<>(leftAddresses, rightAddresses); } /**