am 1b3c16a0: am d0d59156: am ce24ce4e: am 5570a0d0: am bb17a717: Merge changes I3ebf0cec,I8635472c into lmp-dev
* commit '1b3c16a06a43e98de8341535003b4d8fba2ba08a': Add a throw route to the VPN endpoint. Support non-unicast route types: unreachable and throw.
This commit is contained in:
@@ -172,7 +172,7 @@ public final class IpPrefix implements Parcelable {
|
||||
/**
|
||||
* Returns a string representation of this {@code IpPrefix}.
|
||||
*
|
||||
* @return a string such as {@code "192.0.2.0/24"} or {@code "2001:db8:1:2::"}.
|
||||
* @return a string such as {@code "192.0.2.0/24"} or {@code "2001:db8:1:2::/64"}.
|
||||
*/
|
||||
public String toString() {
|
||||
try {
|
||||
|
||||
@@ -381,7 +381,8 @@ public final class LinkProperties implements Parcelable {
|
||||
return new RouteInfo(
|
||||
route.getDestination(),
|
||||
route.getGateway(),
|
||||
mIfaceName);
|
||||
mIfaceName,
|
||||
route.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -62,6 +62,23 @@ public final class RouteInfo implements Parcelable {
|
||||
*/
|
||||
private final String mInterface;
|
||||
|
||||
|
||||
/** Unicast route. @hide */
|
||||
public static final int RTN_UNICAST = 1;
|
||||
|
||||
/** Unreachable route. @hide */
|
||||
public static final int RTN_UNREACHABLE = 7;
|
||||
|
||||
/** Throw route. @hide */
|
||||
public static final int RTN_THROW = 9;
|
||||
|
||||
/**
|
||||
* The type of this route; one of the RTN_xxx constants above.
|
||||
*/
|
||||
private final int mType;
|
||||
|
||||
// Derived data members.
|
||||
// TODO: remove these.
|
||||
private final boolean mIsHost;
|
||||
private final boolean mHasGateway;
|
||||
|
||||
@@ -82,7 +99,26 @@ public final class RouteInfo implements Parcelable {
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) {
|
||||
public RouteInfo(IpPrefix destination, InetAddress gateway, String iface, int type) {
|
||||
switch (type) {
|
||||
case RTN_UNICAST:
|
||||
case RTN_UNREACHABLE:
|
||||
case RTN_THROW:
|
||||
// TODO: It would be nice to ensure that route types that don't have nexthops or
|
||||
// interfaces, such as unreachable or throw, can't be created if an interface or
|
||||
// a gateway is specified. This is a bit too complicated to do at the moment
|
||||
// because:
|
||||
//
|
||||
// - LinkProperties sets the interface on routes added to it, and modifies the
|
||||
// interfaces of all the routes when its interface name changes.
|
||||
// - Even when the gateway is null, we store a non-null gateway here.
|
||||
//
|
||||
// For now, we just rely on the code that sets routes to do things properly.
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown route type " + type);
|
||||
}
|
||||
|
||||
if (destination == null) {
|
||||
if (gateway != null) {
|
||||
if (gateway instanceof Inet4Address) {
|
||||
@@ -117,9 +153,17 @@ public final class RouteInfo implements Parcelable {
|
||||
mDestination = destination; // IpPrefix objects are immutable.
|
||||
mGateway = gateway; // InetAddress objects are immutable.
|
||||
mInterface = iface; // Strings are immutable.
|
||||
mType = type;
|
||||
mIsHost = isHost();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) {
|
||||
this(destination, gateway, iface, RTN_UNICAST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -150,6 +194,8 @@ public final class RouteInfo implements Parcelable {
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*
|
||||
* TODO: Remove this.
|
||||
*/
|
||||
public RouteInfo(LinkAddress destination, InetAddress gateway) {
|
||||
this(destination, gateway, null);
|
||||
@@ -185,6 +231,13 @@ public final class RouteInfo implements Parcelable {
|
||||
this(destination, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(IpPrefix destination, int type) {
|
||||
this(destination, null, null, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -248,13 +301,24 @@ public final class RouteInfo implements Parcelable {
|
||||
return mInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the type of this route.
|
||||
*
|
||||
* @return The type of this route; one of the {@code RTN_xxx} constants defined in this class.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this route is a default route (ie, has no destination specified).
|
||||
*
|
||||
* @return {@code true} if the destination has a prefix length of 0.
|
||||
*/
|
||||
public boolean isDefaultRoute() {
|
||||
return mDestination.getPrefixLength() == 0;
|
||||
return mType == RTN_UNICAST && mDestination.getPrefixLength() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,9 +409,18 @@ public final class RouteInfo implements Parcelable {
|
||||
public String toString() {
|
||||
String val = "";
|
||||
if (mDestination != null) val = mDestination.toString();
|
||||
val += " ->";
|
||||
if (mGateway != null) val += " " + mGateway.getHostAddress();
|
||||
if (mInterface != null) val += " " + mInterface;
|
||||
if (mType == RTN_UNREACHABLE) {
|
||||
val += " unreachable";
|
||||
} else if (mType == RTN_THROW) {
|
||||
val += " throw";
|
||||
} else {
|
||||
val += " ->";
|
||||
if (mGateway != null) val += " " + mGateway.getHostAddress();
|
||||
if (mInterface != null) val += " " + mInterface;
|
||||
if (mType != RTN_UNICAST) {
|
||||
val += " unknown type " + mType;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -364,7 +437,8 @@ public final class RouteInfo implements Parcelable {
|
||||
|
||||
return Objects.equals(mDestination, target.getDestination()) &&
|
||||
Objects.equals(mGateway, target.getGateway()) &&
|
||||
Objects.equals(mInterface, target.getInterface());
|
||||
Objects.equals(mInterface, target.getInterface()) &&
|
||||
mType == target.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,7 +447,8 @@ public final class RouteInfo implements Parcelable {
|
||||
public int hashCode() {
|
||||
return (mDestination.hashCode() * 41)
|
||||
+ (mGateway == null ? 0 :mGateway.hashCode() * 47)
|
||||
+ (mInterface == null ? 0 :mInterface.hashCode() * 67);
|
||||
+ (mInterface == null ? 0 :mInterface.hashCode() * 67)
|
||||
+ (mType * 71);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -391,6 +466,7 @@ public final class RouteInfo implements Parcelable {
|
||||
byte[] gatewayBytes = (mGateway == null) ? null : mGateway.getAddress();
|
||||
dest.writeByteArray(gatewayBytes);
|
||||
dest.writeString(mInterface);
|
||||
dest.writeInt(mType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -408,8 +484,9 @@ public final class RouteInfo implements Parcelable {
|
||||
} catch (UnknownHostException e) {}
|
||||
|
||||
String iface = in.readString();
|
||||
int type = in.readInt();
|
||||
|
||||
return new RouteInfo(dest, gateway, iface);
|
||||
return new RouteInfo(dest, gateway, iface, type);
|
||||
}
|
||||
|
||||
public RouteInfo[] newArray(int size) {
|
||||
|
||||
@@ -25,6 +25,9 @@ import static android.net.NetworkStats.TAG_ALL;
|
||||
import static android.net.NetworkStats.TAG_NONE;
|
||||
import static android.net.NetworkStats.UID_ALL;
|
||||
import static android.net.TrafficStats.UID_TETHERING;
|
||||
import static android.net.RouteInfo.RTN_THROW;
|
||||
import static android.net.RouteInfo.RTN_UNICAST;
|
||||
import static android.net.RouteInfo.RTN_UNREACHABLE;
|
||||
import static android.system.OsConstants.AF_INET;
|
||||
import static android.system.OsConstants.AF_INET6;
|
||||
import static com.android.server.NetworkManagementService.NetdResponseCode.ClatdStatusResult;
|
||||
@@ -955,11 +958,21 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
final Command cmd = new Command("network", "route", action, netId);
|
||||
|
||||
// create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
|
||||
final LinkAddress la = route.getDestinationLinkAddress();
|
||||
cmd.appendArg(route.getInterface());
|
||||
cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getPrefixLength());
|
||||
if (route.hasGateway()) {
|
||||
cmd.appendArg(route.getGateway().getHostAddress());
|
||||
cmd.appendArg(route.getDestination().toString());
|
||||
|
||||
switch (route.getType()) {
|
||||
case RouteInfo.RTN_UNICAST:
|
||||
if (route.hasGateway()) {
|
||||
cmd.appendArg(route.getGateway().getHostAddress());
|
||||
}
|
||||
break;
|
||||
case RouteInfo.RTN_UNREACHABLE:
|
||||
cmd.appendArg("unreachable");
|
||||
break;
|
||||
case RouteInfo.RTN_THROW:
|
||||
cmd.appendArg("throw");
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -2129,6 +2142,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
modifyAddressFamily("remove", family, netId, iface);
|
||||
}
|
||||
|
||||
// TODO: get rid of this and add RTN_UNREACHABLE routes instead.
|
||||
private void modifyAddressFamily(String action, int family, int netId, String iface) {
|
||||
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.connectivity;
|
||||
|
||||
import static android.Manifest.permission.BIND_VPN_SERVICE;
|
||||
import static android.os.UserHandle.PER_USER_RANGE;
|
||||
import static android.net.RouteInfo.RTN_THROW;
|
||||
import static android.system.OsConstants.AF_INET;
|
||||
import static android.system.OsConstants.AF_INET6;
|
||||
|
||||
@@ -38,6 +39,7 @@ import android.content.pm.UserInfo;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.IConnectivityManager;
|
||||
import android.net.INetworkManagementEventObserver;
|
||||
import android.net.IpPrefix;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.LocalSocket;
|
||||
@@ -1220,7 +1222,7 @@ public class Vpn {
|
||||
|
||||
// Now we are connected. Read and parse the new state.
|
||||
String[] parameters = FileUtils.readTextFile(state, 0, null).split("\n", -1);
|
||||
if (parameters.length != 6) {
|
||||
if (parameters.length != 7) {
|
||||
throw new IllegalStateException("Cannot parse the state");
|
||||
}
|
||||
|
||||
@@ -1249,6 +1251,23 @@ public class Vpn {
|
||||
}
|
||||
}
|
||||
|
||||
// Add a throw route for the VPN server endpoint, if one was specified.
|
||||
String endpoint = parameters[5];
|
||||
if (!endpoint.isEmpty()) {
|
||||
try {
|
||||
InetAddress addr = InetAddress.parseNumericAddress(endpoint);
|
||||
if (addr instanceof Inet4Address) {
|
||||
mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 32), RTN_THROW));
|
||||
} else if (addr instanceof Inet6Address) {
|
||||
mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 128), RTN_THROW));
|
||||
} else {
|
||||
Log.e(TAG, "Unknown IP address family for VPN endpoint: " + endpoint);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(TAG, "Exception constructing throw route to " + endpoint + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
// Here is the last step and it must be done synchronously.
|
||||
synchronized (Vpn.this) {
|
||||
// Set the start time
|
||||
|
||||
Reference in New Issue
Block a user