Handle ICMP in testRequestIpSecTransformStateForTx
testRequestIpSecTransformStateForTs was flaky because sometimes ICMPv6(Router Solicitation) might be sent and failed the validation of packet/byte count. This CL provides two improvements - Change the validation to handle possible ICMP packets - In the await method, require sequence number match to ensure the expected packet has been sent out. Otherwise the await method will still return true on an old packet with the same SPI. Bug: 358324865 Test: atest IpSecManagerTunnelTest Flag: Exempt test code only Change-Id: I471014c11328bc0f32ee1f805accbaf7b29b8e7c
This commit is contained in:
parent
721772d97e
commit
3479e57fd2
2 changed files with 65 additions and 21 deletions
|
|
@ -23,10 +23,13 @@ import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA256;
|
|||
import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA384;
|
||||
import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512;
|
||||
import static android.net.IpSecAlgorithm.CRYPT_AES_CBC;
|
||||
import static android.net.cts.PacketUtils.ICMP_HDRLEN;
|
||||
import static android.net.cts.PacketUtils.IP6_HDRLEN;
|
||||
import static android.system.OsConstants.FIONREAD;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
|
|
@ -152,10 +155,17 @@ public class IpSecBaseTest {
|
|||
final IpSecTransformState transformState =
|
||||
futureIpSecTransform.get(SOCK_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
|
||||
assertEquals(txHighestSeqNum, transformState.getTxHighestSequenceNumber());
|
||||
// There might be ICMPv6(Router Solicitation) packets. Thus we can only check the lower
|
||||
// bound of the outgoing traffic.
|
||||
final long icmpV6RsCnt = transformState.getTxHighestSequenceNumber() - txHighestSeqNum;
|
||||
assertTrue(icmpV6RsCnt >= 0);
|
||||
|
||||
final long adjustedPacketCnt = packetCnt + icmpV6RsCnt;
|
||||
final long adjustedByteCnt = byteCnt + icmpV6RsCnt * (IP6_HDRLEN + ICMP_HDRLEN);
|
||||
|
||||
assertEquals(adjustedPacketCnt, transformState.getPacketCount());
|
||||
assertEquals(adjustedByteCnt, transformState.getByteCount());
|
||||
assertEquals(rxHighestSeqNum, transformState.getRxHighestSequenceNumber());
|
||||
assertEquals(packetCnt, transformState.getPacketCount());
|
||||
assertEquals(byteCnt, transformState.getByteCount());
|
||||
assertArrayEquals(replayBitmap, transformState.getReplayBitmap());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ import android.platform.test.annotations.AppModeFull;
|
|||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.net.module.util.CollectionUtils;
|
||||
import com.android.testutils.DevSdkIgnoreRule;
|
||||
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
|
||||
|
||||
|
|
@ -119,7 +120,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||
|
||||
private static final int TIMEOUT_MS = 500;
|
||||
|
||||
private static final int PACKET_COUNT = 5000;
|
||||
private static final int PACKET_COUNT = 100;
|
||||
|
||||
// Static state to reduce setup/teardown
|
||||
private static ConnectivityManager sCM;
|
||||
|
|
@ -1088,6 +1089,27 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||
UdpEncapsulationSocket encapSocket,
|
||||
IpSecTunnelTestRunnable test)
|
||||
throws Exception {
|
||||
return buildTunnelNetworkAndRunTests(
|
||||
localInner,
|
||||
remoteInner,
|
||||
localOuter,
|
||||
remoteOuter,
|
||||
spi,
|
||||
encapSocket,
|
||||
test,
|
||||
true /* enableEncrypt */);
|
||||
}
|
||||
|
||||
private int buildTunnelNetworkAndRunTests(
|
||||
InetAddress localInner,
|
||||
InetAddress remoteInner,
|
||||
InetAddress localOuter,
|
||||
InetAddress remoteOuter,
|
||||
int spi,
|
||||
UdpEncapsulationSocket encapSocket,
|
||||
IpSecTunnelTestRunnable test,
|
||||
boolean enableEncrypt)
|
||||
throws Exception {
|
||||
int innerPrefixLen = localInner instanceof Inet6Address ? IP6_PREFIX_LEN : IP4_PREFIX_LEN;
|
||||
TestNetworkCallback testNetworkCb = null;
|
||||
int innerSocketPort;
|
||||
|
|
@ -1115,8 +1137,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||
|
||||
// Configure Transform parameters
|
||||
IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext);
|
||||
transformBuilder.setEncryption(
|
||||
new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY));
|
||||
|
||||
if (enableEncrypt) {
|
||||
transformBuilder.setEncryption(
|
||||
new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY));
|
||||
}
|
||||
|
||||
transformBuilder.setAuthentication(
|
||||
new IpSecAlgorithm(
|
||||
IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4));
|
||||
|
|
@ -1167,8 +1193,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||
return innerSocketPort;
|
||||
}
|
||||
|
||||
private int buildTunnelNetworkAndRunTestsSimple(int spi, IpSecTunnelTestRunnable test)
|
||||
throws Exception {
|
||||
private int buildTunnelNetworkAndRunTestsSimple(
|
||||
int spi, IpSecTunnelTestRunnable test, boolean enableEncrypt) throws Exception {
|
||||
return buildTunnelNetworkAndRunTests(
|
||||
LOCAL_INNER_6,
|
||||
REMOTE_INNER_6,
|
||||
|
|
@ -1176,7 +1202,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||
REMOTE_OUTER_6,
|
||||
spi,
|
||||
null /* encapSocket */,
|
||||
test);
|
||||
test,
|
||||
enableEncrypt);
|
||||
}
|
||||
|
||||
private static void receiveAndValidatePacket(JavaUdpSocket socket) throws Exception {
|
||||
|
|
@ -1787,10 +1814,11 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||
PACKET_COUNT,
|
||||
PACKET_COUNT,
|
||||
PACKET_COUNT * (long) innerPacketSize,
|
||||
newReplayBitmap(REPLAY_BITMAP_LEN_BYTE * 8));
|
||||
newReplayBitmap(PACKET_COUNT));
|
||||
|
||||
return innerSocketPort;
|
||||
});
|
||||
},
|
||||
true /* enableEncrypt */);
|
||||
}
|
||||
|
||||
@IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
|
|
@ -1814,17 +1842,22 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||
ipsecNetwork.bindSocket(outSocket.mSocket);
|
||||
int innerSocketPort = outSocket.getPort();
|
||||
|
||||
int expectedPacketSize =
|
||||
getPacketSize(
|
||||
AF_INET6,
|
||||
AF_INET6,
|
||||
false /* useEncap */,
|
||||
false /* transportInTunnelMode */);
|
||||
int outSeqNum = 1;
|
||||
int receivedTestDataEspCnt = 0;
|
||||
|
||||
for (int i = 0; i < PACKET_COUNT; i++) {
|
||||
while (receivedTestDataEspCnt < PACKET_COUNT) {
|
||||
outSocket.sendTo(TEST_DATA, REMOTE_INNER_6, innerSocketPort);
|
||||
tunUtils.awaitEspPacketNoPlaintext(
|
||||
spi, TEST_DATA, false /* useEncap */, expectedPacketSize);
|
||||
|
||||
byte[] pkt = null;
|
||||
|
||||
// If it is an ESP that contains the TEST_DATA, move to the next
|
||||
// loop. Otherwise, the ESP may contain an ICMPv6(Router Solicitation).
|
||||
// In this case, just increase the expected sequence number and continue
|
||||
// waiting for the ESP with TEST_DATA
|
||||
do {
|
||||
pkt = tunUtils.awaitEspPacket(spi, false /* useEncap */, outSeqNum++);
|
||||
} while (CollectionUtils.indexOfSubArray(pkt, TEST_DATA) == -1);
|
||||
receivedTestDataEspCnt++;
|
||||
}
|
||||
|
||||
final int innerPacketSize =
|
||||
|
|
@ -1838,6 +1871,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||
newReplayBitmap(0));
|
||||
|
||||
return innerSocketPort;
|
||||
});
|
||||
},
|
||||
false /* enableEncrypt */);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue