Update RouteInfo docs and make public.

Change-Id: I1a8fe04022ea8291076af166f09112d19114ee16
This commit is contained in:
Robert Greenwalt
2014-05-18 12:05:05 -07:00
parent 7d8949fc2d
commit 1aacd72db2

View File

@@ -28,19 +28,18 @@ import java.util.Collection;
/** /**
* A simple container for route information. * A simple container for route information.
* <p>
* This is used both to describe static network configuration and live network
* configuration information. In the static case the interface name (retrieved
* via {@link #getInterface}) should be {@code null} as that information will not
* yet be known.
* *
* In order to be used, a route must have a destination prefix and: * A route may be configured with:
* * <ul>
* - A gateway address (next-hop, for gatewayed routes), or * <li>a destination {@link LinkAddress} for directly-connected subnets,
* - An interface (for directly-connected routes), or * <li>a gateway {@link InetAddress} for default routes,
* - Both a gateway and an interface. * <li>or both for a subnet.
* * </ul>
* This class does not enforce these constraints because there is code that
* uses RouteInfo objects to store directly-connected routes without interfaces.
* Such objects cannot be used directly, but can be put into a LinkProperties
* object which then specifies the interface.
*
* @hide
*/ */
public class RouteInfo implements Parcelable { public class RouteInfo implements Parcelable {
/** /**
@@ -67,7 +66,7 @@ public class RouteInfo implements Parcelable {
* *
* If destination is null, then gateway must be specified and the * If destination is null, then gateway must be specified and the
* constructed route is either the IPv4 default route <code>0.0.0.0</code> * constructed route is either the IPv4 default route <code>0.0.0.0</code>
* if @gateway is an instance of {@link Inet4Address}, or the IPv6 default * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
* route <code>::/0</code> if gateway is an instance of * route <code>::/0</code> if gateway is an instance of
* {@link Inet6Address}. * {@link Inet6Address}.
* *
@@ -76,6 +75,8 @@ public class RouteInfo implements Parcelable {
* @param destination the destination prefix * @param destination the destination prefix
* @param gateway the IP address to route packets through * @param gateway the IP address to route packets through
* @param iface the interface name to send packets on * @param iface the interface name to send packets on
*
* @hide
*/ */
public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) { public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
if (destination == null) { if (destination == null) {
@@ -108,22 +109,51 @@ public class RouteInfo implements Parcelable {
mIsHost = isHost(); mIsHost = isHost();
} }
/**
* Constructs a {@code RouteInfo} object.
*
* If destination is null, then gateway must be specified and the
* constructed route is either the IPv4 default route <code>0.0.0.0</code>
* if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
* route <code>::/0</code> if gateway is an instance of {@link Inet6Address}.
* <p>
* Destination and gateway may not both be null.
*
* @param destination the destination address and prefix in a {@link LinkAddress}
* @param gateway the {@link InetAddress} to route packets through
*/
public RouteInfo(LinkAddress destination, InetAddress gateway) { public RouteInfo(LinkAddress destination, InetAddress gateway) {
this(destination, gateway, null); this(destination, gateway, null);
} }
/**
* Constructs a default {@code RouteInfo} object.
*
* @param gateway the {@link InetAddress} to route packets through
*/
public RouteInfo(InetAddress gateway) { public RouteInfo(InetAddress gateway) {
this(null, gateway, null); this(null, gateway, null);
} }
/**
* Constructs a {@code RouteInfo} object representing a direct connected subnet.
*
* @param host the {@link LinkAddress} describing the address and prefix length of the subnet.
*/
public RouteInfo(LinkAddress host) { public RouteInfo(LinkAddress host) {
this(host, null, null); this(host, null, null);
} }
/**
* @hide
*/
public static RouteInfo makeHostRoute(InetAddress host, String iface) { public static RouteInfo makeHostRoute(InetAddress host, String iface) {
return makeHostRoute(host, null, iface); return makeHostRoute(host, null, iface);
} }
/**
* @hide
*/
public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway, String iface) { public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway, String iface) {
if (host == null) return null; if (host == null) return null;
@@ -153,31 +183,102 @@ public class RouteInfo implements Parcelable {
return val; return val;
} }
/**
* Retrieves the destination address and prefix length in the form of a {@link LinkAddress}.
*
* @return {@link LinkAddress} specifying the destination.
*/
public LinkAddress getDestination() { public LinkAddress getDestination() {
return mDestination; return mDestination;
} }
/**
* Retrieves the gateway or next hop {@link InetAddress} for this route.
*
* @return {@link InetAddress} specifying the gateway or next hop.
*/
public InetAddress getGateway() { public InetAddress getGateway() {
return mGateway; return mGateway;
} }
/**
* Retrieves the interface used for this route, if known. Note that for static
* network configurations, this won't be set.
*
* @return The name of the interface used for this route.
*/
public String getInterface() { public String getInterface() {
return mInterface; return mInterface;
} }
/**
* Indicates if this route is a default route (ie, has no destination specified).
*
* @return {@code true} if the destination is null or has a prefix length of 0.
*/
public boolean isDefaultRoute() { public boolean isDefaultRoute() {
return mIsDefault; return mIsDefault;
} }
/**
* Indicates if this route is a host route (ie, matches only a single host address).
*
* @return {@code true} if the destination has a prefix length of 32/128 for v4/v6.
*/
public boolean isHostRoute() { public boolean isHostRoute() {
return mIsHost; return mIsHost;
} }
/**
* Indicates if this route has a next hop ({@code true}) or is directly-connected
* ({@code false}).
*
* @return {@code true} if a gateway is specified
*/
public boolean hasGateway() { public boolean hasGateway() {
return mHasGateway; return mHasGateway;
} }
/**
* @hide
*/
protected boolean matches(InetAddress destination) {
if (destination == null) return false;
// match the route destination and destination with prefix length
InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
mDestination.getNetworkPrefixLength());
return mDestination.getAddress().equals(dstNet);
}
/**
* Find the route from a Collection of routes that best matches a given address.
* May return null if no routes are applicable.
* @param routes a Collection of RouteInfos to chose from
* @param dest the InetAddress your trying to get to
* @return the RouteInfo from the Collection that best fits the given address
*
* @hide
*/
public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress 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.getNetworkPrefixLength() >=
route.mDestination.getNetworkPrefixLength())) {
continue;
}
if (route.matches(dest)) bestRoute = route;
}
}
return bestRoute;
}
public String toString() { public String toString() {
String val = ""; String val = "";
if (mDestination != null) val = mDestination.toString(); if (mDestination != null) val = mDestination.toString();
@@ -185,30 +286,6 @@ public class RouteInfo implements Parcelable {
return val; return val;
} }
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
if (mDestination == null) {
dest.writeByte((byte) 0);
} else {
dest.writeByte((byte) 1);
dest.writeByteArray(mDestination.getAddress().getAddress());
dest.writeInt(mDestination.getNetworkPrefixLength());
}
if (mGateway == null) {
dest.writeByte((byte) 0);
} else {
dest.writeByte((byte) 1);
dest.writeByteArray(mGateway.getAddress());
}
dest.writeString(mInterface);
}
@Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) return true; if (this == obj) return true;
@@ -232,7 +309,6 @@ public class RouteInfo implements Parcelable {
&& mIsDefault == target.mIsDefault; && mIsDefault == target.mIsDefault;
} }
@Override
public int hashCode() { public int hashCode() {
return (mDestination == null ? 0 : mDestination.hashCode() * 41) return (mDestination == null ? 0 : mDestination.hashCode() * 41)
+ (mGateway == null ? 0 :mGateway.hashCode() * 47) + (mGateway == null ? 0 :mGateway.hashCode() * 47)
@@ -240,6 +316,41 @@ public class RouteInfo implements Parcelable {
+ (mIsDefault ? 3 : 7); + (mIsDefault ? 3 : 7);
} }
/**
* Implement the Parcelable interface
* @hide
*/
public int describeContents() {
return 0;
}
/**
* Implement the Parcelable interface
* @hide
*/
public void writeToParcel(Parcel dest, int flags) {
if (mDestination == null) {
dest.writeByte((byte) 0);
} else {
dest.writeByte((byte) 1);
dest.writeByteArray(mDestination.getAddress().getAddress());
dest.writeInt(mDestination.getNetworkPrefixLength());
}
if (mGateway == null) {
dest.writeByte((byte) 0);
} else {
dest.writeByte((byte) 1);
dest.writeByteArray(mGateway.getAddress());
}
dest.writeString(mInterface);
}
/**
* Implement the Parcelable interface.
* @hide
*/
public static final Creator<RouteInfo> CREATOR = public static final Creator<RouteInfo> CREATOR =
new Creator<RouteInfo>() { new Creator<RouteInfo>() {
public RouteInfo createFromParcel(Parcel in) { public RouteInfo createFromParcel(Parcel in) {
@@ -279,39 +390,4 @@ public class RouteInfo implements Parcelable {
return new RouteInfo[size]; return new RouteInfo[size];
} }
}; };
protected boolean matches(InetAddress destination) {
if (destination == null) return false;
// match the route destination and destination with prefix length
InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
mDestination.getNetworkPrefixLength());
return mDestination.getAddress().equals(dstNet);
}
/**
* Find the route from a Collection of routes that best matches a given address.
* May return null if no routes are applicable.
* @param routes a Collection of RouteInfos to chose from
* @param dest the InetAddress your trying to get to
* @return the RouteInfo from the Collection that best fits the given address
*/
public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress 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.getNetworkPrefixLength() >=
route.mDestination.getNetworkPrefixLength())) {
continue;
}
if (route.matches(dest)) bestRoute = route;
}
}
return bestRoute;
}
} }