Merge "Define DNS-over-TLS port in static lib"
diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index dad60f9..ff65228 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -265,6 +265,14 @@
         "//packages/apps/Settings",
     ],
     lint: { strict_updatability_linting: true },
+    errorprone: {
+        enabled: true,
+        // Error-prone checking only warns of problems when building. To make the build fail with
+        // these errors, list the specific error-prone problems below.
+        javacflags: [
+            "-Xep:NullablePrimitive:ERROR",
+        ],
+    },
 }
 
 java_library {
diff --git a/staticlibs/device/com/android/net/module/util/BpfMap.java b/staticlibs/device/com/android/net/module/util/BpfMap.java
index 9042085..9df2b03 100644
--- a/staticlibs/device/com/android/net/module/util/BpfMap.java
+++ b/staticlibs/device/com/android/net/module/util/BpfMap.java
@@ -70,8 +70,11 @@
     private static ParcelFileDescriptor cachedBpfFdGet(String path, int mode,
                                                        int keySize, int valueSize)
             throws ErrnoException, NullPointerException {
-        // TODO: key should include keySize & valueSize, but really we should match specific types
-        Pair<String, Integer> key = Pair.create(path, mode);
+        // Supports up to 1023 byte key and 65535 byte values
+        // Creating a BpfMap with larger keys/values seems like a bad idea any way...
+        keySize &= 1023; // 10-bits
+        valueSize &= 65535; // 16-bits
+        var key = Pair.create(path, (mode << 26) ^ (keySize << 16) ^ valueSize);
         // unlocked fetch is safe: map is concurrent read capable, and only inserted into
         ParcelFileDescriptor fd = sFdCache.get(key);
         if (fd != null) return fd;
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 d462c53..e69a844 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/InetDiagMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/InetDiagMessage.java
@@ -468,6 +468,23 @@
                         && !isAdbSocket(diagMsg));
     }
 
