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

Commit cf1a4614 authored by Di Lu's avatar Di Lu Committed by Gerrit Code Review
Browse files

Merge "Add test case for user quota management in IpSecService"

parents 795d4a5a aa5c1dc6
Loading
Loading
Loading
Loading
+119 −0
Original line number Diff line number Diff line
@@ -23,7 +23,11 @@ import static android.system.OsConstants.SOCK_DGRAM;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -46,6 +50,8 @@ import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
@@ -57,6 +63,8 @@ import org.junit.runner.RunWith;
public class IpSecServiceTest {

    private static final int DROID_SPI = 0xD1201D;
    private static final int MAX_NUM_ENCAP_SOCKETS = 100;
    private static final int MAX_NUM_SPIS = 100;
    private static final int TEST_UDP_ENCAP_INVALID_PORT = 100;
    private static final int TEST_UDP_ENCAP_PORT_OUT_RANGE = 100000;

@@ -260,4 +268,115 @@ public class IpSecServiceTest {
            }
        }
    }

    /**
     * This function checks if the number of encap UDP socket that one UID can reserve
     * has a reasonable limit.
     */
    @Test
    public void testSocketResourceTrackerLimitation() throws Exception {
        List<IpSecUdpEncapResponse> openUdpEncapSockets = new ArrayList<IpSecUdpEncapResponse>();
        // Reserve sockets until it fails.
        for (int i = 0; i < MAX_NUM_ENCAP_SOCKETS; i++) {
            IpSecUdpEncapResponse newUdpEncapSocket =
                    mIpSecService.openUdpEncapsulationSocket(0, new Binder());
            assertNotNull(newUdpEncapSocket);
            if (IpSecManager.Status.OK != newUdpEncapSocket.status) {
                break;
            }
            openUdpEncapSockets.add(newUdpEncapSocket);
        }
        // Assert that the total sockets quota has a reasonable limit.
        assertTrue(
                openUdpEncapSockets.size() > 0
                        && openUdpEncapSockets.size() < MAX_NUM_ENCAP_SOCKETS);

        // Try to reserve one more UDP encapsulation socket, and should fail.
        IpSecUdpEncapResponse extraUdpEncapSocket =
                mIpSecService.openUdpEncapsulationSocket(0, new Binder());
        assertNotNull(extraUdpEncapSocket);
        assertEquals(IpSecManager.Status.RESOURCE_UNAVAILABLE, extraUdpEncapSocket.status);

        // Close one of the open UDP encapsulation scokets.
        mIpSecService.closeUdpEncapsulationSocket(openUdpEncapSockets.get(0).resourceId);
        openUdpEncapSockets.get(0).fileDescriptor.close();
        openUdpEncapSockets.remove(0);

        // Try to reserve one more UDP encapsulation socket, and should be successful.
        extraUdpEncapSocket = mIpSecService.openUdpEncapsulationSocket(0, new Binder());
        assertNotNull(extraUdpEncapSocket);
        assertEquals(IpSecManager.Status.OK, extraUdpEncapSocket.status);
        openUdpEncapSockets.add(extraUdpEncapSocket);

        // Close open UDP sockets.
        for (IpSecUdpEncapResponse openSocket : openUdpEncapSockets) {
            mIpSecService.closeUdpEncapsulationSocket(openSocket.resourceId);
            openSocket.fileDescriptor.close();
        }
    }

    /**
     * This function checks if the number of SPI that one UID can reserve
     * has a reasonable limit.
     * This test does not test for both address families or duplicate SPIs because resource
     * tracking code does not depend on them.
     */
    @Test
    public void testSpiResourceTrackerLimitation() throws Exception {
        List<IpSecSpiResponse> reservedSpis = new ArrayList<IpSecSpiResponse>();
        // Return the same SPI for all SPI allocation since IpSecService only
        // tracks the resource ID.
        when(mMockNetd.ipSecAllocateSpi(
                        anyInt(),
                        eq(IpSecTransform.DIRECTION_OUT),
                        anyString(),
                        eq(InetAddress.getLoopbackAddress().getHostAddress()),
                        anyInt()))
                .thenReturn(DROID_SPI);
        // Reserve spis until it fails.
        for (int i = 0; i < MAX_NUM_SPIS; i++) {
            IpSecSpiResponse newSpi =
                    mIpSecService.reserveSecurityParameterIndex(
                            0x1,
                            InetAddress.getLoopbackAddress().getHostAddress(),
                            DROID_SPI + i,
                            new Binder());
            assertNotNull(newSpi);
            if (IpSecManager.Status.OK != newSpi.status) {
                break;
            }
            reservedSpis.add(newSpi);
        }
        // Assert that the SPI quota has a reasonable limit.
        assertTrue(reservedSpis.size() > 0 && reservedSpis.size() < MAX_NUM_SPIS);

        // Try to reserve one more SPI, and should fail.
        IpSecSpiResponse extraSpi =
                mIpSecService.reserveSecurityParameterIndex(
                        0x1,
                        InetAddress.getLoopbackAddress().getHostAddress(),
                        DROID_SPI + MAX_NUM_SPIS,
                        new Binder());
        assertNotNull(extraSpi);
        assertEquals(IpSecManager.Status.RESOURCE_UNAVAILABLE, extraSpi.status);

        // Release one reserved spi.
        mIpSecService.releaseSecurityParameterIndex(reservedSpis.get(0).resourceId);
        reservedSpis.remove(0);

        // Should successfully reserve one more spi.
        extraSpi =
                mIpSecService.reserveSecurityParameterIndex(
                        0x1,
                        InetAddress.getLoopbackAddress().getHostAddress(),
                        DROID_SPI + MAX_NUM_SPIS,
                        new Binder());
        assertNotNull(extraSpi);
        assertEquals(IpSecManager.Status.OK, extraSpi.status);

        // Release reserved SPIs.
        for (IpSecSpiResponse spiResp : reservedSpis) {
            mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId);
        }
    }
}