Send rawOffloadPacket to OffloadEngine

Add the missing logic to send the rawOffloadPacket to OffloadEngine.

Bug: 297314970
Test: atest CtsNetTestCases FrameworksNetTestCases
Change-Id: I06d7a9bb84df72808eff4f0c9df60f7e60aa2a2c
diff --git a/framework-t/src/android/net/nsd/OffloadServiceInfo.java b/framework-t/src/android/net/nsd/OffloadServiceInfo.java
index 7bd5a7d..2c839bc 100644
--- a/framework-t/src/android/net/nsd/OffloadServiceInfo.java
+++ b/framework-t/src/android/net/nsd/OffloadServiceInfo.java
@@ -161,6 +161,23 @@
     }
 
     /**
+     * Create a new OffloadServiceInfo with payload updated.
+     *
+     * @hide
+     */
+    @NonNull
+    public OffloadServiceInfo withOffloadPayload(@NonNull byte[] offloadPayload) {
+        return new OffloadServiceInfo(
+                this.getKey(),
+                this.getSubtypes(),
+                this.getHostname(),
+                offloadPayload,
+                this.getPriority(),
+                this.getOffloadType()
+        );
+    }
+
+    /**
      * Get the offloadType.
      * <p>
      * For example, if the {@link com.android.server.NsdService} requests the OffloadEngine to both
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java b/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java
index f43df45..ce05a84 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsAdvertiser.java
@@ -146,9 +146,12 @@
                             interfaceName, k -> new ArrayList<>());
             // Remove existing offload services from cache for update.
             existingOffloadServiceInfoWrappers.removeIf(item -> item.mServiceId == serviceId);
+
+            byte[] rawOffloadPacket = advertiser.getRawOffloadPayload(serviceId);
             final OffloadServiceInfoWrapper newOffloadServiceInfoWrapper = createOffloadService(
                     serviceId,
-                    registration);
+                    registration,
+                    rawOffloadPacket);
             existingOffloadServiceInfoWrappers.add(newOffloadServiceInfoWrapper);
             mCb.onOffloadStartOrUpdate(interfaceName,
                     newOffloadServiceInfoWrapper.mOffloadServiceInfo);
@@ -393,7 +396,29 @@
         public void onAddressesChanged(@NonNull SocketKey socketKey,
                 @NonNull MdnsInterfaceSocket socket, @NonNull List<LinkAddress> addresses) {
             final MdnsInterfaceAdvertiser advertiser = mAdvertisers.get(socket);
-            if (advertiser != null) advertiser.updateAddresses(addresses);
+            if (advertiser == null)  {
+                return;
+            }
+            advertiser.updateAddresses(addresses);
+            // Update address should trigger offload packet update.
+            final String interfaceName = advertiser.getSocketInterfaceName();
+            final List<OffloadServiceInfoWrapper> existingOffloadServiceInfoWrappers =
+                    mInterfaceOffloadServices.get(interfaceName);
+            if (existingOffloadServiceInfoWrappers == null) {
+                return;
+            }
+            final List<OffloadServiceInfoWrapper> updatedOffloadServiceInfoWrappers =
+                    new ArrayList<>(existingOffloadServiceInfoWrappers.size());
+            for (OffloadServiceInfoWrapper oldWrapper : existingOffloadServiceInfoWrappers) {
+                OffloadServiceInfoWrapper newWrapper = new OffloadServiceInfoWrapper(
+                        oldWrapper.mServiceId,
+                        oldWrapper.mOffloadServiceInfo.withOffloadPayload(
+                                advertiser.getRawOffloadPayload(oldWrapper.mServiceId))
+                );
+                updatedOffloadServiceInfoWrappers.add(newWrapper);
+                mCb.onOffloadStartOrUpdate(interfaceName, newWrapper.mOffloadServiceInfo);
+            }
+            mInterfaceOffloadServices.put(interfaceName, updatedOffloadServiceInfoWrappers);
         }
     }
 
@@ -630,9 +655,9 @@
     }
 
     private OffloadServiceInfoWrapper createOffloadService(int serviceId,
-            @NonNull Registration registration) {
+            @NonNull Registration registration, byte[] rawOffloadPacket) {
         final NsdServiceInfo nsdServiceInfo = registration.getServiceInfo();
-        List<String> subTypes = new ArrayList<>();
+        final List<String> subTypes = new ArrayList<>();
         String subType = registration.getSubtype();
         if (subType != null) {
             subTypes.add(subType);
@@ -642,7 +667,7 @@
                         nsdServiceInfo.getServiceType()),
                 subTypes,
                 String.join(".", mDeviceHostName),
-                null /* rawOffloadPacket */,
+                rawOffloadPacket,
                 // TODO: define overlayable resources in
                 // ServiceConnectivityResources that set the priority based on
                 // service type.
