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

Commit f4912722 authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by android-build-merger
Browse files

Merge "Add support for TAP interfaces in TestNetworkManager." am: dc7b7de8 am: ba2eb5e0

am: 14626021

Change-Id: I73c565cd69367cd7075c70cfa30d7f09c70acac0
parents ac7eb77b 14626021
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1365,6 +1365,7 @@ package android.net {
  }

  public class TestNetworkManager {
    method public android.net.TestNetworkInterface createTapInterface();
    method public android.net.TestNetworkInterface createTunInterface(@NonNull android.net.LinkAddress[]);
    method public void setupTestNetwork(@NonNull String, @NonNull android.os.IBinder);
    method public void teardownTestNetwork(@NonNull android.net.Network);
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.os.ParcelFileDescriptor;
interface ITestNetworkManager
{
    TestNetworkInterface createTunInterface(in LinkAddress[] linkAddrs);
    TestNetworkInterface createTapInterface();

    void setupTestNetwork(in String iface, in IBinder binder);

+17 −0
Original line number Diff line number Diff line
@@ -85,4 +85,21 @@ public class TestNetworkManager {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Create a tap interface for testing purposes
     *
     * @return A ParcelFileDescriptor of the underlying TAP interface. Close this to tear down the
     *     TAP interface.
     * @hide
     */
    @TestApi
    public TestNetworkInterface createTapInterface() {
        try {
            return mService.createTapInterface();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

}
+31 −8
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ class TestNetworkService extends ITestNetworkManager.Stub {
    @NonNull private static final String TAG = TestNetworkService.class.getSimpleName();
    @NonNull private static final String TEST_NETWORK_TYPE = "TEST_NETWORK";
    @NonNull private static final String TEST_TUN_PREFIX = "testtun";
    @NonNull private static final String TEST_TAP_PREFIX = "testtap";
    @NonNull private static final AtomicInteger sTestTunIndex = new AtomicInteger();

    @NonNull private final Context mContext;
@@ -70,7 +71,7 @@ class TestNetworkService extends ITestNetworkManager.Stub {
    @NonNull private final Handler mHandler;

    // Native method stubs
    private static native int jniCreateTun(@NonNull String iface);
    private static native int jniCreateTunTap(boolean isTun, @NonNull String iface);

    @VisibleForTesting
    protected TestNetworkService(
@@ -85,23 +86,23 @@ class TestNetworkService extends ITestNetworkManager.Stub {
    }

    /**
     * Create a TUN interface with the given interface name and link addresses
     * Create a TUN or TAP interface with the given interface name and link addresses
     *
     * <p>This method will return the FileDescriptor to the TUN interface. Close it to tear down the
     * TUN interface.
     * <p>This method will return the FileDescriptor to the interface. Close it to tear down the
     * interface.
     */
    @Override
    public TestNetworkInterface createTunInterface(@NonNull LinkAddress[] linkAddrs) {
    private TestNetworkInterface createInterface(boolean isTun, LinkAddress[] linkAddrs) {
        enforceTestNetworkPermissions(mContext);

        checkNotNull(linkAddrs, "missing linkAddrs");

        String iface = TEST_TUN_PREFIX + sTestTunIndex.getAndIncrement();
        String ifacePrefix = isTun ? TEST_TUN_PREFIX : TEST_TAP_PREFIX;
        String iface = ifacePrefix + sTestTunIndex.getAndIncrement();
        return Binder.withCleanCallingIdentity(
                () -> {
                    try {
                        ParcelFileDescriptor tunIntf =
                                ParcelFileDescriptor.adoptFd(jniCreateTun(iface));
                                ParcelFileDescriptor.adoptFd(jniCreateTunTap(isTun, iface));
                        for (LinkAddress addr : linkAddrs) {
                            mNetd.interfaceAddAddress(
                                    iface,
@@ -116,6 +117,28 @@ class TestNetworkService extends ITestNetworkManager.Stub {
                });
    }

    /**
     * Create a TUN interface with the given interface name and link addresses
     *
     * <p>This method will return the FileDescriptor to the TUN interface. Close it to tear down the
     * TUN interface.
     */
    @Override
    public TestNetworkInterface createTunInterface(@NonNull LinkAddress[] linkAddrs) {
        return createInterface(true, linkAddrs);
    }

    /**
     * Create a TAP interface with the given interface name
     *
     * <p>This method will return the FileDescriptor to the TAP interface. Close it to tear down the
     * TAP interface.
     */
    @Override
    public TestNetworkInterface createTapInterface() {
        return createInterface(false, new LinkAddress[0]);
    }

    // Tracker for TestNetworkAgents
    @GuardedBy("mTestNetworkTracker")
    @NonNull
+6 −6
Original line number Diff line number Diff line
@@ -54,12 +54,12 @@ static void throwException(JNIEnv* env, int error, const char* action, const cha
    jniThrowException(env, "java/lang/IllegalStateException", msg.c_str());
}

static int createTunInterface(JNIEnv* env, const char* iface) {
static int createTunTapInterface(JNIEnv* env, bool isTun, const char* iface) {
    base::unique_fd tun(open("/dev/tun", O_RDWR | O_NONBLOCK));
    ifreq ifr{};

    // Allocate interface.
    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
    ifr.ifr_flags = (isTun ? IFF_TUN : IFF_TAP) | IFF_NO_PI;
    strlcpy(ifr.ifr_name, iface, IFNAMSIZ);
    if (ioctl(tun.get(), TUNSETIFF, &ifr)) {
        throwException(env, errno, "allocating", ifr.ifr_name);
@@ -80,23 +80,23 @@ static int createTunInterface(JNIEnv* env, const char* iface) {

//------------------------------------------------------------------------------

static jint create(JNIEnv* env, jobject /* thiz */, jstring jIface) {
static jint create(JNIEnv* env, jobject /* thiz */, jboolean isTun, jstring jIface) {
    ScopedUtfChars iface(env, jIface);
    if (!iface.c_str()) {
        jniThrowNullPointerException(env, "iface");
        return -1;
    }

    int tun = createTunInterface(env, iface.c_str());
    int tun = createTunTapInterface(env, isTun, iface.c_str());

    // Any exceptions will be thrown from the createTunInterface call
    // Any exceptions will be thrown from the createTunTapInterface call
    return tun;
}

//------------------------------------------------------------------------------

static const JNINativeMethod gMethods[] = {
    {"jniCreateTun", "(Ljava/lang/String;)I", (void*)create},
    {"jniCreateTunTap", "(ZLjava/lang/String;)I", (void*)create},
};

int register_android_server_TestNetworkService(JNIEnv* env) {