diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index 129248c7e05e6..a4ec80c9a511a 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -49,9 +49,8 @@ import java.util.Objects; public final class RouteInfo implements Parcelable { /** * The IP destination address for this route. - * TODO: Make this an IpPrefix. */ - private final LinkAddress mDestination; + private final IpPrefix mDestination; /** * The gateway address for this route. @@ -81,26 +80,15 @@ public final class RouteInfo implements Parcelable { * @param gateway the IP address to route packets through * @param iface the interface name to send packets on * - * TODO: Convert to use IpPrefix. - * * @hide */ public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) { - this(destination == null ? null : - new LinkAddress(destination.getAddress(), destination.getPrefixLength()), - gateway, iface); - } - - /** - * @hide - */ - public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) { if (destination == null) { if (gateway != null) { if (gateway instanceof Inet4Address) { - destination = new LinkAddress(Inet4Address.ANY, 0); + destination = new IpPrefix(Inet4Address.ANY, 0); } else { - destination = new LinkAddress(Inet6Address.ANY, 0); + destination = new IpPrefix(Inet6Address.ANY, 0); } } else { // no destination, no gateway. invalid. @@ -108,6 +96,9 @@ public final class RouteInfo implements Parcelable { destination); } } + // TODO: set mGateway to null if there is no gateway. This is more correct, saves space, and + // matches the documented behaviour. Before we can do this we need to fix all callers (e.g., + // ConnectivityService) to stop doing things like r.getGateway().equals(), ... . if (gateway == null) { if (destination.getAddress() instanceof Inet4Address) { gateway = Inet4Address.ANY; @@ -117,19 +108,27 @@ public final class RouteInfo implements Parcelable { } mHasGateway = (!gateway.isAnyLocalAddress()); - mDestination = new LinkAddress(NetworkUtils.getNetworkPart(destination.getAddress(), - destination.getPrefixLength()), destination.getPrefixLength()); if ((destination.getAddress() instanceof Inet4Address && (gateway instanceof Inet4Address == false)) || (destination.getAddress() instanceof Inet6Address && (gateway instanceof Inet6Address == false))) { throw new IllegalArgumentException("address family mismatch in RouteInfo constructor"); } - mGateway = gateway; - mInterface = iface; + mDestination = destination; // IpPrefix objects are immutable. + mGateway = gateway; // InetAddress objects are immutable. + mInterface = iface; // Strings are immutable. mIsHost = isHost(); } + /** + * @hide + */ + public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) { + this(destination == null ? null : + new IpPrefix(destination.getAddress(), destination.getPrefixLength()), + gateway, iface); + } + /** * Constructs a {@code RouteInfo} object. * @@ -164,7 +163,7 @@ public final class RouteInfo implements Parcelable { * @hide */ public RouteInfo(InetAddress gateway) { - this((LinkAddress) null, gateway, null); + this((IpPrefix) null, gateway, null); } /** @@ -200,9 +199,9 @@ public final class RouteInfo implements Parcelable { if (host == null) return null; if (host instanceof Inet4Address) { - return new RouteInfo(new LinkAddress(host, 32), gateway, iface); + return new RouteInfo(new IpPrefix(host, 32), gateway, iface); } else { - return new RouteInfo(new LinkAddress(host, 128), gateway, iface); + return new RouteInfo(new IpPrefix(host, 128), gateway, iface); } } @@ -219,7 +218,7 @@ public final class RouteInfo implements Parcelable { * @return {@link IpPrefix} specifying the destination. This is never {@code null}. */ public IpPrefix getDestination() { - return new IpPrefix(mDestination.getAddress(), mDestination.getPrefixLength()); + return mDestination; } /** @@ -227,7 +226,7 @@ public final class RouteInfo implements Parcelable { * @hide */ public LinkAddress getDestinationLinkAddress() { - return mDestination; + return new LinkAddress(mDestination.getAddress(), mDestination.getPrefixLength()); } /** @@ -363,7 +362,7 @@ public final class RouteInfo implements Parcelable { RouteInfo target = (RouteInfo) obj; - return Objects.equals(mDestination, target.getDestinationLinkAddress()) && + return Objects.equals(mDestination, target.getDestination()) && Objects.equals(mGateway, target.getGateway()) && Objects.equals(mInterface, target.getInterface()); } @@ -388,16 +387,9 @@ public final class RouteInfo implements Parcelable { * Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { - dest.writeByteArray(mDestination.getAddress().getAddress()); - dest.writeInt(mDestination.getPrefixLength()); - - if (mGateway == null) { - dest.writeByte((byte) 0); - } else { - dest.writeByte((byte) 1); - dest.writeByteArray(mGateway.getAddress()); - } - + dest.writeParcelable(mDestination, flags); + byte[] gatewayBytes = (mGateway == null) ? null : mGateway.getAddress(); + dest.writeByteArray(gatewayBytes); dest.writeString(mInterface); } @@ -407,33 +399,16 @@ public final class RouteInfo implements Parcelable { public static final Creator CREATOR = new Creator() { public RouteInfo createFromParcel(Parcel in) { - InetAddress destAddr = null; - int prefix = 0; + IpPrefix dest = in.readParcelable(null); + InetAddress gateway = null; - byte[] addr = in.createByteArray(); - prefix = in.readInt(); - try { - destAddr = InetAddress.getByAddress(addr); + gateway = InetAddress.getByAddress(addr); } catch (UnknownHostException e) {} - if (in.readByte() == 1) { - addr = in.createByteArray(); - - try { - gateway = InetAddress.getByAddress(addr); - } catch (UnknownHostException e) {} - } - String iface = in.readString(); - LinkAddress dest = null; - - if (destAddr != null) { - dest = new LinkAddress(destAddr, prefix); - } - return new RouteInfo(dest, gateway, iface); } diff --git a/core/tests/coretests/src/android/net/RouteInfoTest.java b/core/tests/coretests/src/android/net/RouteInfoTest.java index dcacd11776ca4..0b88bc703d2c1 100644 --- a/core/tests/coretests/src/android/net/RouteInfoTest.java +++ b/core/tests/coretests/src/android/net/RouteInfoTest.java @@ -214,6 +214,29 @@ public class RouteInfoTest extends TestCase { assertFalse(r.isIPv6Default()); } + public void testTruncation() { + LinkAddress l; + RouteInfo r; + + l = new LinkAddress("192.0.2.5/30"); + r = new RouteInfo(l, Address("192.0.2.1"), "wlan0"); + assertEquals("192.0.2.4", r.getDestination().getAddress().getHostAddress()); + + l = new LinkAddress("2001:db8:1:f::5/63"); + r = new RouteInfo(l, Address("2001:db8:5::1"), "wlan0"); + assertEquals("2001:db8:1:e::", r.getDestination().getAddress().getHostAddress()); + } + + // Make sure that creating routes to multicast addresses doesn't throw an exception. Even though + // there's nothing we can do with them, we don't want to crash if, e.g., someone calls + // requestRouteToHostAddress("230.0.0.0", MOBILE_HIPRI); + public void testMulticastRoute() { + RouteInfo r; + r = new RouteInfo(Prefix("230.0.0.0/32"), Address("192.0.2.1"), "wlan0"); + r = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::1"), "wlan0"); + // No exceptions? Good. + } + public RouteInfo passThroughParcel(RouteInfo r) { Parcel p = Parcel.obtain(); RouteInfo r2 = null;