@@ -651,5 +676,4 @@
                 OffloadEngine.OFFLOAD_TYPE_REPLY);
         return new OffloadServiceInfoWrapper(serviceId, offloadServiceInfo);
     }
-
 }
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiser.java b/service-t/src/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiser.java
index a83b852..61a2c5e 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiser.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiser.java
@@ -28,6 +28,7 @@
 import com.android.net.module.util.SharedLog;
 import com.android.server.connectivity.mdns.MdnsAnnouncer.BaseAnnouncementInfo;
 import com.android.server.connectivity.mdns.MdnsPacketRepeater.PacketRepeaterCallback;
+import com.android.server.connectivity.mdns.util.MdnsUtils;
 
 import java.io.IOException;
 import java.net.InetSocketAddress;
@@ -351,7 +352,25 @@
         mReplySender.queueReply(answers);
     }
 
+    /**
+     * Get the socket interface name.
+     */
     public String getSocketInterfaceName() {
         return mSocket.getInterface().getName();
     }
+
+    /**
+     * Gets the offload MdnsPacket.
+     * @param serviceId The serviceId.
+     * @return the raw offload payload
+     */
+    public byte[] getRawOffloadPayload(int serviceId) {
+        try {
+            return MdnsUtils.createRawDnsPacket(mReplySender.getPacketCreationBuffer(),
+                    mRecordRepository.getOffloadPacket(serviceId));
+        } catch (IOException | IllegalArgumentException e) {
+            mSharedLog.wtf("Cannot create rawOffloadPacket: " + e.getMessage());
+            return new byte[0];
+        }
+    }
 }
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java b/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java
index 1375279..e25d7e1 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java
@@ -736,6 +736,38 @@
     }
 
     /**
+     * Gets the offload MdnsPacket.
+     * @param serviceId The serviceId.
+     * @return The offload {@link MdnsPacket} that contains PTR/SRV/TXT/A/AAAA records.
+     */
+    public MdnsPacket getOffloadPacket(int serviceId) throws IllegalArgumentException {
+        final ServiceRegistration registration = mServices.get(serviceId);
+        if (registration == null) throw new IllegalArgumentException(
+                "Service is not registered: " + serviceId);
+
+        final ArrayList<MdnsRecord> answers = new ArrayList<>();
+
+        // Adds all PTR, SRV, TXT, A/AAAA records.
+        for (RecordInfo<MdnsPointerRecord> ptrRecord : registration.ptrRecords) {
+            answers.add(ptrRecord.record);
+        }
+        answers.add(registration.srvRecord.record);
+        answers.add(registration.txtRecord.record);
+        for (RecordInfo<?> record : mGeneralRecords) {
+            if (record.record instanceof MdnsInetAddressRecord) {
+                answers.add(record.record);
+            }
+        }
+
+        final int flags = 0x8400; // Response, authoritative (rfc6762 18.4)
+        return new MdnsPacket(flags,
+                Collections.emptyList() /* questions */,
+                answers,
+                Collections.emptyList() /* authorityRecords */,
+                Collections.emptyList() /* additionalRecords */);
+    }
+
+    /**
      * Get the service IDs of services conflicting with a received packet.
      */
     public Set<Integer> getConflictingServices(MdnsPacket packet) {
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java b/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java
index 16c7d27..cf7a464 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java
@@ -25,6 +25,7 @@
 
 import com.android.net.module.util.SharedLog;
 import com.android.server.connectivity.mdns.MdnsRecordRepository.ReplyInfo;
+import com.android.server.connectivity.mdns.util.MdnsUtils;
 
 import java.io.IOException;
 import java.net.DatagramPacket;
@@ -86,36 +87,13 @@
             // Skip sending if the socket has not joined the v4/v6 group (there was no address)
             return;
         }
