Fix crash when socket read is interrupted
The exception is thrown in some normal cases e.g. interrupt()
called when Os.read is blocked and waiting for the input.
Ignore such events.
Test: 1. atest NetworkStackCoverageMtsConfigTests on S device
2. atest com.android.cts.net.HostsideVpnTests
3. atest NetworkStatsIntegrationTest
Bug: 259632210
Change-Id: Ibff41312d9c7431c2b19f780844ab3a81b48f9e8
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/NatPacketForwarderBase.java b/staticlibs/testutils/devicetests/com/android/testutils/NatPacketForwarderBase.java
index 85c6493..0a2b5d4 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/NatPacketForwarderBase.java
+++ b/staticlibs/testutils/devicetests/com/android/testutils/NatPacketForwarderBase.java
@@ -151,7 +151,8 @@
private void processPacket() {
final int len = PacketReflectorUtil.readPacket(mSrcFd, mBuf);
if (len < 1) {
- throw new IllegalStateException("Unexpected buffer length: " + len);
+ // Usually happens when socket read is being interrupted, e.g. stopping PacketForwarder.
+ return;
}
final int version = mBuf[0] >>> 4;
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/PacketReflectorUtil.kt b/staticlibs/testutils/devicetests/com/android/testutils/PacketReflectorUtil.kt
index b028045..498b1a3 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/PacketReflectorUtil.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/PacketReflectorUtil.kt
@@ -20,11 +20,12 @@
import android.system.ErrnoException
import android.system.Os
+import android.system.OsConstants
import com.android.net.module.util.IpUtils
import com.android.testutils.PacketReflector.IPV4_HEADER_LENGTH
import com.android.testutils.PacketReflector.IPV6_HEADER_LENGTH
import java.io.FileDescriptor
-import java.io.IOException
+import java.io.InterruptedIOException
import java.net.InetAddress
import java.nio.ByteBuffer
@@ -32,8 +33,15 @@
return try {
Os.read(fd, buf, 0, buf.size)
} catch (e: ErrnoException) {
- -1
- } catch (e: IOException) {
+ // Ignore normal use cases such as the EAGAIN error indicates that the read operation
+ // cannot be completed immediately, or the EINTR error indicates that the read
+ // operation was interrupted by a signal.
+ if (e.errno == OsConstants.EAGAIN || e.errno == OsConstants.EINTR) {
+ -1
+ } else {
+ throw e
+ }
+ } catch (e: InterruptedIOException) {
-1
}
}