Merge "Change DnsPacket.DnsRecord.MAXNAMESIZE to public"
diff --git a/staticlibs/device/com/android/net/module/util/netlink/InetDiagMessage.java b/staticlibs/device/com/android/net/module/util/netlink/InetDiagMessage.java
index e69a844..f8b4716 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/InetDiagMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/InetDiagMessage.java
@@ -39,6 +39,7 @@
import android.net.util.SocketUtils;
import android.os.Process;
+import android.os.SystemClock;
import android.system.ErrnoException;
import android.util.Log;
import android.util.Range;
@@ -461,11 +462,15 @@
*/
public static void destroyLiveTcpSockets(Set<Range<Integer>> ranges, Set<Integer> exemptUids)
throws SocketException, InterruptedIOException, ErrnoException {
+ final long startTimeMs = SystemClock.elapsedRealtime();
destroySockets(IPPROTO_TCP, TCP_ALIVE_STATE_FILTER,
(diagMsg) -> !exemptUids.contains(diagMsg.inetDiagMsg.idiag_uid)
&& containsUid(diagMsg, ranges)
&& !isLoopback(diagMsg)
&& !isAdbSocket(diagMsg));
+ final long durationMs = SystemClock.elapsedRealtime() - startTimeMs;
+ Log.d(TAG, "Destroyed live tcp sockets for uids=" + ranges + " exemptUids=" + exemptUids
+ + " in " + durationMs + "ms");
}
/**
@@ -479,10 +484,13 @@
*/
public static void destroyLiveTcpSocketsByOwnerUids(Set<Integer> ownerUids)
throws SocketException, InterruptedIOException, ErrnoException {
+ final long startTimeMs = SystemClock.elapsedRealtime();
destroySockets(IPPROTO_TCP, TCP_ALIVE_STATE_FILTER,
(diagMsg) -> ownerUids.contains(diagMsg.inetDiagMsg.idiag_uid)
&& !isLoopback(diagMsg)
&& !isAdbSocket(diagMsg));
+ final long durationMs = SystemClock.elapsedRealtime() - startTimeMs;
+ Log.d(TAG, "Destroyed live tcp sockets for uids=" + ownerUids + " in " + durationMs + "ms");
}
@Override
diff --git a/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java b/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java
index 308ea24..b512a95 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java
@@ -93,6 +93,15 @@
if (nlmsghdr == null || nlmsghdr.nlmsg_type != NetlinkConstants.NLMSG_ERROR) {
return null;
}
+
+ final int messageLength = NetlinkConstants.alignedLengthOf(nlmsghdr.nlmsg_len);
+ final int payloadLength = messageLength - StructNlMsgHdr.STRUCT_SIZE;
+ if (payloadLength < 0 || payloadLength > bytes.remaining()) {
+ // Malformed message or runt buffer. Pretend the buffer was consumed.
+ bytes.position(bytes.limit());
+ return null;
+ }
+
return NetlinkErrorMessage.parse(nlmsghdr, bytes);
}
diff --git a/staticlibs/native/bpf_headers/include/bpf/KernelUtils.h b/staticlibs/native/bpf_headers/include/bpf/KernelUtils.h
index b3dd86c..59257b8 100644
--- a/staticlibs/native/bpf_headers/include/bpf/KernelUtils.h
+++ b/staticlibs/native/bpf_headers/include/bpf/KernelUtils.h
@@ -57,11 +57,11 @@
}
#if defined(__LP64__)
-static_assert(isUserspace64bit(), "huh?");
+static_assert(isUserspace64bit(), "huh? LP64 must have 64-bit userspace");
#elif defined(__ILP32__)
-static_assert(isUserspace32bit(), "huh?");
+static_assert(isUserspace32bit(), "huh? ILP32 must have 32-bit userspace");
#else
-#error "huh?"
+#error "huh? must be either LP64 (64-bit userspace) or ILP32 (32-bit userspace)"
#endif
static_assert(isUserspace32bit() || isUserspace64bit(), "must be either 32 or 64 bit");
@@ -119,7 +119,11 @@
}
static constexpr bool isArm() {
-#if defined(__arm__) || defined(__aarch64__)
+#if defined(__arm__)
+ static_assert(isUserspace32bit(), "huh? arm must be 32 bit");
+ return true;
+#elif defined(__aarch64__)
+ static_assert(isUserspace64bit(), "aarch64 must be LP64 - no support for ILP32");
return true;
#else
return false;
@@ -127,7 +131,11 @@
}
static constexpr bool isX86() {
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__)
+ static_assert(isUserspace32bit(), "huh? i386 must be 32 bit");
+ return true;
+#elif defined(__x86_64__)
+ static_assert(isUserspace64bit(), "x86_64 must be LP64 - no support for ILP32 (x32)");
return true;
#else
return false;
diff --git a/staticlibs/tests/unit/src/com/android/testutils/HandlerUtilsTest.kt b/staticlibs/tests/unit/src/com/android/testutils/HandlerUtilsTest.kt
index 30e0daf..0f6fa48 100644
--- a/staticlibs/tests/unit/src/com/android/testutils/HandlerUtilsTest.kt
+++ b/staticlibs/tests/unit/src/com/android/testutils/HandlerUtilsTest.kt
@@ -18,8 +18,10 @@
import android.os.Handler
import android.os.HandlerThread
+import com.android.testutils.FunctionalUtils.ThrowingSupplier
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
+import kotlin.test.assertNull
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -69,13 +71,18 @@
repeat(ATTEMPTS) { attempt ->
var x = -10
- visibleOnHandlerThread(handler) { x = attempt }
+ var y = -11
+ y = visibleOnHandlerThread(handler, ThrowingSupplier<Int> { x = attempt; attempt })
assertEquals(attempt, x)
+ assertEquals(attempt, y)
handler.post { assertEquals(attempt, x) }
}
assertFailsWith<IllegalArgumentException> {
visibleOnHandlerThread(handler) { throw IllegalArgumentException() }
}
+
+ // Null values may be returned by the supplier
+ assertNull(visibleOnHandlerThread(handler, ThrowingSupplier<Nothing?> { null }))
}
}
diff --git a/staticlibs/tests/unit/src/com/android/testutils/TestableNetworkCallbackTest.kt b/staticlibs/tests/unit/src/com/android/testutils/TestableNetworkCallbackTest.kt
index 4ed881a..e838bdc 100644
--- a/staticlibs/tests/unit/src/com/android/testutils/TestableNetworkCallbackTest.kt
+++ b/staticlibs/tests/unit/src/com/android/testutils/TestableNetworkCallbackTest.kt
@@ -354,6 +354,13 @@
}
@Test
+ fun testExpectClass() {
+ val net = Network(1)
+ mCallback.onAvailable(net)
+ assertFails { mCallback.expect(LOST, net) }
+ }
+
+ @Test
fun testPoll() {
assertNull(mCallback.poll(SHORT_TIMEOUT_MS))
TNCInterpreter.interpretTestSpec(initial = mCallback, lineShift = 1,
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/HandlerUtils.kt b/staticlibs/testutils/devicetests/com/android/testutils/HandlerUtils.kt
index aa252a5..f00ca11 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/HandlerUtils.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/HandlerUtils.kt
@@ -23,6 +23,7 @@
import android.os.HandlerThread
import android.util.Log
import com.android.testutils.FunctionalUtils.ThrowingRunnable
+import com.android.testutils.FunctionalUtils.ThrowingSupplier
import java.lang.Exception
import java.util.concurrent.Executor
import kotlin.test.fail
@@ -55,7 +56,8 @@
}
/**
- * Executes a block of code, making its side effects visible on the caller and the handler thread
+ * Executes a block of code that returns a value, making its side effects visible on the caller and
+ * the handler thread.
*
* After this function returns, the side effects of the passed block of code are guaranteed to be
* observed both on the thread running the handler and on the thread running this method.
@@ -63,15 +65,15 @@
* until it's executed, so keep in mind this method will block, (including, if the handler isn't
* running, blocking forever).
*/
-fun visibleOnHandlerThread(handler: Handler, r: ThrowingRunnable) {
+fun <T> visibleOnHandlerThread(handler: Handler, supplier: ThrowingSupplier<T>): T {
val cv = ConditionVariable()
- var e: Exception? = null
+ var rv: Result<T> = Result.failure(RuntimeException("Not run"))
handler.post {
try {
- r.run()
+ rv = Result.success(supplier.get())
} catch (exception: Exception) {
Log.e(TAG, "visibleOnHandlerThread caught exception", exception)
- e = exception
+ rv = Result.failure(exception)
}
cv.open()
}
@@ -79,5 +81,10 @@
// and this thread also has seen the change (since cv.open() happens-before cv.block()
// returns).
cv.block()
- e?.let { throw it }
+ return rv.getOrThrow()
+}
+
+/** Overload of visibleOnHandlerThread but executes a block of code that does not return a value. */
+inline fun visibleOnHandlerThread(handler: Handler, r: ThrowingRunnable){
+ visibleOnHandlerThread(handler, ThrowingSupplier<Unit> { r.run() })
}
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
}
}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkCallback.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkCallback.kt
index 0e73112..4b6aea2 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkCallback.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkCallback.kt
@@ -236,7 +236,11 @@
errorMsg: String? = null,
test: (T) -> Boolean = { true }
) = expect<CallbackEntry>(network, timeoutMs, errorMsg) {
- test(it as? T ?: fail("Expected callback ${type.simpleName}, got $it"))
+ if (type.isInstance(it)) {
+ test(it as T) // Cast can't fail since type.isInstance(it) and type: KClass<T>
+ } else {
+ fail("Expected callback ${type.simpleName}, got $it")
+ }
} as T
@JvmOverloads