+        final byte[] outBuffer = MdnsUtils.createRawDnsPacket(mPacketCreationBuffer, packet);
+        mSocket.send(new DatagramPacket(outBuffer, 0, outBuffer.length, destination));
+    }
 
-        // TODO: support packets over size (send in multiple packets with TC bit set)
-        final MdnsPacketWriter writer = new MdnsPacketWriter(mPacketCreationBuffer);
-
-        writer.writeUInt16(0); // Transaction ID (advertisement: 0)
-        writer.writeUInt16(packet.flags); // Response, authoritative (rfc6762 18.4)
-        writer.writeUInt16(packet.questions.size()); // questions count
-        writer.writeUInt16(packet.answers.size()); // answers count
-        writer.writeUInt16(packet.authorityRecords.size()); // authority entries count
-        writer.writeUInt16(packet.additionalRecords.size()); // additional records count
-
-        for (MdnsRecord record : packet.questions) {
-            // Questions do not have TTL or data
-            record.writeHeaderFields(writer);
-        }
-        for (MdnsRecord record : packet.answers) {
-            record.write(writer, 0L);
-        }
-        for (MdnsRecord record : packet.authorityRecords) {
-            record.write(writer, 0L);
-        }
-        for (MdnsRecord record : packet.additionalRecords) {
-            record.write(writer, 0L);
-        }
-
-        final int len = writer.getWritePosition();
-        final byte[] outBuffer = new byte[len];
-        System.arraycopy(mPacketCreationBuffer, 0, outBuffer, 0, len);
-
-        mSocket.send(new DatagramPacket(outBuffer, 0, len, destination));
+    /** Get the packetCreationBuffer */
+    public byte[] getPacketCreationBuffer() {
+        return mPacketCreationBuffer;
     }
 
     /**
diff --git a/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java b/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java
index df3bde8..c1c9c42 100644
--- a/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java
+++ b/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java
@@ -24,8 +24,11 @@
 import android.util.ArraySet;
 
 import com.android.server.connectivity.mdns.MdnsConstants;
+import com.android.server.connectivity.mdns.MdnsPacket;
+import com.android.server.connectivity.mdns.MdnsPacketWriter;
 import com.android.server.connectivity.mdns.MdnsRecord;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
@@ -165,6 +168,41 @@
     }
 
     /**
+     * Create a raw DNS packet.
+     */
+    public static byte[] createRawDnsPacket(@NonNull byte[] packetCreationBuffer,
+            @NonNull MdnsPacket packet) throws IOException {
+        // TODO: support packets over size (send in multiple packets with TC bit set)
+        final MdnsPacketWriter writer = new MdnsPacketWriter(packetCreationBuffer);
+
+        writer.writeUInt16(0); // Transaction ID (advertisement: 0)
+        writer.writeUInt16(packet.flags); // Response, authoritative (rfc6762 18.4)
+        writer.writeUInt16(packet.questions.size()); // questions count
+        writer.writeUInt16(packet.answers.size()); // answers count
+        writer.writeUInt16(packet.authorityRecords.size()); // authority entries count
+        writer.writeUInt16(packet.additionalRecords.size()); // additional records count
+
+        for (MdnsRecord record : packet.questions) {
+            // Questions do not have TTL or data
+            record.writeHeaderFields(writer);
+        }
+        for (MdnsRecord record : packet.answers) {
+            record.write(writer, 0L);
+        }
+        for (MdnsRecord record : packet.authorityRecords) {
+            record.write(writer, 0L);
+        }
+        for (MdnsRecord record : packet.additionalRecords) {
+            record.write(writer, 0L);
+        }
+
+        final int len = writer.getWritePosition();
+        final byte[] outBuffer = new byte[len];
+        System.arraycopy(packetCreationBuffer, 0, outBuffer, 0, len);
+        return outBuffer;
+    }
+
+    /**
      * Checks if the MdnsRecord needs to be renewed or not.
      *
      * <p>As per RFC6762 7.1 no need to query if remaining TTL is more than half the original one,
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
index 508e924..17a135a 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
@@ -900,6 +900,39 @@
         assertTrue(serviceInfo.hostname.endsWith("local"))
         assertEquals(0, serviceInfo.priority)
         assertEquals(OffloadEngine.OFFLOAD_TYPE_REPLY.toLong(), serviceInfo.offloadType)
+        val offloadPayload = serviceInfo.offloadPayload
+        assertNotNull(offloadPayload)
+        val dnsPacket = TestDnsPacket(offloadPayload)
+        assertEquals(0x8400, dnsPacket.header.flags)
+        assertEquals(0, dnsPacket.records[DnsPacket.QDSECTION].size)
+        assertTrue(dnsPacket.records[DnsPacket.ANSECTION].size >= 5)
+        assertEquals(0, dnsPacket.records[DnsPacket.NSSECTION].size)
+        assertEquals(0, dnsPacket.records[DnsPacket.ARSECTION].size)
+
+        val ptrRecord = dnsPacket.records[DnsPacket.ANSECTION][0]
+        assertEquals("$expectedServiceType.local", ptrRecord.dName)
+        assertEquals(0x0C /* PTR */, ptrRecord.nsType)
+        val ptrSubRecord = dnsPacket.records[DnsPacket.ANSECTION][1]
+        assertEquals("_subtype._sub.$expectedServiceType.local", ptrSubRecord.dName)
+        assertEquals(0x0C /* PTR */, ptrSubRecord.nsType)
+        val srvRecord = dnsPacket.records[DnsPacket.ANSECTION][2]
+        assertEquals("${si.serviceName}.$expectedServiceType.local", srvRecord.dName)
+        assertEquals(0x21 /* SRV */, srvRecord.nsType)
+        val txtRecord = dnsPacket.records[DnsPacket.ANSECTION][3]
+        assertEquals("${si.serviceName}.$expectedServiceType.local", txtRecord.dName)
+        assertEquals(0x10 /* TXT */, txtRecord.nsType)
+        val iface = NetworkInterface.getByName(testNetwork1.iface.interfaceName)
+        val allAddress = iface.inetAddresses.toList()
+        for (i in 4 until dnsPacket.records[DnsPacket.ANSECTION].size) {
+            val addressRecord = dnsPacket.records[DnsPacket.ANSECTION][i]
+            assertTrue(addressRecord.dName.startsWith("Android_"))
+            assertTrue(addressRecord.dName.endsWith("local"))
+            assertTrue(addressRecord.nsType in arrayOf(0x1C /* AAAA */, 0x01 /* A */))
+            val rData = addressRecord.rr
+            assertNotNull(rData)
+            val addr = InetAddress.getByAddress(rData)
+            assertTrue(addr in allAddress)
+        }
     }
 
     @Test
