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
This commit is contained in:
@@ -113,7 +113,7 @@ public final class IpPrefix implements Parcelable {
|
|||||||
// first statement in constructor". We could factor out setting the member variables to an
|
// 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:
|
// 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.
|
// 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.address = ipAndMask.first.getAddress();
|
||||||
this.prefixLength = ipAndMask.second;
|
this.prefixLength = ipAndMask.second;
|
||||||
checkAndMaskAddressAndPrefixLength();
|
checkAndMaskAddressAndPrefixLength();
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ public class LinkAddress implements Parcelable {
|
|||||||
public LinkAddress(@NonNull String address, int flags, int scope) {
|
public LinkAddress(@NonNull String address, int flags, int scope) {
|
||||||
// This may throw an IllegalArgumentException; catching it is the caller's responsibility.
|
// 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".
|
// 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);
|
init(ipAndMask.first, ipAndMask.second, flags, scope, LIFETIME_UNKNOWN, LIFETIME_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ import com.android.net.module.util.Inet4AddressUtils;
|
|||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
|
import java.net.Inet6Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
@@ -212,7 +214,7 @@ public class NetworkUtils {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static InetAddress numericToInetAddress(String addrString)
|
public static InetAddress numericToInetAddress(String addrString)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
return InetAddress.parseNumericAddress(addrString);
|
return InetAddresses.parseNumericAddress(addrString);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -234,7 +236,7 @@ public class NetworkUtils {
|
|||||||
try {
|
try {
|
||||||
String[] pieces = ipAndMaskString.split("/", 2);
|
String[] pieces = ipAndMaskString.split("/", 2);
|
||||||
prefixLength = Integer.parseInt(pieces[1]);
|
prefixLength = Integer.parseInt(pieces[1]);
|
||||||
address = InetAddress.parseNumericAddress(pieces[0]);
|
address = InetAddresses.parseNumericAddress(pieces[0]);
|
||||||
} catch (NullPointerException e) { // Null string.
|
} catch (NullPointerException e) { // Null string.
|
||||||
} catch (ArrayIndexOutOfBoundsException e) { // No prefix length.
|
} catch (ArrayIndexOutOfBoundsException e) { // No prefix length.
|
||||||
} catch (NumberFormatException e) { // Non-numeric prefix.
|
} catch (NumberFormatException e) { // Non-numeric prefix.
|
||||||
@@ -248,6 +250,47 @@ public class NetworkUtils {
|
|||||||
return new Pair<InetAddress, Integer>(address, prefixLength);
|
return new Pair<InetAddress, Integer>(address, prefixLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* 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
|
* throws a runtime exception if the string isn't 32 chars, isn't hex or can't be
|
||||||
|
|||||||
@@ -113,6 +113,15 @@ public class IpPrefixTest {
|
|||||||
p = new IpPrefix("f00:::/32");
|
p = new IpPrefix("f00:::/32");
|
||||||
fail("Expected IllegalArgumentException: invalid IPv6 address");
|
fail("Expected IllegalArgumentException: invalid IPv6 address");
|
||||||
} catch (IllegalArgumentException expected) { }
|
} 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
|
@Test
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
|
import java.net.Inet6Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InterfaceAddress;
|
import java.net.InterfaceAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
@@ -117,6 +118,20 @@ public class LinkAddressTest {
|
|||||||
assertEquals(456, address.getScope());
|
assertEquals(456, address.getScope());
|
||||||
assertTrue(address.isIpv4());
|
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.
|
// InterfaceAddress doesn't have a constructor. Fetch some from an interface.
|
||||||
List<InterfaceAddress> addrs = NetworkInterface.getByName("lo").getInterfaceAddresses();
|
List<InterfaceAddress> addrs = NetworkInterface.getByName("lo").getInterfaceAddresses();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user