diff --git a/tests/cts/net/src/android/net/cts/TunUtils.java b/tests/cts/net/src/android/net/cts/TunUtils.java index 03771608e4..268d8d2603 100644 --- a/tests/cts/net/src/android/net/cts/TunUtils.java +++ b/tests/cts/net/src/android/net/cts/TunUtils.java @@ -22,7 +22,6 @@ import static android.net.cts.PacketUtils.IPPROTO_ESP; import static android.net.cts.PacketUtils.UDP_HDRLEN; import static android.system.OsConstants.IPPROTO_UDP; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import android.os.ParcelFileDescriptor; @@ -32,6 +31,7 @@ import com.android.net.module.util.CollectionUtils; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -140,10 +140,8 @@ public class TunUtils { public byte[] awaitEspPacketNoPlaintext( int spi, byte[] plaintext, boolean useEncap, int expectedPacketSize) throws Exception { final byte[] espPkt = awaitPacket( - (pkt) -> isEspFailIfSpecifiedPlaintextFound(pkt, spi, useEncap, plaintext)); - - // Validate packet size - assertEquals(expectedPacketSize, espPkt.length); + (pkt) -> expectedPacketSize == pkt.length + && isEspFailIfSpecifiedPlaintextFound(pkt, spi, useEncap, plaintext)); return espPkt; // We've found the packet we're looking for. } @@ -153,11 +151,11 @@ public class TunUtils { } private static boolean isSpiEqual(byte[] pkt, int espOffset, int spi) { - // Check SPI byte by byte. - return pkt[espOffset] == (byte) ((spi >>> 24) & 0xff) - && pkt[espOffset + 1] == (byte) ((spi >>> 16) & 0xff) - && pkt[espOffset + 2] == (byte) ((spi >>> 8) & 0xff) - && pkt[espOffset + 3] == (byte) (spi & 0xff); + ByteBuffer buffer = ByteBuffer.wrap(pkt); + buffer.get(new byte[espOffset]); // Skip IP, UDP header + int actualSpi = buffer.getInt(); + + return actualSpi == spi; } /** @@ -180,8 +178,13 @@ public class TunUtils { private static boolean isEsp(byte[] pkt, int spi, boolean encap) { if (isIpv6(pkt)) { - // IPv6 UDP encap not supported by kernels; assume non-encap. - return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP6_HDRLEN, spi); + if (encap) { + return pkt[IP6_PROTO_OFFSET] == IPPROTO_UDP + && isSpiEqual(pkt, IP6_HDRLEN + UDP_HDRLEN, spi); + } else { + return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP6_HDRLEN, spi); + } + } else { // Use default IPv4 header length (assuming no options) if (encap) { diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java index df3a4aa052..d81763077f 100644 --- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java +++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java @@ -75,6 +75,13 @@ import java.util.concurrent.TimeoutException; public final class CtsNetUtils { private static final String TAG = CtsNetUtils.class.getSimpleName(); + + // Redefine this flag here so that IPsec code shipped in a mainline module can build on old + // platforms before FEATURE_IPSEC_TUNNEL_MIGRATION API is released. + // TODO: b/275378783 Remove this flag and use the platform API when it is available. + private static final String FEATURE_IPSEC_TUNNEL_MIGRATION = + "android.software.ipsec_tunnel_migration"; + private static final int SOCKET_TIMEOUT_MS = 2000; private static final int PRIVATE_DNS_PROBE_MS = 1_000; @@ -115,6 +122,11 @@ public final class CtsNetUtils { || getFirstApiLevel() >= Build.VERSION_CODES.Q; } + /** Checks if FEATURE_IPSEC_TUNNEL_MIGRATION is enabled on the device */ + public boolean hasIpsecTunnelMigrateFeature() { + return mContext.getPackageManager().hasSystemFeature(FEATURE_IPSEC_TUNNEL_MIGRATION); + } + /** * Sets the given appop using shell commands *