@@ -1410,6 +1443,11 @@
 ): ByteArray? = pollForMdnsPacket(timeoutMs) { it.isReplyFor("$serviceName.$serviceType.local") }
 
 private class TestDnsPacket(data: ByteArray) : DnsPacket(data) {
+    val header: DnsHeader
+        get() = mHeader
+    val records: Array<List<DnsRecord>>
+        get() = mRecords
+
     fun isProbeFor(name: String): Boolean = mRecords[QDSECTION].any {
         it.dName == name && it.nsType == 0xff /* ANY */
     }
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsAdvertiserTest.kt b/tests/unit/java/com/android/server/connectivity/mdns/MdnsAdvertiserTest.kt
index 9b38fea..862a9ec 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsAdvertiserTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsAdvertiserTest.kt
@@ -56,7 +56,9 @@
 private const val CASE_INSENSITIVE_TEST_SERVICE_ID = 5
 private const val TIMEOUT_MS = 10_000L
 private val TEST_ADDR = parseNumericAddress("2001:db8::123")
+private val TEST_ADDR2 = parseNumericAddress("2001:db8::124")
 private val TEST_LINKADDR = LinkAddress(TEST_ADDR, 64 /* prefixLength */)
+private val TEST_LINKADDR2 = LinkAddress(TEST_ADDR2, 64 /* prefixLength */)
 private val TEST_NETWORK_1 = mock(Network::class.java)
 private val TEST_SOCKETKEY_1 = SocketKey(1001 /* interfaceIndex */)
 private val TEST_SOCKETKEY_2 = SocketKey(1002 /* interfaceIndex */)
@@ -64,6 +66,8 @@
 private const val TEST_SUBTYPE = "_subtype"
 private val TEST_INTERFACE1 = "test_iface1"
 private val TEST_INTERFACE2 = "test_iface2"
+private val TEST_OFFLOAD_PACKET1 = byteArrayOf(0x01, 0x02, 0x03)
+private val TEST_OFFLOAD_PACKET2 = byteArrayOf(0x02, 0x03, 0x04)
 
 private val SERVICE_1 = NsdServiceInfo("TestServiceName", "_advertisertest._tcp").apply {
     port = 12345
@@ -102,7 +106,7 @@
     OffloadServiceInfo.Key("TestServiceName", "_advertisertest._tcp"),
     listOf(TEST_SUBTYPE),
     "Android_test.local",
-    null, /* rawOffloadPacket */
+    TEST_OFFLOAD_PACKET1,
     0, /* priority */
     OffloadEngine.OFFLOAD_TYPE_REPLY.toLong()
 )
@@ -111,7 +115,16 @@
     OffloadServiceInfo.Key("TestServiceName", "_advertisertest._tcp"),
     listOf(),
     "Android_test.local",
-    null, /* rawOffloadPacket */
+    TEST_OFFLOAD_PACKET1,
+    0, /* priority */
+    OffloadEngine.OFFLOAD_TYPE_REPLY.toLong()
+)
+
+private val OFFLOAD_SERVICEINFO_NO_SUBTYPE2 = OffloadServiceInfo(
+    OffloadServiceInfo.Key("TestServiceName", "_advertisertest._tcp"),
+    listOf(),
+    "Android_test.local",
+    TEST_OFFLOAD_PACKET2,
     0, /* priority */
     OffloadEngine.OFFLOAD_TYPE_REPLY.toLong()
 )
