Split UDP Encap socket tests into a base class and tests
This change splits any pieces of the UDP encapsulation socket tests in
preparation for adding UDP (non-encap) socket tests
Bug: 152460200
Test: FrameworksIkeTests pass
Change-Id: I5d1ae410c3c1dfee95617e3f6d746cefeedda98c
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSocketTestBase.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSocketTestBase.java
new file mode 100644
index 0000000..5bece07
--- /dev/null
+++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSocketTestBase.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.net.ipsec.ike;
+
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+
+import android.net.InetAddresses;
+import android.net.Network;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.Log;
+import android.util.LongSparseArray;
+
+import org.junit.After;
+import org.junit.Before;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public abstract class IkeSocketTestBase {
+ protected static final int REMOTE_RECV_BUFF_SIZE = 2048;
+ protected static final int TIMEOUT = 1000;
+
+ protected static final String NON_ESP_MARKER_HEX_STRING = "00000000";
+ protected static final String IKE_REQ_MESSAGE_HEX_STRING =
+ "5f54bf6d8b48e6e100000000000000002120220800000000"
+ + "00000150220000300000002c010100040300000c0100000c"
+ + "800e00800300000803000002030000080400000200000008"
+ + "020000022800008800020000b4a2faf4bb54878ae21d6385"
+ + "12ece55d9236fc5046ab6cef82220f421f3ce6361faf3656"
+ + "4ecb6d28798a94aad7b2b4b603ddeaaa5630adb9ece8ac37"
+ + "534036040610ebdd92f46bef84f0be7db860351843858f8a"
+ + "cf87056e272377f70c9f2d81e29c7b0ce4f291a3a72476bb"
+ + "0b278fd4b7b0a4c26bbeb08214c707137607958729000024"
+ + "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c7"
+ + "2cb4240eb5c464122900001c00004004e54f73b7d83f6beb"
+ + "881eab2051d8663f421d10b02b00001c00004005d915368c"
+ + "a036004cb578ae3e3fb268509aeab1900000002069936922"
+ + "8741c6d4ca094c93e242c9de19e7b7c60000000500000500";
+
+ protected static final long LOCAL_SPI = 0x0L;
+ protected static final long REMOTE_SPI = 0x5f54bf6d8b48e6e1L;
+
+ protected static final String DATA_ONE = "one 1";
+ protected static final String DATA_TWO = "two 2";
+
+ protected static final InetAddress IPV4_LOOPBACK =
+ InetAddresses.parseNumericAddress("127.0.0.1");
+ protected static final InetAddress IPV6_LOOPBACK = InetAddresses.parseNumericAddress("::1");
+
+ protected final LongSparseArray mSpiToIkeStateMachineMap =
+ new LongSparseArray<IkeSessionStateMachine>();
+
+ protected final Network mMockNetwork = mock(Network.class);
+ protected final IkeSessionStateMachine mMockIkeSessionStateMachine =
+ mock(IkeSessionStateMachine.class);
+
+ protected byte[] mDataOne;
+ protected byte[] mDataTwo;
+ protected FileDescriptor mDummyRemoteServerFd;
+ protected InetAddress mLocalAddress;
+
+ @Before
+ public void setUp() throws Exception {
+ mSpiToIkeStateMachineMap.put(LOCAL_SPI, mMockIkeSessionStateMachine);
+ mDummyRemoteServerFd = getBoundUdpSocket(IPV4_LOOPBACK);
+
+ mDataOne = DATA_ONE.getBytes("UTF-8");
+ mDataTwo = DATA_TWO.getBytes("UTF-8");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ IkeUdpEncapSocket.setPacketReceiver(getPacketReceiver());
+ Os.close(mDummyRemoteServerFd);
+ }
+
+ protected abstract IkeSocket.IPacketReceiver getPacketReceiver();
+
+ protected static FileDescriptor getBoundUdpSocket(InetAddress address) throws Exception {
+ FileDescriptor sock =
+ Os.socket(OsConstants.AF_INET, OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP);
+ Os.bind(sock, address, IkeSocket.SERVER_PORT_UDP_ENCAPSULATED);
+ return sock;
+ }
+
+ protected void verifyCloseFd(FileDescriptor fd) {
+ try {
+ Os.sendto(
+ fd,
+ ByteBuffer.wrap(mDataOne),
+ 0,
+ InetAddress.getLoopbackAddress(),
+ IkeSocket.SERVER_PORT_UDP_ENCAPSULATED);
+ fail("Expected to fail because fd is closed");
+ } catch (ErrnoException | IOException expected) {
+ }
+ }
+
+ protected byte[] receive(FileDescriptor mfd) throws Exception {
+ byte[] receiveBuffer = new byte[REMOTE_RECV_BUFF_SIZE];
+ AtomicInteger bytesRead = new AtomicInteger(-1);
+ Thread receiveThread =
+ new Thread(
+ () -> {
+ while (bytesRead.get() < 0) {
+ try {
+ bytesRead.set(
+ Os.recvfrom(
+ mDummyRemoteServerFd,
+ receiveBuffer,
+ 0,
+ REMOTE_RECV_BUFF_SIZE,
+ 0,
+ null));
+ } catch (Exception e) {
+ Log.e(
+ "IkeSocketTest",
+ "Error encountered reading from socket",
+ e);
+ }
+ }
+ });
+
+ receiveThread.start();
+ receiveThread.join(TIMEOUT);
+
+ return Arrays.copyOfRange(receiveBuffer, 0, bytesRead.get());
+ }
+
+ protected void sendToIkeSocket(
+ FileDescriptor fd, byte[] data, InetAddress destAddress, int port) throws Exception {
+ Os.sendto(fd, data, 0, data.length, 0, destAddress, port);
+ }
+
+ protected static class DummyPacketReceiver implements IkeSocket.IPacketReceiver {
+ byte[] mReceivedData = null;
+ final TestCountDownLatch mLatch;
+
+ DummyPacketReceiver(TestCountDownLatch latch) {
+ mLatch = latch;
+ }
+
+ public void handlePacket(
+ byte[] revbuf, LongSparseArray<IkeSessionStateMachine> spiToIkeSession) {
+ mReceivedData = Arrays.copyOfRange(revbuf, 0, revbuf.length);
+ mLatch.countDown();
+ }
+ }
+
+ protected static class TestCountDownLatch {
+ private CountDownLatch mLatch;
+
+ TestCountDownLatch() {
+ reset();
+ }
+
+ private void reset() {
+ mLatch = new CountDownLatch(1);
+ }
+
+ void countDown() {
+ mLatch.countDown();
+ }
+
+ void await() {
+ try {
+ if (!mLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
+ fail("Time out");
+ }
+ } catch (InterruptedException e) {
+ fail(e.toString());
+ }
+ reset();
+ }
+ }
+}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeUdpEncapSocketTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeUdpEncapSocketTest.java
index c7b0a64..fab2b47 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeUdpEncapSocketTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeUdpEncapSocketTest.java
@@ -20,7 +20,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyObject;
@@ -28,7 +27,6 @@
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -42,15 +40,11 @@
import android.os.HandlerThread;
import android.os.Looper;
import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
import android.util.Log;
-import android.util.LongSparseArray;
import androidx.test.InstrumentationRegistry;
import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.IkeUdpEncapSocket.PacketReceiver;
import com.android.internal.net.ipsec.ike.message.IkeHeader;
import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils;
import com.android.server.IpSecService;
@@ -65,62 +59,18 @@
import java.io.IOException;
import java.net.InetAddress;
import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-public final class IkeUdpEncapSocketTest {
- private static final int REMOTE_RECV_BUFF_SIZE = 2048;
- private static final int TIMEOUT = 1000;
-
- private static final String NON_ESP_MARKER_HEX_STRING = "00000000";
- private static final String IKE_REQ_MESSAGE_HEX_STRING =
- "5f54bf6d8b48e6e100000000000000002120220800000000"
- + "00000150220000300000002c010100040300000c0100000c"
- + "800e00800300000803000002030000080400000200000008"
- + "020000022800008800020000b4a2faf4bb54878ae21d6385"
- + "12ece55d9236fc5046ab6cef82220f421f3ce6361faf3656"
- + "4ecb6d28798a94aad7b2b4b603ddeaaa5630adb9ece8ac37"
- + "534036040610ebdd92f46bef84f0be7db860351843858f8a"
- + "cf87056e272377f70c9f2d81e29c7b0ce4f291a3a72476bb"
- + "0b278fd4b7b0a4c26bbeb08214c707137607958729000024"
- + "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c7"
- + "2cb4240eb5c464122900001c00004004e54f73b7d83f6beb"
- + "881eab2051d8663f421d10b02b00001c00004005d915368c"
- + "a036004cb578ae3e3fb268509aeab1900000002069936922"
- + "8741c6d4ca094c93e242c9de19e7b7c60000000500000500";
-
- private static final String LOCAL_SPI = "0000000000000000";
- private static final String REMOTE_SPI = "5f54bf6d8b48e6e1";
-
- private static final String DATA_ONE = "one 1";
- private static final String DATA_TWO = "two 2";
-
- private static final String IPV4_LOOPBACK = "127.0.0.1";
-
- private byte[] mDataOne;
- private byte[] mDataTwo;
-
- private long mLocalSpi;
- private long mRemoteSpi;
-
- private LongSparseArray mSpiToIkeStateMachineMap;
- private PacketReceiver mPacketReceiver;
-
+public final class IkeUdpEncapSocketTest extends IkeSocketTestBase {
private UdpEncapsulationSocket mSpyUdpEncapSocket;
- private InetAddress mLocalAddress;
- private FileDescriptor mDummyRemoteServerFd;
private UdpEncapsulationSocket mSpyDummyUdpEncapSocketOne;
private UdpEncapsulationSocket mSpyDummyUdpEncapSocketTwo;
private IpSecManager mSpyIpSecManager;
- private Network mMockNetwork;
- private IkeSessionStateMachine mMockIkeSessionStateMachine;
-
@Before
public void setUp() throws Exception {
+ super.setUp();
+
Context context = InstrumentationRegistry.getContext();
IpSecManager ipSecManager = (IpSecManager) context.getSystemService(Context.IPSEC_SERVICE);
mSpyUdpEncapSocket = spy(ipSecManager.openUdpEncapsulationSocket());
@@ -142,40 +92,18 @@
.doReturn(mSpyDummyUdpEncapSocketTwo)
.when(mSpyIpSecManager)
.openUdpEncapsulationSocket();
-
- mMockNetwork = mock(Network.class);
-
- mLocalAddress = InetAddress.getByName(IPV4_LOOPBACK);
- mDummyRemoteServerFd = getBoundUdpSocket(mLocalAddress);
-
- mDataOne = DATA_ONE.getBytes("UTF-8");
- mDataTwo = DATA_TWO.getBytes("UTF-8");
-
- ByteBuffer localSpiBuffer = ByteBuffer.wrap(TestUtils.hexStringToByteArray(LOCAL_SPI));
- mLocalSpi = localSpiBuffer.getLong();
- ByteBuffer remoteSpiBuffer = ByteBuffer.wrap(TestUtils.hexStringToByteArray(REMOTE_SPI));
- mRemoteSpi = remoteSpiBuffer.getLong();
-
- mMockIkeSessionStateMachine = mock(IkeSessionStateMachine.class);
-
- mSpiToIkeStateMachineMap = new LongSparseArray<IkeSessionStateMachine>();
- mSpiToIkeStateMachineMap.put(mLocalSpi, mMockIkeSessionStateMachine);
-
- mPacketReceiver = new IkeUdpEncapSocket.PacketReceiver();
}
@After
public void tearDown() throws Exception {
mSpyUdpEncapSocket.close();
- IkeUdpEncapSocket.setPacketReceiver(mPacketReceiver);
- Os.close(mDummyRemoteServerFd);
+
+ super.tearDown();
}
- private static FileDescriptor getBoundUdpSocket(InetAddress address) throws Exception {
- FileDescriptor sock =
- Os.socket(OsConstants.AF_INET, OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP);
- Os.bind(sock, address, IkeSocket.SERVER_PORT_UDP_ENCAPSULATED);
- return sock;
+ @Override
+ protected IkeSocket.IPacketReceiver getPacketReceiver() {
+ return new IkeUdpEncapSocket.PacketReceiver();
}
@Test
@@ -265,7 +193,7 @@
IkeUdpEncapSocket ikeSocket =
IkeUdpEncapSocket.getIkeUdpEncapSocket(
mMockNetwork, mSpyIpSecManager, mMockIkeSessionStateMachine);
- ikeSocket.sendIkePacket(mDataOne, mLocalAddress);
+ ikeSocket.sendIkePacket(mDataOne, IPV4_LOOPBACK);
byte[] receivedData = receive(mDummyRemoteServerFd);
@@ -322,14 +250,14 @@
IkeUdpEncapSocket.setPacketReceiver(packetReceiver);
// Send first packet.
- sendToIkeUdpEncapSocket(mDummyRemoteServerFd, mDataOne, mLocalAddress);
+ sendToIkeUdpEncapSocket(mDummyRemoteServerFd, mDataOne, IPV4_LOOPBACK);
receiveLatch.await();
assertEquals(1, ikeSocket.numPacketsReceived());
assertArrayEquals(mDataOne, packetReceiver.mReceivedData);
// Send second packet.
- sendToIkeUdpEncapSocket(mDummyRemoteServerFd, mDataTwo, mLocalAddress);
+ sendToIkeUdpEncapSocket(mDummyRemoteServerFd, mDataTwo, IPV4_LOOPBACK);
receiveLatch.await();
assertEquals(2, ikeSocket.numPacketsReceived());
@@ -352,26 +280,13 @@
mIkeThread.quitSafely();
}
- private void verifyCloseFd(FileDescriptor fd) {
- try {
- Os.sendto(
- fd,
- ByteBuffer.wrap("Check if closed".getBytes()),
- 0,
- InetAddress.getLoopbackAddress(),
- IkeSocket.SERVER_PORT_UDP_ENCAPSULATED);
- fail("Expected to fail because fd is closed");
- } catch (ErrnoException | IOException expected) {
- }
- }
-
@Test
public void testHandlePacket() throws Exception {
byte[] recvBuf =
TestUtils.hexStringToByteArray(
NON_ESP_MARKER_HEX_STRING + IKE_REQ_MESSAGE_HEX_STRING);
- mPacketReceiver.handlePacket(recvBuf, mSpiToIkeStateMachineMap);
+ getPacketReceiver().handlePacket(recvBuf, mSpiToIkeStateMachineMap);
byte[] expectedIkePacketBytes = TestUtils.hexStringToByteArray(IKE_REQ_MESSAGE_HEX_STRING);
ArgumentCaptor<IkeHeader> ikeHeaderCaptor = ArgumentCaptor.forClass(IkeHeader.class);
@@ -379,8 +294,8 @@
.receiveIkePacket(ikeHeaderCaptor.capture(), eq(expectedIkePacketBytes));
IkeHeader capturedIkeHeader = ikeHeaderCaptor.getValue();
- assertEquals(mRemoteSpi, capturedIkeHeader.ikeInitiatorSpi);
- assertEquals(mLocalSpi, capturedIkeHeader.ikeResponderSpi);
+ assertEquals(REMOTE_SPI, capturedIkeHeader.ikeInitiatorSpi);
+ assertEquals(LOCAL_SPI, capturedIkeHeader.ikeResponderSpi);
}
@Test
@@ -391,7 +306,7 @@
// Modify Non-ESP Marker
recvBuf[0] = 1;
- mPacketReceiver.handlePacket(recvBuf, mSpiToIkeStateMachineMap);
+ getPacketReceiver().handlePacket(recvBuf, mSpiToIkeStateMachineMap);
verify(mMockIkeSessionStateMachine, never()).receiveIkePacket(any(), any());
}
@@ -403,48 +318,14 @@
TestUtils.hexStringToByteArray(
NON_ESP_MARKER_HEX_STRING + malformedIkePacketHexString);
- mPacketReceiver.handlePacket(recvBuf, mSpiToIkeStateMachineMap);
+ getPacketReceiver().handlePacket(recvBuf, mSpiToIkeStateMachineMap);
verify(mMockIkeSessionStateMachine, never()).receiveIkePacket(any(), any());
}
- private byte[] receive(FileDescriptor mfd) throws Exception {
- byte[] receiveBuffer = new byte[REMOTE_RECV_BUFF_SIZE];
- AtomicInteger bytesRead = new AtomicInteger(-1);
- Thread receiveThread =
- new Thread(
- () -> {
- while (bytesRead.get() < 0) {
- try {
- bytesRead.set(
- Os.recvfrom(
- mDummyRemoteServerFd,
- receiveBuffer,
- 0,
- REMOTE_RECV_BUFF_SIZE,
- 0,
- null));
- } catch (Exception e) {
- Log.e(
- "IkeUdpEncapSocketTest",
- "Error encountered reading from socket",
- e);
- }
- }
- Log.d(
- "IkeUdpEncapSocketTest",
- "Packet received with size of " + bytesRead.get());
- });
-
- receiveThread.start();
- receiveThread.join(TIMEOUT);
-
- return Arrays.copyOfRange(receiveBuffer, 0, bytesRead.get());
- }
-
private void sendToIkeUdpEncapSocket(FileDescriptor fd, byte[] data, InetAddress destAddress)
throws Exception {
- Os.sendto(fd, data, 0, data.length, 0, destAddress, mSpyUdpEncapSocket.getPort());
+ sendToIkeSocket(fd, data, destAddress, mSpyUdpEncapSocket.getPort());
}
private static class IkeUdpEncapSocketReceiver {
@@ -458,47 +339,4 @@
return mIkeUdpEncapSocket;
}
}
-
- private static class DummyPacketReceiver implements IkeUdpEncapSocket.IPacketReceiver {
- byte[] mReceivedData = null;
- final TestCountDownLatch mLatch;
-
- DummyPacketReceiver(TestCountDownLatch latch) {
- mLatch = latch;
- }
-
- public void handlePacket(
- byte[] revbuf, LongSparseArray<IkeSessionStateMachine> spiToIkeSession) {
- mReceivedData = Arrays.copyOfRange(revbuf, 0, revbuf.length);
- mLatch.countDown();
- Log.d("IkeUdpEncapSocketTest", "Packet received");
- }
- }
-
- private static class TestCountDownLatch {
- private CountDownLatch mLatch;
-
- TestCountDownLatch() {
- reset();
- }
-
- private void reset() {
- mLatch = new CountDownLatch(1);
- }
-
- void countDown() {
- mLatch.countDown();
- }
-
- void await() {
- try {
- if (!mLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
- fail("Time out");
- }
- } catch (InterruptedException e) {
- fail(e.toString());
- }
- reset();
- }
- }
}