Loading core/java/android/net/LinkProperties.java +69 −7 Original line number Diff line number Diff line Loading @@ -21,8 +21,6 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.net.util.LinkPropertiesUtils; import android.net.util.LinkPropertiesUtils.CompareResult; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -92,6 +90,36 @@ public final class LinkProperties implements Parcelable { // Indexed by interface name to allow modification and to prevent duplicates being added. private Hashtable<String, LinkProperties> mStackedLinks = new Hashtable<>(); /** * @hide */ public static class CompareResult<T> { public final List<T> removed = new ArrayList<>(); public final List<T> added = new ArrayList<>(); public CompareResult() {} public CompareResult(Collection<T> oldItems, Collection<T> newItems) { if (oldItems != null) { removed.addAll(oldItems); } if (newItems != null) { for (T newItem : newItems) { if (!removed.remove(newItem)) { added.add(newItem); } } } } @Override public String toString() { return "removed=[" + TextUtils.join(",", removed) + "] added=[" + TextUtils.join(",", added) + "]"; } } /** * @hide */ Loading Loading @@ -1298,7 +1326,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalInterfaceName(@NonNull LinkProperties target) { return LinkPropertiesUtils.isIdenticalInterfaceName(target, this); return TextUtils.equals(getInterfaceName(), target.getInterfaceName()); } /** Loading @@ -1321,7 +1349,10 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalAddresses(@NonNull LinkProperties target) { return LinkPropertiesUtils.isIdenticalAddresses(target, this); Collection<InetAddress> targetAddresses = target.getAddresses(); Collection<InetAddress> sourceAddresses = getAddresses(); return (sourceAddresses.size() == targetAddresses.size()) ? sourceAddresses.containsAll(targetAddresses) : false; } /** Loading @@ -1333,7 +1364,15 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalDnses(@NonNull LinkProperties target) { return LinkPropertiesUtils.isIdenticalDnses(target, this); Collection<InetAddress> targetDnses = target.getDnsServers(); String targetDomains = target.getDomains(); if (mDomains == null) { if (targetDomains != null) return false; } else { if (!mDomains.equals(targetDomains)) return false; } return (mDnses.size() == targetDnses.size()) ? mDnses.containsAll(targetDnses) : false; } /** Loading Loading @@ -1386,7 +1425,9 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalRoutes(@NonNull LinkProperties target) { return LinkPropertiesUtils.isIdenticalRoutes(target, this); Collection<RouteInfo> targetRoutes = target.getRoutes(); return (mRoutes.size() == targetRoutes.size()) ? mRoutes.containsAll(targetRoutes) : false; } /** Loading @@ -1398,7 +1439,8 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public boolean isIdenticalHttpProxy(@NonNull LinkProperties target) { return LinkPropertiesUtils.isIdenticalHttpProxy(target, this); return getHttpProxy() == null ? target.getHttpProxy() == null : getHttpProxy().equals(target.getHttpProxy()); } /** Loading Loading @@ -1620,6 +1662,26 @@ public final class LinkProperties implements Parcelable { && isIdenticalCaptivePortalData(target); } /** * Compares the addresses in this LinkProperties with another * LinkProperties, examining only addresses on the base link. * * @param target a LinkProperties with the new list of addresses * @return the differences between the addresses. * @hide */ public @NonNull CompareResult<LinkAddress> compareAddresses(@Nullable LinkProperties target) { /* * Duplicate the LinkAddresses into removed, we will be removing * address which are common between mLinkAddresses and target * leaving the addresses that are different. And address which * are in target but not in mLinkAddresses are placed in the * addedAddresses. */ return new CompareResult<>(mLinkAddresses, target != null ? target.getLinkAddresses() : null); } /** * Compares the DNS addresses in this LinkProperties with another * LinkProperties, examining only DNS addresses on the base link. Loading core/java/android/net/MacAddress.java +73 −6 Original line number Diff line number Diff line Loading @@ -20,11 +20,11 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.net.util.MacAddressUtils; import android.net.wifi.WifiInfo; import android.os.Parcel; import android.os.Parcelable; import com.android.internal.util.BitUtils; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; Loading @@ -33,6 +33,7 @@ import java.net.Inet6Address; import java.net.UnknownHostException; import java.security.SecureRandom; import java.util.Arrays; import java.util.Random; /** * Representation of a MAC address. Loading Loading @@ -108,12 +109,20 @@ public final class MacAddress implements Parcelable { if (equals(BROADCAST_ADDRESS)) { return TYPE_BROADCAST; } if ((mAddr & MULTICAST_MASK) != 0) { if (isMulticastAddress()) { return TYPE_MULTICAST; } return TYPE_UNICAST; } /** * @return true if this MacAddress is a multicast address. * @hide */ public boolean isMulticastAddress() { return (mAddr & MULTICAST_MASK) != 0; } /** * @return true if this MacAddress is a locally assigned address. */ Loading Loading @@ -183,7 +192,7 @@ public final class MacAddress implements Parcelable { * @hide */ public static boolean isMacAddress(byte[] addr) { return MacAddressUtils.isMacAddress(addr); return addr != null && addr.length == ETHER_ADDR_LEN; } /** Loading Loading @@ -252,11 +261,26 @@ public final class MacAddress implements Parcelable { } private static byte[] byteAddrFromLongAddr(long addr) { return MacAddressUtils.byteAddrFromLongAddr(addr); byte[] bytes = new byte[ETHER_ADDR_LEN]; int index = ETHER_ADDR_LEN; while (index-- > 0) { bytes[index] = (byte) addr; addr = addr >> 8; } return bytes; } private static long longAddrFromByteAddr(byte[] addr) { return MacAddressUtils.longAddrFromByteAddr(addr); Preconditions.checkNotNull(addr); if (!isMacAddress(addr)) { throw new IllegalArgumentException( Arrays.toString(addr) + " was not a valid MAC address"); } long longAddr = 0; for (byte b : addr) { longAddr = (longAddr << 8) + BitUtils.uint8(b); } return longAddr; } // Internal conversion function equivalent to longAddrFromByteAddr(byteAddrFromStringAddr(addr)) Loading Loading @@ -326,7 +350,50 @@ public final class MacAddress implements Parcelable { * @hide */ public static @NonNull MacAddress createRandomUnicastAddressWithGoogleBase() { return MacAddressUtils.createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom()); return createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom()); } /** * Returns a generated MAC address whose 46 bits, excluding the locally assigned bit and the * unicast bit, are randomly selected. * * The locally assigned bit is always set to 1. The multicast bit is always set to 0. * * @return a random locally assigned, unicast MacAddress. * * @hide */ public static @NonNull MacAddress createRandomUnicastAddress() { return createRandomUnicastAddress(null, new SecureRandom()); } /** * Returns a randomly generated MAC address using the given Random object and the same * OUI values as the given MacAddress. * * The locally assigned bit is always set to 1. The multicast bit is always set to 0. * * @param base a base MacAddress whose OUI is used for generating the random address. * If base == null then the OUI will also be randomized. * @param r a standard Java Random object used for generating the random address. * @return a random locally assigned MacAddress. * * @hide */ public static @NonNull MacAddress createRandomUnicastAddress(MacAddress base, Random r) { long addr; if (base == null) { addr = r.nextLong() & VALID_LONG_MASK; } else { addr = (base.mAddr & OUI_MASK) | (NIC_MASK & r.nextLong()); } addr |= LOCALLY_ASSIGNED_MASK; addr &= ~MULTICAST_MASK; MacAddress mac = new MacAddress(addr); if (mac.equals(DEFAULT_MAC_ADDRESS)) { return createRandomUnicastAddress(base, r); } return mac; } // Convenience function for working around the lack of byte literals. Loading core/java/android/net/NetworkUtils.java +10 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.util.Pair; import java.io.FileDescriptor; import java.math.BigInteger; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; Loading Loading @@ -311,6 +312,15 @@ public class NetworkUtils { return new Pair<InetAddress, Integer>(address, prefixLength); } /** * Check if IP address type is consistent between two InetAddress. * @return true if both are the same type. False otherwise. */ public static boolean addressTypeMatches(InetAddress left, InetAddress right) { return (((left instanceof Inet4Address) && (right instanceof Inet4Address)) || ((left instanceof Inet6Address) && (right instanceof Inet6Address))); } /** * Convert a 32 char hex string into a Inet6Address. * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be Loading core/java/android/net/RouteInfo.java +15 −2 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.net.util.NetUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -484,7 +483,21 @@ public final class RouteInfo implements Parcelable { @UnsupportedAppUsage @Nullable public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) { return NetUtils.selectBestRoute(routes, dest); if ((routes == null) || (dest == null)) return null; RouteInfo bestRoute = null; // pick a longest prefix match under same address type for (RouteInfo route : routes) { if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) { if ((bestRoute != null) && (bestRoute.mDestination.getPrefixLength() >= route.mDestination.getPrefixLength())) { continue; } if (route.matches(dest)) bestRoute = route; } } return bestRoute; } /** Loading services/core/java/com/android/server/ConnectivityService.java +1 −1 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ import android.net.InetAddresses; import android.net.IpMemoryStore; import android.net.IpPrefix; import android.net.LinkProperties; import android.net.LinkProperties.CompareResult; import android.net.MatchAllNetworkSpecifier; import android.net.NattSocketKeepalive; import android.net.Network; Loading Loading @@ -122,7 +123,6 @@ import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; import android.net.netlink.InetDiagMessage; import android.net.shared.PrivateDnsConfig; import android.net.util.LinkPropertiesUtils.CompareResult; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; import android.os.Binder; Loading Loading
core/java/android/net/LinkProperties.java +69 −7 Original line number Diff line number Diff line Loading @@ -21,8 +21,6 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.net.util.LinkPropertiesUtils; import android.net.util.LinkPropertiesUtils.CompareResult; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -92,6 +90,36 @@ public final class LinkProperties implements Parcelable { // Indexed by interface name to allow modification and to prevent duplicates being added. private Hashtable<String, LinkProperties> mStackedLinks = new Hashtable<>(); /** * @hide */ public static class CompareResult<T> { public final List<T> removed = new ArrayList<>(); public final List<T> added = new ArrayList<>(); public CompareResult() {} public CompareResult(Collection<T> oldItems, Collection<T> newItems) { if (oldItems != null) { removed.addAll(oldItems); } if (newItems != null) { for (T newItem : newItems) { if (!removed.remove(newItem)) { added.add(newItem); } } } } @Override public String toString() { return "removed=[" + TextUtils.join(",", removed) + "] added=[" + TextUtils.join(",", added) + "]"; } } /** * @hide */ Loading Loading @@ -1298,7 +1326,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalInterfaceName(@NonNull LinkProperties target) { return LinkPropertiesUtils.isIdenticalInterfaceName(target, this); return TextUtils.equals(getInterfaceName(), target.getInterfaceName()); } /** Loading @@ -1321,7 +1349,10 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalAddresses(@NonNull LinkProperties target) { return LinkPropertiesUtils.isIdenticalAddresses(target, this); Collection<InetAddress> targetAddresses = target.getAddresses(); Collection<InetAddress> sourceAddresses = getAddresses(); return (sourceAddresses.size() == targetAddresses.size()) ? sourceAddresses.containsAll(targetAddresses) : false; } /** Loading @@ -1333,7 +1364,15 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalDnses(@NonNull LinkProperties target) { return LinkPropertiesUtils.isIdenticalDnses(target, this); Collection<InetAddress> targetDnses = target.getDnsServers(); String targetDomains = target.getDomains(); if (mDomains == null) { if (targetDomains != null) return false; } else { if (!mDomains.equals(targetDomains)) return false; } return (mDnses.size() == targetDnses.size()) ? mDnses.containsAll(targetDnses) : false; } /** Loading Loading @@ -1386,7 +1425,9 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalRoutes(@NonNull LinkProperties target) { return LinkPropertiesUtils.isIdenticalRoutes(target, this); Collection<RouteInfo> targetRoutes = target.getRoutes(); return (mRoutes.size() == targetRoutes.size()) ? mRoutes.containsAll(targetRoutes) : false; } /** Loading @@ -1398,7 +1439,8 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public boolean isIdenticalHttpProxy(@NonNull LinkProperties target) { return LinkPropertiesUtils.isIdenticalHttpProxy(target, this); return getHttpProxy() == null ? target.getHttpProxy() == null : getHttpProxy().equals(target.getHttpProxy()); } /** Loading Loading @@ -1620,6 +1662,26 @@ public final class LinkProperties implements Parcelable { && isIdenticalCaptivePortalData(target); } /** * Compares the addresses in this LinkProperties with another * LinkProperties, examining only addresses on the base link. * * @param target a LinkProperties with the new list of addresses * @return the differences between the addresses. * @hide */ public @NonNull CompareResult<LinkAddress> compareAddresses(@Nullable LinkProperties target) { /* * Duplicate the LinkAddresses into removed, we will be removing * address which are common between mLinkAddresses and target * leaving the addresses that are different. And address which * are in target but not in mLinkAddresses are placed in the * addedAddresses. */ return new CompareResult<>(mLinkAddresses, target != null ? target.getLinkAddresses() : null); } /** * Compares the DNS addresses in this LinkProperties with another * LinkProperties, examining only DNS addresses on the base link. Loading
core/java/android/net/MacAddress.java +73 −6 Original line number Diff line number Diff line Loading @@ -20,11 +20,11 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.net.util.MacAddressUtils; import android.net.wifi.WifiInfo; import android.os.Parcel; import android.os.Parcelable; import com.android.internal.util.BitUtils; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; Loading @@ -33,6 +33,7 @@ import java.net.Inet6Address; import java.net.UnknownHostException; import java.security.SecureRandom; import java.util.Arrays; import java.util.Random; /** * Representation of a MAC address. Loading Loading @@ -108,12 +109,20 @@ public final class MacAddress implements Parcelable { if (equals(BROADCAST_ADDRESS)) { return TYPE_BROADCAST; } if ((mAddr & MULTICAST_MASK) != 0) { if (isMulticastAddress()) { return TYPE_MULTICAST; } return TYPE_UNICAST; } /** * @return true if this MacAddress is a multicast address. * @hide */ public boolean isMulticastAddress() { return (mAddr & MULTICAST_MASK) != 0; } /** * @return true if this MacAddress is a locally assigned address. */ Loading Loading @@ -183,7 +192,7 @@ public final class MacAddress implements Parcelable { * @hide */ public static boolean isMacAddress(byte[] addr) { return MacAddressUtils.isMacAddress(addr); return addr != null && addr.length == ETHER_ADDR_LEN; } /** Loading Loading @@ -252,11 +261,26 @@ public final class MacAddress implements Parcelable { } private static byte[] byteAddrFromLongAddr(long addr) { return MacAddressUtils.byteAddrFromLongAddr(addr); byte[] bytes = new byte[ETHER_ADDR_LEN]; int index = ETHER_ADDR_LEN; while (index-- > 0) { bytes[index] = (byte) addr; addr = addr >> 8; } return bytes; } private static long longAddrFromByteAddr(byte[] addr) { return MacAddressUtils.longAddrFromByteAddr(addr); Preconditions.checkNotNull(addr); if (!isMacAddress(addr)) { throw new IllegalArgumentException( Arrays.toString(addr) + " was not a valid MAC address"); } long longAddr = 0; for (byte b : addr) { longAddr = (longAddr << 8) + BitUtils.uint8(b); } return longAddr; } // Internal conversion function equivalent to longAddrFromByteAddr(byteAddrFromStringAddr(addr)) Loading Loading @@ -326,7 +350,50 @@ public final class MacAddress implements Parcelable { * @hide */ public static @NonNull MacAddress createRandomUnicastAddressWithGoogleBase() { return MacAddressUtils.createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom()); return createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom()); } /** * Returns a generated MAC address whose 46 bits, excluding the locally assigned bit and the * unicast bit, are randomly selected. * * The locally assigned bit is always set to 1. The multicast bit is always set to 0. * * @return a random locally assigned, unicast MacAddress. * * @hide */ public static @NonNull MacAddress createRandomUnicastAddress() { return createRandomUnicastAddress(null, new SecureRandom()); } /** * Returns a randomly generated MAC address using the given Random object and the same * OUI values as the given MacAddress. * * The locally assigned bit is always set to 1. The multicast bit is always set to 0. * * @param base a base MacAddress whose OUI is used for generating the random address. * If base == null then the OUI will also be randomized. * @param r a standard Java Random object used for generating the random address. * @return a random locally assigned MacAddress. * * @hide */ public static @NonNull MacAddress createRandomUnicastAddress(MacAddress base, Random r) { long addr; if (base == null) { addr = r.nextLong() & VALID_LONG_MASK; } else { addr = (base.mAddr & OUI_MASK) | (NIC_MASK & r.nextLong()); } addr |= LOCALLY_ASSIGNED_MASK; addr &= ~MULTICAST_MASK; MacAddress mac = new MacAddress(addr); if (mac.equals(DEFAULT_MAC_ADDRESS)) { return createRandomUnicastAddress(base, r); } return mac; } // Convenience function for working around the lack of byte literals. Loading
core/java/android/net/NetworkUtils.java +10 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.util.Pair; import java.io.FileDescriptor; import java.math.BigInteger; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; Loading Loading @@ -311,6 +312,15 @@ public class NetworkUtils { return new Pair<InetAddress, Integer>(address, prefixLength); } /** * Check if IP address type is consistent between two InetAddress. * @return true if both are the same type. False otherwise. */ public static boolean addressTypeMatches(InetAddress left, InetAddress right) { return (((left instanceof Inet4Address) && (right instanceof Inet4Address)) || ((left instanceof Inet6Address) && (right instanceof Inet6Address))); } /** * Convert a 32 char hex string into a Inet6Address. * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be Loading
core/java/android/net/RouteInfo.java +15 −2 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.net.util.NetUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -484,7 +483,21 @@ public final class RouteInfo implements Parcelable { @UnsupportedAppUsage @Nullable public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) { return NetUtils.selectBestRoute(routes, dest); if ((routes == null) || (dest == null)) return null; RouteInfo bestRoute = null; // pick a longest prefix match under same address type for (RouteInfo route : routes) { if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) { if ((bestRoute != null) && (bestRoute.mDestination.getPrefixLength() >= route.mDestination.getPrefixLength())) { continue; } if (route.matches(dest)) bestRoute = route; } } return bestRoute; } /** Loading
services/core/java/com/android/server/ConnectivityService.java +1 −1 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ import android.net.InetAddresses; import android.net.IpMemoryStore; import android.net.IpPrefix; import android.net.LinkProperties; import android.net.LinkProperties.CompareResult; import android.net.MatchAllNetworkSpecifier; import android.net.NattSocketKeepalive; import android.net.Network; Loading Loading @@ -122,7 +123,6 @@ import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; import android.net.netlink.InetDiagMessage; import android.net.shared.PrivateDnsConfig; import android.net.util.LinkPropertiesUtils.CompareResult; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; import android.os.Binder; Loading