@@ -147,6 +160,10 @@
         doReturn(createEmptyNetworkInterface()).`when`(mockSocket2).getInterface()
         doReturn(TEST_INTERFACE1).`when`(mockInterfaceAdvertiser1).socketInterfaceName
         doReturn(TEST_INTERFACE2).`when`(mockInterfaceAdvertiser2).socketInterfaceName
+        doReturn(TEST_OFFLOAD_PACKET1).`when`(mockInterfaceAdvertiser1).getRawOffloadPayload(
+            SERVICE_ID_1)
+        doReturn(TEST_OFFLOAD_PACKET1).`when`(mockInterfaceAdvertiser2).getRawOffloadPayload(
+            SERVICE_ID_1)
     }
 
     @After
@@ -189,10 +206,23 @@
         verify(cb).onRegisterServiceSucceeded(eq(SERVICE_ID_1), argThat { it.matches(SERVICE_1) })
         verify(cb).onOffloadStartOrUpdate(eq(TEST_INTERFACE1), eq(OFFLOAD_SERVICEINFO_NO_SUBTYPE))
 
+        doReturn(TEST_OFFLOAD_PACKET2).`when`(mockInterfaceAdvertiser1)
+            .getRawOffloadPayload(
+                SERVICE_ID_1
+            )
+        postSync {
+            socketCb.onAddressesChanged(
+                TEST_SOCKETKEY_1,
+                mockSocket1,
+                listOf(TEST_LINKADDR2)
+            )
+        }
+        verify(cb).onOffloadStartOrUpdate(eq(TEST_INTERFACE1), eq(OFFLOAD_SERVICEINFO_NO_SUBTYPE2))
+
         postSync { socketCb.onInterfaceDestroyed(TEST_SOCKETKEY_1, mockSocket1) }
         verify(mockInterfaceAdvertiser1).destroyNow()
         postSync { intAdvCbCaptor.value.onDestroyed(mockSocket1) }