+    /**
+     * Close tcp sockets that match the following condition
+     *  1. TCP status is one of TCP_ESTABLISHED, TCP_SYN_SENT, and TCP_SYN_RECV
+     *  2. Owner uid of socket is in the targetUids
+     *  3. Socket is not loopback
+     *  4. Socket is not adb socket
+     *
+     * @param ownerUids target uids to close sockets
+     */
+    public static void destroyLiveTcpSocketsByOwnerUids(Set<Integer> ownerUids)
+            throws SocketException, InterruptedIOException, ErrnoException {
+        destroySockets(IPPROTO_TCP, TCP_ALIVE_STATE_FILTER,
+                (diagMsg) -> ownerUids.contains(diagMsg.inetDiagMsg.idiag_uid)
+                        && !isLoopback(diagMsg)
+                        && !isAdbSocket(diagMsg));
+    }
+
     @Override
     public String toString() {
         return "InetDiagMessage{ "
diff --git a/staticlibs/framework/com/android/net/module/util/CollectionUtils.java b/staticlibs/framework/com/android/net/module/util/CollectionUtils.java
index f08880c..39e7ce9 100644
--- a/staticlibs/framework/com/android/net/module/util/CollectionUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/CollectionUtils.java
@@ -101,7 +101,6 @@
     /**
      * @return The index of the first element that matches the predicate, or -1 if none.
      */
-    @Nullable
     public static <T> int indexOf(@NonNull final Collection<T> elem,
             @NonNull final Predicate<? super T> predicate) {
         int idx = 0;
diff --git a/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java b/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
index 8138b58..6a6f5e1 100644
--- a/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
+++ b/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
@@ -197,6 +197,8 @@
      *     - https://tools.ietf.org/html/rfc768
      */
     public static final int UDP_HEADER_LEN = 8;
+    public static final int UDP_SRCPORT_OFFSET = 0;
+    public static final int UDP_DSTPORT_OFFSET = 2;
     public static final int UDP_LENGTH_OFFSET = 4;
     public static final int UDP_CHECKSUM_OFFSET = 6;
 
diff --git a/staticlibs/native/bpfmapjni/Android.bp b/staticlibs/native/bpfmapjni/Android.bp
index 43d61fc..8babcce 100644
--- a/staticlibs/native/bpfmapjni/Android.bp
+++ b/staticlibs/native/bpfmapjni/Android.bp
@@ -46,7 +46,6 @@
     ],
     visibility: [
         "//packages/modules/Connectivity:__subpackages__",
-        "//packages/modules/NetworkStack:__subpackages__",
         // TODO: remove after NetworkStatsService moves to the module.
         "//frameworks/base/packages/ConnectivityT/service",
     ],
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/ArpResponder.kt b/staticlibs/testutils/devicetests/com/android/testutils/ArpResponder.kt
index 86631c3..cf0490c 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/ArpResponder.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/ArpResponder.kt
@@ -17,10 +17,14 @@
 package com.android.testutils
 
 import android.net.MacAddress
+import com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN
 import java.net.Inet4Address
 import java.net.InetAddress
 import java.nio.ByteBuffer
 
+private const val ARP_SENDER_MAC_OFFSET = ETHER_HEADER_LEN + 8
+private const val ARP_TARGET_IPADDR_OFFSET = ETHER_HEADER_LEN + 24
+
 private val TYPE_ARP = byteArrayOf(0x08, 0x06)
 // Arp reply header for IPv4 over ethernet
 private val ARP_REPLY_IPV4 = byteArrayOf(0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02)
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/PacketFilter.kt b/staticlibs/testutils/hostdevice/com/android/testutils/PacketFilter.kt
index 7c615d0..1bb6d68 100644
--- a/staticlibs/testutils/hostdevice/com/android/testutils/PacketFilter.kt
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/PacketFilter.kt
@@ -19,24 +19,25 @@
 import java.net.Inet4Address
 import java.util.function.Predicate
 
-const val ETHER_TYPE_OFFSET = 12
-const val ETHER_HEADER_LENGTH = 14
-const val IPV4_PROTOCOL_OFFSET = ETHER_HEADER_LENGTH + 9
-const val IPV4_CHECKSUM_OFFSET = ETHER_HEADER_LENGTH + 10
-const val IPV4_DST_OFFSET = ETHER_HEADER_LENGTH + 16
-const val IPV4_HEADER_LENGTH = 20
-const val IPV4_UDP_OFFSET = ETHER_HEADER_LENGTH + IPV4_HEADER_LENGTH
-const val IPV4_UDP_SRCPORT_OFFSET = IPV4_UDP_OFFSET
-const val IPV4_UDP_DSTPORT_OFFSET = IPV4_UDP_OFFSET + 2
-const val UDP_HEADER_LENGTH = 8
-const val BOOTP_OFFSET = IPV4_UDP_OFFSET + UDP_HEADER_LENGTH
-const val BOOTP_TID_OFFSET = BOOTP_OFFSET + 4
-const val BOOTP_CLIENT_MAC_OFFSET = BOOTP_OFFSET + 28
-const val DHCP_OPTIONS_OFFSET = BOOTP_OFFSET + 240
-
-const val ARP_OPCODE_OFFSET = ETHER_HEADER_LENGTH + 6
-const val ARP_SENDER_MAC_OFFSET = ETHER_HEADER_LENGTH + 8
-const val ARP_TARGET_IPADDR_OFFSET = ETHER_HEADER_LENGTH + 24
+// Some of the below constants are duplicated with NetworkStackConstants, but this is a hostdevice
+// library usable for host-side tests, so device-side utils are not usable, and there is no
+// host-side non-test library to host common constants.
+private const val ETHER_TYPE_OFFSET = 12
+private const val ETHER_HEADER_LENGTH = 14
+private const val IPV4_PROTOCOL_OFFSET = ETHER_HEADER_LENGTH + 9
+private const val IPV6_PROTOCOL_OFFSET = ETHER_HEADER_LENGTH + 6
+private const val IPV4_CHECKSUM_OFFSET = ETHER_HEADER_LENGTH + 10
+private const val IPV4_DST_OFFSET = ETHER_HEADER_LENGTH + 16
+private const val IPV4_HEADER_LENGTH = 20
+private const val IPV6_HEADER_LENGTH = 40
+private const val IPV4_PAYLOAD_OFFSET = ETHER_HEADER_LENGTH + IPV4_HEADER_LENGTH
+private const val IPV6_PAYLOAD_OFFSET = ETHER_HEADER_LENGTH + IPV6_HEADER_LENGTH
+private const val UDP_HEADER_LENGTH = 8
+private const val BOOTP_OFFSET = IPV4_PAYLOAD_OFFSET + UDP_HEADER_LENGTH
+private const val BOOTP_TID_OFFSET = BOOTP_OFFSET + 4
+private const val BOOTP_CLIENT_MAC_OFFSET = BOOTP_OFFSET + 28
+private const val DHCP_OPTIONS_OFFSET = BOOTP_OFFSET + 240
+private const val ARP_OPCODE_OFFSET = ETHER_HEADER_LENGTH + 6
 
 /**
  * A [Predicate] that matches a [ByteArray] if it contains the specified [bytes] at the specified
@@ -47,12 +48,48 @@
             bytes.withIndex().all { it.value == packet[offset + it.index] }
 }
 
+private class UdpPortFilter(
+    private val udpOffset: Int,
+    private val src: Short?,
+    private val dst: Short?
+) : Predicate<ByteArray> {
+    override fun test(t: ByteArray): Boolean {
+        if (src != null && !OffsetFilter(udpOffset,
+                        src.toInt().ushr(8).toByte(), src.toByte()).test(t)) {
+            return false
+        }
+
+        if (dst != null && !OffsetFilter(udpOffset + 2,
+                        dst.toInt().ushr(8).toByte(), dst.toByte()).test(t)) {
+            return false
+        }
+        return true
+    }
+}
+
 /**
  * A [Predicate] that matches ethernet-encapped packets that contain an UDP over IPv4 datagram.
  */
-class IPv4UdpFilter : Predicate<ByteArray> {
+class IPv4UdpFilter @JvmOverloads constructor(
+    srcPort: Short? = null,
+    dstPort: Short? = null
+) : Predicate<ByteArray> {
     private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x08, 0x00 /* IPv4 */).and(
-            OffsetFilter(IPV4_PROTOCOL_OFFSET, 17 /* UDP */))
+            OffsetFilter(IPV4_PROTOCOL_OFFSET, 17 /* UDP */)).and(
+            UdpPortFilter(IPV4_PAYLOAD_OFFSET, srcPort, dstPort))
+    override fun test(t: ByteArray) = impl.test(t)
+}
+
+/**
+ * A [Predicate] that matches ethernet-encapped packets that contain an UDP over IPv6 datagram.
+ */
+class IPv6UdpFilter @JvmOverloads constructor(
+    srcPort: Short? = null,
+    dstPort: Short? = null
+) : Predicate<ByteArray> {
+    private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x86.toByte(), 0xdd.toByte() /* IPv6 */).and(
+            OffsetFilter(IPV6_PROTOCOL_OFFSET, 17 /* UDP */)).and(
+            UdpPortFilter(IPV6_PAYLOAD_OFFSET, srcPort, dstPort))
     override fun test(t: ByteArray) = impl.test(t)
 }
 
@@ -77,9 +114,7 @@
  * A [Predicate] that matches ethernet-encapped DHCP packets sent from a DHCP client.
  */
 class DhcpClientPacketFilter : Predicate<ByteArray> {
-    private val impl = IPv4UdpFilter()
-            .and(OffsetFilter(IPV4_UDP_SRCPORT_OFFSET, 0x00, 0x44 /* 68 */))
-            .and(OffsetFilter(IPV4_UDP_DSTPORT_OFFSET, 0x00, 0x43 /* 67 */))
+    private val impl = IPv4UdpFilter(srcPort = 68, dstPort = 67)
     override fun test(t: ByteArray) = impl.test(t)
 }