diff options
author | paulhu <paulhu@google.com> | 2021-03-03 22:15:11 +0800 |
---|---|---|
committer | paulhu <paulhu@google.com> | 2021-03-12 19:57:40 +0800 |
commit | 033521c57b04ba5fc93193185b4cfa4ef7525af6 (patch) | |
tree | 508e111985d17da7d44466f8eae84bf83e40d467 | |
parent | c77293b7a92590e5583b9af0e4a6128d841f8c6f (diff) |
Replace InetAddress#parseNumericAddress
-Connectivity is becoming a mainline module in S but mainline
modules are not allowed to use non-formal APIs. Thus, replace
non-formal API InetAddress#parseNumericAddress to
InetAddresses#parseNumericAddress.
- Add deprecated method legacyParseIpAndMask() for IpPrefix and
LinkAddress. Because InetAddresses#parseNumericAddress has
a little different behavior in some case, but these two classes
should keep working as before. So these two classes will use
the new deprecated method.
Bug: 181756157
Test: FrameworksNetTests
Change-Id: I1c96b75f0b8d5e93304a39b4a8c8849964e5e810
5 files changed, 71 insertions, 4 deletions
diff --git a/packages/Connectivity/framework/src/android/net/IpPrefix.java b/packages/Connectivity/framework/src/android/net/IpPrefix.java index d2ee7d13b05f..bf4481afc53d 100644 --- a/packages/Connectivity/framework/src/android/net/IpPrefix.java +++ b/packages/Connectivity/framework/src/android/net/IpPrefix.java @@ -113,7 +113,7 @@ public final class IpPrefix implements Parcelable { // first statement in constructor". We could factor out setting the member variables to an // init() method, but if we did, then we'd have to make the members non-final, or "error: // cannot assign a value to final variable address". So we just duplicate the code here. - Pair<InetAddress, Integer> ipAndMask = NetworkUtils.parseIpAndMask(prefix); + Pair<InetAddress, Integer> ipAndMask = NetworkUtils.legacyParseIpAndMask(prefix); this.address = ipAndMask.first.getAddress(); this.prefixLength = ipAndMask.second; checkAndMaskAddressAndPrefixLength(); diff --git a/packages/Connectivity/framework/src/android/net/LinkAddress.java b/packages/Connectivity/framework/src/android/net/LinkAddress.java index d1bdaa078cdc..d48b8c71f495 100644 --- a/packages/Connectivity/framework/src/android/net/LinkAddress.java +++ b/packages/Connectivity/framework/src/android/net/LinkAddress.java @@ -325,7 +325,7 @@ public class LinkAddress implements Parcelable { public LinkAddress(@NonNull String address, int flags, int scope) { // This may throw an IllegalArgumentException; catching it is the caller's responsibility. // TODO: consider rejecting mapped IPv4 addresses such as "::ffff:192.0.2.5/24". - Pair<InetAddress, Integer> ipAndMask = NetworkUtils.parseIpAndMask(address); + Pair<InetAddress, Integer> ipAndMask = NetworkUtils.legacyParseIpAndMask(address); init(ipAndMask.first, ipAndMask.second, flags, scope, LIFETIME_UNKNOWN, LIFETIME_UNKNOWN); } diff --git a/packages/Connectivity/framework/src/android/net/NetworkUtils.java b/packages/Connectivity/framework/src/android/net/NetworkUtils.java index 9e42bbecbe9d..c0f262815b0c 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkUtils.java +++ b/packages/Connectivity/framework/src/android/net/NetworkUtils.java @@ -27,8 +27,10 @@ import com.android.net.module.util.Inet4AddressUtils; 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; import java.util.Locale; import java.util.TreeSet; @@ -212,7 +214,7 @@ public class NetworkUtils { @Deprecated public static InetAddress numericToInetAddress(String addrString) throws IllegalArgumentException { - return InetAddress.parseNumericAddress(addrString); + return InetAddresses.parseNumericAddress(addrString); } /** @@ -234,7 +236,7 @@ public class NetworkUtils { try { String[] pieces = ipAndMaskString.split("/", 2); prefixLength = Integer.parseInt(pieces[1]); - address = InetAddress.parseNumericAddress(pieces[0]); + address = InetAddresses.parseNumericAddress(pieces[0]); } catch (NullPointerException e) { // Null string. } catch (ArrayIndexOutOfBoundsException e) { // No prefix length. } catch (NumberFormatException e) { // Non-numeric prefix. @@ -249,6 +251,47 @@ public class NetworkUtils { } /** + * Utility method to parse strings such as "192.0.2.5/24" or "2001:db8::cafe:d00d/64". + * @hide + * + * @deprecated This method is used only for IpPrefix and LinkAddress. Since Android S, use + * {@link #parseIpAndMask(String)}, if possible. + */ + @Deprecated + public static Pair<InetAddress, Integer> legacyParseIpAndMask(String ipAndMaskString) { + InetAddress address = null; + int prefixLength = -1; + try { + String[] pieces = ipAndMaskString.split("/", 2); + prefixLength = Integer.parseInt(pieces[1]); + if (pieces[0] == null || pieces[0].isEmpty()) { + final byte[] bytes = new byte[16]; + bytes[15] = 1; + return new Pair<InetAddress, Integer>(Inet6Address.getByAddress( + "ip6-localhost"/* host */, bytes, 0 /* scope_id */), prefixLength); + } + + if (pieces[0].startsWith("[") + && pieces[0].endsWith("]") + && pieces[0].indexOf(':') != -1) { + pieces[0] = pieces[0].substring(1, pieces[0].length() - 1); + } + address = InetAddresses.parseNumericAddress(pieces[0]); + } catch (NullPointerException e) { // Null string. + } catch (ArrayIndexOutOfBoundsException e) { // No prefix length. + } catch (NumberFormatException e) { // Non-numeric prefix. + } catch (IllegalArgumentException e) { // Invalid IP address. + } catch (UnknownHostException e) { // IP address length is illegal + } + + if (address == null || prefixLength == -1) { + throw new IllegalArgumentException("Invalid IP address and mask " + ipAndMaskString); + } + + return new Pair<InetAddress, Integer>(address, prefixLength); + } + + /** * 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 * made into an Inet6Address diff --git a/tests/net/common/java/android/net/IpPrefixTest.java b/tests/net/common/java/android/net/IpPrefixTest.java index 9c0fc7ce7881..50ecb428359e 100644 --- a/tests/net/common/java/android/net/IpPrefixTest.java +++ b/tests/net/common/java/android/net/IpPrefixTest.java @@ -113,6 +113,15 @@ public class IpPrefixTest { p = new IpPrefix("f00:::/32"); fail("Expected IllegalArgumentException: invalid IPv6 address"); } catch (IllegalArgumentException expected) { } + + p = new IpPrefix("/64"); + assertEquals("::/64", p.toString()); + + p = new IpPrefix("/128"); + assertEquals("::1/128", p.toString()); + + p = new IpPrefix("[2001:db8::123]/64"); + assertEquals("2001:db8::/64", p.toString()); } @Test diff --git a/tests/net/common/java/android/net/LinkAddressTest.java b/tests/net/common/java/android/net/LinkAddressTest.java index 1eaf30c5e068..2cf3cf9c11da 100644 --- a/tests/net/common/java/android/net/LinkAddressTest.java +++ b/tests/net/common/java/android/net/LinkAddressTest.java @@ -53,6 +53,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; @@ -117,6 +118,20 @@ public class LinkAddressTest { assertEquals(456, address.getScope()); assertTrue(address.isIpv4()); + address = new LinkAddress("/64", 1 /* flags */, 2 /* scope */); + assertEquals(Inet6Address.LOOPBACK, address.getAddress()); + assertEquals(64, address.getPrefixLength()); + assertEquals(1, address.getFlags()); + assertEquals(2, address.getScope()); + assertTrue(address.isIpv6()); + + address = new LinkAddress("[2001:db8::123]/64", 3 /* flags */, 4 /* scope */); + assertEquals(InetAddresses.parseNumericAddress("2001:db8::123"), address.getAddress()); + assertEquals(64, address.getPrefixLength()); + assertEquals(3, address.getFlags()); + assertEquals(4, address.getScope()); + assertTrue(address.isIpv6()); + // InterfaceAddress doesn't have a constructor. Fetch some from an interface. List<InterfaceAddress> addrs = NetworkInterface.getByName("lo").getInterfaceAddresses(); |