-        verify(cb).onOffloadStop(eq(TEST_INTERFACE1), eq(OFFLOAD_SERVICEINFO_NO_SUBTYPE))
+        verify(cb).onOffloadStop(eq(TEST_INTERFACE1), eq(OFFLOAD_SERVICEINFO_NO_SUBTYPE2))
     }
 
     @Test
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt
index 0033b5a..56fbdf0 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordRepositoryTest.kt
@@ -366,6 +366,58 @@
     }
 
     @Test
+    fun testGetOffloadPacket() {
+        val repository = MdnsRecordRepository(thread.looper, deps, TEST_HOSTNAME)
+        repository.initWithService(TEST_SERVICE_ID_1, TEST_SERVICE_1)
+        val serviceName = arrayOf("MyTestService", "_testservice", "_tcp", "local")
+        val serviceType = arrayOf("_testservice", "_tcp", "local")
+        val offloadPacket = repository.getOffloadPacket(TEST_SERVICE_ID_1)
+        assertEquals(0x8400, offloadPacket.flags)
+        assertEquals(0, offloadPacket.questions.size)
+        assertEquals(0, offloadPacket.additionalRecords.size)
+        assertEquals(0, offloadPacket.authorityRecords.size)
+        assertContentEquals(listOf(
+            MdnsPointerRecord(
+                serviceType,
+                0L /* receiptTimeMillis */,
+                // Not a unique name owned by the announcer, so cacheFlush=false
+                false /* cacheFlush */,
+                4500000L /* ttlMillis */,
+                serviceName),
+            MdnsServiceRecord(
+                serviceName,
+                0L /* receiptTimeMillis */,
+                true /* cacheFlush */,
+                120000L /* ttlMillis */,
+                0 /* servicePriority */,
+                0 /* serviceWeight */,
+                TEST_PORT /* servicePort */,
+                TEST_HOSTNAME),
+            MdnsTextRecord(
+                serviceName,
+                0L /* receiptTimeMillis */,
+                true /* cacheFlush */,
+                4500000L /* ttlMillis */,
+                emptyList() /* entries */),
+            MdnsInetAddressRecord(TEST_HOSTNAME,
+                0L /* receiptTimeMillis */,
+                true /* cacheFlush */,
+                120000L /* ttlMillis */,
+                TEST_ADDRESSES[0].address),
+            MdnsInetAddressRecord(TEST_HOSTNAME,
+                0L /* receiptTimeMillis */,
+                true /* cacheFlush */,
+                120000L /* ttlMillis */,
+                TEST_ADDRESSES[1].address),
+            MdnsInetAddressRecord(TEST_HOSTNAME,
+                0L /* receiptTimeMillis */,
+                true /* cacheFlush */,
+                120000L /* ttlMillis */,
+                TEST_ADDRESSES[2].address),
+        ), offloadPacket.answers)
+    }
+
+    @Test
     fun testGetReverseDnsAddress() {
         val expectedV6 = "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.B.D.0.1.0.0.2.ip6.arpa"
                 .split(".").toTypedArray()