Merge "Move common logic in testing and verification to IkeSessionTestBase"

This commit is contained in:
Yan Yan
2020-05-26 22:51:40 +00:00
committed by Gerrit Code Review
3 changed files with 153 additions and 134 deletions

View File

@@ -16,25 +16,17 @@
package android.net.ipsec.ike.cts; package android.net.ipsec.ike.cts;
import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION;
import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN; import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static com.android.internal.util.HexDump.hexStringToByteArray;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import android.net.ipsec.ike.ChildSessionConfiguration; import android.net.LinkAddress;
import android.net.ipsec.ike.IkeFqdnIdentification; import android.net.ipsec.ike.IkeFqdnIdentification;
import android.net.ipsec.ike.IkeSession; import android.net.ipsec.ike.IkeSession;
import android.net.ipsec.ike.IkeSessionConfiguration;
import android.net.ipsec.ike.IkeSessionConnectionInfo;
import android.net.ipsec.ike.IkeSessionParams; import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.TunnelModeChildSessionParams;
import android.net.ipsec.ike.exceptions.IkeException; import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeProtocolException; import android.net.ipsec.ike.exceptions.IkeProtocolException;
import android.platform.test.annotations.AppModeFull; import android.platform.test.annotations.AppModeFull;
@@ -45,10 +37,11 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") @AppModeFull(reason = "MANAGE_IPSEC_TUNNELS permission can't be granted to instant apps")
public class IkeSessionPskTest extends IkeSessionTestBase { public class IkeSessionPskTest extends IkeSessionTestBase {
// Test vectors for success workflow // Test vectors for success workflow
private static final String SUCCESS_IKE_INIT_RESP = private static final String SUCCESS_IKE_INIT_RESP =
@@ -89,16 +82,6 @@ public class IkeSessionPskTest extends IkeSessionTestBase {
+ "9352D71100777B00ABCC6BD7DBEA697827FFAAA48DF9A54D1D68161939F5DC8" + "9352D71100777B00ABCC6BD7DBEA697827FFAAA48DF9A54D1D68161939F5DC8"
+ "6743A7CEB2BE34AC00095A5B8"; + "6743A7CEB2BE34AC00095A5B8";
private static final long IKE_INIT_SPI = Long.parseLong("46B8ECA1E0D72A18", 16);
private static final TunnelModeChildSessionParams CHILD_PARAMS =
new TunnelModeChildSessionParams.Builder()
.addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
.addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher())
.addInternalAddressRequest(AF_INET)
.addInternalAddressRequest(AF_INET6)
.build();
private IkeSession openIkeSessionWithRemoteAddress(InetAddress remoteAddress) { private IkeSession openIkeSessionWithRemoteAddress(InetAddress remoteAddress) {
IkeSessionParams ikeParams = IkeSessionParams ikeParams =
new IkeSessionParams.Builder(sContext) new IkeSessionParams.Builder(sContext)
@@ -113,7 +96,7 @@ public class IkeSessionPskTest extends IkeSessionTestBase {
return new IkeSession( return new IkeSession(
sContext, sContext,
ikeParams, ikeParams,
CHILD_PARAMS, buildTunnelModeChildSessionParams(),
mUserCbExecutor, mUserCbExecutor,
mIkeSessionCallback, mIkeSessionCallback,
mFirstChildSessionCallback); mFirstChildSessionCallback);
@@ -125,45 +108,17 @@ public class IkeSessionPskTest extends IkeSessionTestBase {
// Open IKE Session // Open IKE Session
IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress); IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
int expectedMsgId = 0; performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
mTunUtils.awaitReqAndInjectResp(
IKE_INIT_SPI,
expectedMsgId++,
false /* expectedUseEncap */,
hexStringToByteArray(SUCCESS_IKE_INIT_RESP));
mTunUtils.awaitReqAndInjectResp( // IKE INIT and IKE AUTH takes two exchanges. Message ID starts from 2
IKE_INIT_SPI, int expectedMsgId = 2;
expectedMsgId++,
true /* expectedUseEncap */,
hexStringToByteArray(SUCCESS_IKE_AUTH_RESP));
// Verify opening IKE Session verifyIkeSessionSetupBlocking();
IkeSessionConfiguration ikeConfig = mIkeSessionCallback.awaitIkeConfig(); verifyChildSessionSetupBlocking(
assertNotNull(ikeConfig); mFirstChildSessionCallback,
assertEquals(EXPECTED_REMOTE_APP_VERSION_EMPTY, ikeConfig.getRemoteApplicationVersion()); Arrays.asList(TUNNEL_MODE_INBOUND_TS),
assertTrue(ikeConfig.getRemoteVendorIds().isEmpty()); Arrays.asList(TUNNEL_MODE_OUTBOUND_TS),
assertTrue(ikeConfig.getPcscfServers().isEmpty()); Arrays.asList(EXPECTED_INTERNAL_LINK_ADDR));
assertTrue(ikeConfig.isIkeExtensionEnabled(EXTENSION_TYPE_FRAGMENTATION));
IkeSessionConnectionInfo ikeConnectInfo = ikeConfig.getIkeSessionConnectionInfo();
assertNotNull(ikeConnectInfo);
assertEquals(mLocalAddress, ikeConnectInfo.getLocalAddress());
assertEquals(mRemoteAddress, ikeConnectInfo.getRemoteAddress());
assertEquals(mTunNetwork, ikeConnectInfo.getNetwork());
// Verify opening first Child Session
ChildSessionConfiguration firstChildConfig = mFirstChildSessionCallback.awaitChildConfig();
assertNotNull(firstChildConfig);
assertEquals(
Arrays.asList(EXPECTED_INBOUND_TS), firstChildConfig.getInboundTrafficSelectors());
assertEquals(Arrays.asList(DEFAULT_V4_TS), firstChildConfig.getOutboundTrafficSelectors());
assertEquals(
Arrays.asList(EXPECTED_INTERNAL_LINK_ADDR),
firstChildConfig.getInternalAddresses());
assertTrue(firstChildConfig.getInternalSubnets().isEmpty());
assertTrue(firstChildConfig.getInternalDnsServers().isEmpty());
assertTrue(firstChildConfig.getInternalDhcpServers().isEmpty());
IpSecTransformCallRecord firstTransformRecordA = IpSecTransformCallRecord firstTransformRecordA =
mFirstChildSessionCallback.awaitNextCreatedIpSecTransform(); mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
@@ -173,24 +128,19 @@ public class IkeSessionPskTest extends IkeSessionTestBase {
// Open additional Child Session // Open additional Child Session
TestChildSessionCallback additionalChildCb = new TestChildSessionCallback(); TestChildSessionCallback additionalChildCb = new TestChildSessionCallback();
ikeSession.openChildSession(CHILD_PARAMS, additionalChildCb); ikeSession.openChildSession(buildTunnelModeChildSessionParams(), additionalChildCb);
mTunUtils.awaitReqAndInjectResp( mTunUtils.awaitReqAndInjectResp(
IKE_INIT_SPI, IKE_DETERMINISTIC_INITIATOR_SPI,
expectedMsgId++, expectedMsgId++,
true /* expectedUseEncap */, true /* expectedUseEncap */,
hexStringToByteArray(SUCCESS_CREATE_CHILD_RESP)); SUCCESS_CREATE_CHILD_RESP);
// Verify opening additional Child Session // Verify opening additional Child Session
ChildSessionConfiguration additionalChildConfig = additionalChildCb.awaitChildConfig(); verifyChildSessionSetupBlocking(
assertNotNull(additionalChildConfig); additionalChildCb,
assertEquals( Arrays.asList(TUNNEL_MODE_INBOUND_TS),
Arrays.asList(EXPECTED_INBOUND_TS), firstChildConfig.getInboundTrafficSelectors()); Arrays.asList(TUNNEL_MODE_OUTBOUND_TS),
assertEquals(Arrays.asList(DEFAULT_V4_TS), firstChildConfig.getOutboundTrafficSelectors()); new ArrayList<LinkAddress>());
assertTrue(additionalChildConfig.getInternalAddresses().isEmpty());
assertTrue(additionalChildConfig.getInternalSubnets().isEmpty());
assertTrue(additionalChildConfig.getInternalDnsServers().isEmpty());
assertTrue(additionalChildConfig.getInternalDhcpServers().isEmpty());
IpSecTransformCallRecord additionalTransformRecordA = IpSecTransformCallRecord additionalTransformRecordA =
additionalChildCb.awaitNextCreatedIpSecTransform(); additionalChildCb.awaitNextCreatedIpSecTransform();
IpSecTransformCallRecord additionalTransformRecordB = IpSecTransformCallRecord additionalTransformRecordB =
@@ -200,10 +150,10 @@ public class IkeSessionPskTest extends IkeSessionTestBase {
// Close additional Child Session // Close additional Child Session
ikeSession.closeChildSession(additionalChildCb); ikeSession.closeChildSession(additionalChildCb);
mTunUtils.awaitReqAndInjectResp( mTunUtils.awaitReqAndInjectResp(
IKE_INIT_SPI, IKE_DETERMINISTIC_INITIATOR_SPI,
expectedMsgId++, expectedMsgId++,
true /* expectedUseEncap */, true /* expectedUseEncap */,
hexStringToByteArray(SUCCESS_DELETE_CHILD_RESP)); SUCCESS_DELETE_CHILD_RESP);
verifyDeleteIpSecTransformPair( verifyDeleteIpSecTransformPair(
additionalChildCb, additionalTransformRecordA, additionalTransformRecordB); additionalChildCb, additionalTransformRecordA, additionalTransformRecordB);
@@ -211,16 +161,8 @@ public class IkeSessionPskTest extends IkeSessionTestBase {
// Close IKE Session // Close IKE Session
ikeSession.close(); ikeSession.close();
mTunUtils.awaitReqAndInjectResp( performCloseIkeBlocking(expectedMsgId++, SUCCESS_DELETE_IKE_RESP);
IKE_INIT_SPI, verifyCloseIkeAndChildBlocking(firstTransformRecordA, firstTransformRecordB);
expectedMsgId++,
true /* expectedUseEncap */,
hexStringToByteArray(SUCCESS_DELETE_IKE_RESP));
verifyDeleteIpSecTransformPair(
mFirstChildSessionCallback, firstTransformRecordA, firstTransformRecordB);
mFirstChildSessionCallback.awaitOnClosed();
mIkeSessionCallback.awaitOnClosed();
} }
@Test @Test
@@ -229,18 +171,7 @@ public class IkeSessionPskTest extends IkeSessionTestBase {
// Open IKE Session // Open IKE Session
IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress); IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
int expectedMsgId = 0; performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
mTunUtils.awaitReqAndInjectResp(
IKE_INIT_SPI,
expectedMsgId++,
false /* expectedUseEncap */,
hexStringToByteArray(SUCCESS_IKE_INIT_RESP));
mTunUtils.awaitReqAndInjectResp(
IKE_INIT_SPI,
expectedMsgId++,
true /* expectedUseEncap */,
hexStringToByteArray(SUCCESS_IKE_AUTH_RESP));
ikeSession.kill(); ikeSession.kill();
mFirstChildSessionCallback.awaitOnClosed(); mFirstChildSessionCallback.awaitOnClosed();
@@ -256,10 +187,10 @@ public class IkeSessionPskTest extends IkeSessionTestBase {
IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress); IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
int expectedMsgId = 0; int expectedMsgId = 0;
mTunUtils.awaitReqAndInjectResp( mTunUtils.awaitReqAndInjectResp(
IKE_INIT_SPI, IKE_DETERMINISTIC_INITIATOR_SPI,
expectedMsgId++, expectedMsgId++,
false /* expectedUseEncap */, false /* expectedUseEncap */,
hexStringToByteArray(ikeInitFailRespHex)); ikeInitFailRespHex);
mFirstChildSessionCallback.awaitOnClosed(); mFirstChildSessionCallback.awaitOnClosed();

View File

@@ -16,9 +16,13 @@
package android.net.ipsec.ike.cts; package android.net.ipsec.ike.cts;
import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS; import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.app.AppOpsManager; import android.app.AppOpsManager;
@@ -37,7 +41,9 @@ import android.net.ipsec.ike.ChildSessionCallback;
import android.net.ipsec.ike.ChildSessionConfiguration; import android.net.ipsec.ike.ChildSessionConfiguration;
import android.net.ipsec.ike.IkeSessionCallback; import android.net.ipsec.ike.IkeSessionCallback;
import android.net.ipsec.ike.IkeSessionConfiguration; import android.net.ipsec.ike.IkeSessionConfiguration;
import android.net.ipsec.ike.IkeSessionConnectionInfo;
import android.net.ipsec.ike.IkeTrafficSelector; import android.net.ipsec.ike.IkeTrafficSelector;
import android.net.ipsec.ike.TunnelModeChildSessionParams;
import android.net.ipsec.ike.cts.TestNetworkUtils.TestNetworkCallback; import android.net.ipsec.ike.cts.TestNetworkUtils.TestNetworkCallback;
import android.net.ipsec.ike.exceptions.IkeException; import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeProtocolException; import android.net.ipsec.ike.exceptions.IkeProtocolException;
@@ -60,6 +66,7 @@ import org.junit.runner.RunWith;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -90,9 +97,13 @@ abstract class IkeSessionTestBase extends IkeTestBase {
InetAddresses.parseNumericAddress("198.51.100.10"); InetAddresses.parseNumericAddress("198.51.100.10");
static final LinkAddress EXPECTED_INTERNAL_LINK_ADDR = static final LinkAddress EXPECTED_INTERNAL_LINK_ADDR =
new LinkAddress(EXPECTED_INTERNAL_ADDR, IP4_PREFIX_LEN); new LinkAddress(EXPECTED_INTERNAL_ADDR, IP4_PREFIX_LEN);
static final IkeTrafficSelector EXPECTED_INBOUND_TS =
static final IkeTrafficSelector TUNNEL_MODE_INBOUND_TS =
new IkeTrafficSelector( new IkeTrafficSelector(
MIN_PORT, MAX_PORT, EXPECTED_INTERNAL_ADDR, EXPECTED_INTERNAL_ADDR); MIN_PORT, MAX_PORT, EXPECTED_INTERNAL_ADDR, EXPECTED_INTERNAL_ADDR);
static final IkeTrafficSelector TUNNEL_MODE_OUTBOUND_TS = DEFAULT_V4_TS;
static final long IKE_DETERMINISTIC_INITIATOR_SPI = Long.parseLong("46B8ECA1E0D72A18", 16);
// Static state to reduce setup/teardown // Static state to reduce setup/teardown
static Context sContext = InstrumentationRegistry.getContext(); static Context sContext = InstrumentationRegistry.getContext();
@@ -238,6 +249,45 @@ abstract class IkeSessionTestBase extends IkeTestBase {
} }
} }
TunnelModeChildSessionParams buildTunnelModeChildSessionParams() {
return new TunnelModeChildSessionParams.Builder()
.addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
.addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher())
.addInternalAddressRequest(AF_INET)
.addInternalAddressRequest(AF_INET6)
.build();
}
void performSetupIkeAndFirstChildBlocking(String ikeInitRespHex, String ikeAuthRespHex)
throws Exception {
mTunUtils.awaitReqAndInjectResp(
IKE_DETERMINISTIC_INITIATOR_SPI,
0 /* expectedMsgId */,
false /* expectedUseEncap */,
ikeInitRespHex);
mTunUtils.awaitReqAndInjectResp(
IKE_DETERMINISTIC_INITIATOR_SPI,
1 /* expectedMsgId */,
true /* expectedUseEncap */,
ikeAuthRespHex);
}
void performSetupIkeAndFirstChildBlocking(
String ikeInitRespHex, int expectedAuthReqPktCnt, String... ikeAuthRespPktHex)
throws Exception {
// TODO: Implemented in followup CL (aosp/1308675) to support awaiting multiple IKE AUTH
// request fragments and injecting multiple IKE AUTH response fragments
}
void performCloseIkeBlocking(int expectedMsgId, String deleteIkeRespHex) throws Exception {
mTunUtils.awaitReqAndInjectResp(
IKE_DETERMINISTIC_INITIATOR_SPI,
expectedMsgId,
true /* expectedUseEncap */,
deleteIkeRespHex);
}
/** Testing callback that allows caller to block current thread until a method get called */ /** Testing callback that allows caller to block current thread until a method get called */
static class TestIkeSessionCallback implements IkeSessionCallback { static class TestIkeSessionCallback implements IkeSessionCallback {
private CompletableFuture<IkeSessionConfiguration> mFutureIkeConfig = private CompletableFuture<IkeSessionConfiguration> mFutureIkeConfig =
@@ -392,6 +442,47 @@ abstract class IkeSessionTestBase extends IkeTestBase {
} }
} }
void verifyIkeSessionSetupBlocking() throws Exception {
IkeSessionConfiguration ikeConfig = mIkeSessionCallback.awaitIkeConfig();
assertNotNull(ikeConfig);
assertEquals(EXPECTED_REMOTE_APP_VERSION_EMPTY, ikeConfig.getRemoteApplicationVersion());
assertTrue(ikeConfig.getRemoteVendorIds().isEmpty());
assertTrue(ikeConfig.getPcscfServers().isEmpty());
assertTrue(ikeConfig.isIkeExtensionEnabled(EXTENSION_TYPE_FRAGMENTATION));
IkeSessionConnectionInfo ikeConnectInfo = ikeConfig.getIkeSessionConnectionInfo();
assertNotNull(ikeConnectInfo);
assertEquals(mLocalAddress, ikeConnectInfo.getLocalAddress());
assertEquals(mRemoteAddress, ikeConnectInfo.getRemoteAddress());
assertEquals(mTunNetwork, ikeConnectInfo.getNetwork());
}
void verifyChildSessionSetupBlocking(
TestChildSessionCallback childCallback,
List<IkeTrafficSelector> expectedInboundTs,
List<IkeTrafficSelector> expectedOutboundTs,
List<LinkAddress> expectedInternalAddresses)
throws Exception {
ChildSessionConfiguration childConfig = childCallback.awaitChildConfig();
assertNotNull(childConfig);
assertEquals(expectedInboundTs, childConfig.getInboundTrafficSelectors());
assertEquals(expectedOutboundTs, childConfig.getOutboundTrafficSelectors());
assertEquals(expectedInternalAddresses, childConfig.getInternalAddresses());
assertTrue(childConfig.getInternalSubnets().isEmpty());
assertTrue(childConfig.getInternalDnsServers().isEmpty());
assertTrue(childConfig.getInternalDhcpServers().isEmpty());
}
void verifyCloseIkeAndChildBlocking(
IpSecTransformCallRecord expectedTransformRecordA,
IpSecTransformCallRecord expectedTransformRecordB)
throws Exception {
verifyDeleteIpSecTransformPair(
mFirstChildSessionCallback, expectedTransformRecordA, expectedTransformRecordB);
mFirstChildSessionCallback.awaitOnClosed();
mIkeSessionCallback.awaitOnClosed();
}
static void verifyCreateIpSecTransformPair( static void verifyCreateIpSecTransformPair(
IpSecTransformCallRecord transformRecordA, IpSecTransformCallRecord transformRecordB) { IpSecTransformCallRecord transformRecordA, IpSecTransformCallRecord transformRecordB) {
IpSecTransform transformA = transformRecordA.ipSecTransform; IpSecTransform transformA = transformRecordA.ipSecTransform;

View File

@@ -26,6 +26,8 @@ import static android.net.ipsec.ike.cts.PacketUtils.UDP_HDRLEN;
import static android.net.ipsec.ike.cts.PacketUtils.UdpHeader; import static android.net.ipsec.ike.cts.PacketUtils.UdpHeader;
import static android.system.OsConstants.IPPROTO_UDP; import static android.system.OsConstants.IPPROTO_UDP;
import static com.android.internal.util.HexDump.hexStringToByteArray;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
@@ -35,6 +37,7 @@ import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Arrays; import java.util.Arrays;
import java.util.function.Predicate;
public class IkeTunUtils extends TunUtils { public class IkeTunUtils extends TunUtils {
private static final int PORT_LEN = 2; private static final int PORT_LEN = 2;
@@ -54,17 +57,24 @@ public class IkeTunUtils extends TunUtils {
/** /**
* Await the expected IKE request and inject an IKE response. * Await the expected IKE request and inject an IKE response.
* *
* @param respIkePkt IKE response packet without IP/UDP headers or NON ESP MARKER. * @param ikeRespDataHex IKE response hex without IP/UDP headers or NON ESP MARKER.
*/ */
public byte[] awaitReqAndInjectResp( public byte[] awaitReqAndInjectResp(
long expectedInitIkeSpi, int expectedMsgId, boolean expectedUseEncap, byte[] respIkePkt) long expectedInitIkeSpi,
int expectedMsgId,
boolean expectedUseEncap,
String ikeRespDataHex)
throws Exception { throws Exception {
byte[] request = byte[] request =
awaitIkePacket( awaitIkePacket(
expectedInitIkeSpi, (pkt) -> {
expectedMsgId, return isExpectedIkePkt(
false /* expectedResp */, pkt,
expectedUseEncap); expectedInitIkeSpi,
expectedMsgId,
false /* expectedResp */,
expectedUseEncap);
});
// Build response header by flipping address and port // Build response header by flipping address and port
InetAddress srcAddr = getAddress(request, false /* shouldGetSource */); InetAddress srcAddr = getAddress(request, false /* shouldGetSource */);
@@ -73,32 +83,26 @@ public class IkeTunUtils extends TunUtils {
int dstPort = getPort(request, true /* shouldGetSource */); int dstPort = getPort(request, true /* shouldGetSource */);
byte[] response = byte[] response =
buildIkePacket(srcAddr, dstAddr, srcPort, dstPort, expectedUseEncap, respIkePkt); buildIkePacket(
srcAddr,
dstAddr,
srcPort,
dstPort,
expectedUseEncap,
hexStringToByteArray(ikeRespDataHex));
injectPacket(response); injectPacket(response);
return request; return request;
} }
private byte[] awaitIkePacket( // TODO: Implemented in followup CL (aosp/1308675) to support awaiting multiple
long expectedInitIkeSpi, // request fragments and injecting multiple response fragments
int expectedMsgId,
boolean expectedResp, private byte[] awaitIkePacket(Predicate<byte[]> pktVerifier) throws Exception {
boolean expectedUseEncap)
throws Exception {
long endTime = System.currentTimeMillis() + TIMEOUT; long endTime = System.currentTimeMillis() + TIMEOUT;
int startIndex = 0; int startIndex = 0;
synchronized (mPackets) { synchronized (mPackets) {
while (System.currentTimeMillis() < endTime) { while (System.currentTimeMillis() < endTime) {
byte[] ikePkt = byte[] ikePkt = getFirstMatchingPacket(pktVerifier, startIndex);
getFirstMatchingPacket(
(pkt) -> {
return isIke(
pkt,
expectedInitIkeSpi,
expectedMsgId,
expectedResp,
expectedUseEncap);
},
startIndex);
if (ikePkt != null) { if (ikePkt != null) {
return ikePkt; // We've found the packet we're looking for. return ikePkt; // We've found the packet we're looking for.
} }
@@ -112,21 +116,14 @@ public class IkeTunUtils extends TunUtils {
} }
} }
String direction = expectedResp ? "response" : "request"; fail("No matching packet found");
fail(
"No such IKE "
+ direction
+ " found with Initiator SPI "
+ expectedInitIkeSpi
+ " and message ID "
+ expectedMsgId);
} }
throw new IllegalStateException( throw new IllegalStateException(
"Hit an impossible case where fail() didn't throw an exception"); "Hit an impossible case where fail() didn't throw an exception");
} }
private static boolean isIke( private static boolean isExpectedIkePkt(
byte[] pkt, byte[] pkt,
long expectedInitIkeSpi, long expectedInitIkeSpi,
int expectedMsgId, int expectedMsgId,
@@ -153,7 +150,7 @@ public class IkeTunUtils extends TunUtils {
} }
return pkt[ipProtocolOffset] == IPPROTO_UDP return pkt[ipProtocolOffset] == IPPROTO_UDP
&& areSpiAndMsgIdEqual( && isExpectedSpiAndMsgId(
pkt, ikeOffset, expectedInitIkeSpi, expectedMsgId, expectedResp); pkt, ikeOffset, expectedInitIkeSpi, expectedMsgId, expectedResp);
} }
@@ -170,10 +167,10 @@ public class IkeTunUtils extends TunUtils {
return Arrays.equals(NON_ESP_MARKER, nonEspMarker); return Arrays.equals(NON_ESP_MARKER, nonEspMarker);
} }
private static boolean areSpiAndMsgIdEqual( private static boolean isExpectedSpiAndMsgId(
byte[] pkt, byte[] pkt,
int ikeOffset, int ikeOffset,
long expectedIkeInitSpi, long expectedInitIkeSpi,
int expectedMsgId, int expectedMsgId,
boolean expectedResp) { boolean expectedResp) {
if (pkt.length <= ikeOffset + IKE_HEADER_LEN) return false; if (pkt.length <= ikeOffset + IKE_HEADER_LEN) return false;