Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 633b7bb8 authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Android Git Automerger
Browse files

am bb17a717: Merge changes I3ebf0cec,I8635472c into lmp-dev

* commit 'bb17a717750c558ece69344ecd93d96d4fbc4aca':
  Add a throw route to the VPN endpoint.
  Support non-unicast route types: unreachable and throw.
parents eccd4ed7 1e2b63d9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 {
+2 −1
Original line number Diff line number Diff line
@@ -381,7 +381,8 @@ public final class LinkProperties implements Parcelable {
        return new RouteInfo(
            route.getDestination(),
            route.getGateway(),
            mIfaceName);
            mIfaceName,
            route.getType());
    }

    /**
+85 −8
Original line number Diff line number Diff line
@@ -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();
        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) {
+18 −4
Original line number Diff line number Diff line
@@ -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,12 +958,22 @@ 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());
        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 {
            mConnector.execute(cmd);
@@ -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);

+20 −1
Original line number Diff line number Diff line
@@ -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