Merge "Support mDns Multipacket Known-Answer Suppression" into main am: eeb79c6937
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/2854586 Change-Id: I123f70215f47358612cbafbfbb92ae21ddd03fef Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
78ceed67b0
5 changed files with 516 additions and 83 deletions
|
|
@ -55,6 +55,7 @@ class MdnsAnnouncerTest {
|
|||
private val socket = mock(MdnsInterfaceSocket::class.java)
|
||||
private val sharedLog = mock(SharedLog::class.java)
|
||||
private val buffer = ByteArray(1500)
|
||||
private val flags = MdnsFeatureFlags.newBuilder().build()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
|
@ -83,7 +84,7 @@ class MdnsAnnouncerTest {
|
|||
@Test
|
||||
fun testAnnounce() {
|
||||
val replySender = MdnsReplySender(
|
||||
thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */)
|
||||
thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */, flags)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val cb = mock(MdnsPacketRepeater.PacketRepeaterCallback::class.java)
|
||||
as MdnsPacketRepeater.PacketRepeaterCallback<BaseAnnouncementInfo>
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import org.mockito.ArgumentCaptor
|
|||
import org.mockito.Mockito.any
|
||||
import org.mockito.Mockito.anyInt
|
||||
import org.mockito.Mockito.anyString
|
||||
import org.mockito.Mockito.argThat
|
||||
import org.mockito.Mockito.doAnswer
|
||||
import org.mockito.Mockito.doReturn
|
||||
import org.mockito.Mockito.eq
|
||||
|
|
@ -87,7 +88,8 @@ class MdnsInterfaceAdvertiserTest {
|
|||
private val announcer = mock(MdnsAnnouncer::class.java)
|
||||
private val prober = mock(MdnsProber::class.java)
|
||||
private val sharedlog = SharedLog("MdnsInterfaceAdvertiserTest")
|
||||
private val flags = MdnsFeatureFlags.newBuilder().build()
|
||||
private val flags = MdnsFeatureFlags.newBuilder()
|
||||
.setIsKnownAnswerSuppressionEnabled(true).build()
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val probeCbCaptor = ArgumentCaptor.forClass(PacketRepeaterCallback::class.java)
|
||||
as ArgumentCaptor<PacketRepeaterCallback<ProbingInfo>>
|
||||
|
|
@ -118,7 +120,8 @@ class MdnsInterfaceAdvertiserTest {
|
|||
@Before
|
||||
fun setUp() {
|
||||
doReturn(repository).`when`(deps).makeRecordRepository(any(), eq(TEST_HOSTNAME), any())
|
||||
doReturn(replySender).`when`(deps).makeReplySender(anyString(), any(), any(), any(), any())
|
||||
doReturn(replySender).`when`(deps).makeReplySender(
|
||||
anyString(), any(), any(), any(), any(), any())
|
||||
doReturn(announcer).`when`(deps).makeMdnsAnnouncer(anyString(), any(), any(), any(), any())
|
||||
doReturn(prober).`when`(deps).makeMdnsProber(anyString(), any(), any(), any(), any())
|
||||
|
||||
|
|
@ -200,7 +203,8 @@ class MdnsInterfaceAdvertiserTest {
|
|||
fun testReplyToQuery() {
|
||||
addServiceAndFinishProbing(TEST_SERVICE_ID_1, TEST_SERVICE_1)
|
||||
|
||||
val testReply = MdnsReplyInfo(emptyList(), emptyList(), 0, InetSocketAddress(0))
|
||||
val testReply = MdnsReplyInfo(emptyList(), emptyList(), 0, InetSocketAddress(0),
|
||||
InetSocketAddress(0), emptyList())
|
||||
doReturn(testReply).`when`(repository).getReply(any(), any())
|
||||
|
||||
// Query obtained with:
|
||||
|
|
@ -234,6 +238,112 @@ class MdnsInterfaceAdvertiserTest {
|
|||
verify(replySender).queueReply(testReply)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReplyToQuery_TruncatedBitSet() {
|
||||
addServiceAndFinishProbing(TEST_SERVICE_ID_1, TEST_SERVICE_1)
|
||||
val src = InetSocketAddress(parseNumericAddress("2001:db8::456"), MdnsConstants.MDNS_PORT)
|
||||
val testReply = MdnsReplyInfo(emptyList(), emptyList(), 400L, InetSocketAddress(0), src,
|
||||
emptyList())
|
||||
val knownAnswersReply = MdnsReplyInfo(emptyList(), emptyList(), 400L, InetSocketAddress(0),
|
||||
src, emptyList())
|
||||
val knownAnswersReply2 = MdnsReplyInfo(emptyList(), emptyList(), 0L, InetSocketAddress(0),
|
||||
src, emptyList())
|
||||
doReturn(testReply).`when`(repository).getReply(
|
||||
argThat { pkg -> pkg.questions.size != 0 && pkg.answers.size == 0 &&
|
||||
(pkg.flags and MdnsConstants.FLAG_TRUNCATED) != 0},
|
||||
eq(src))
|
||||
doReturn(knownAnswersReply).`when`(repository).getReply(
|
||||
argThat { pkg -> pkg.questions.size == 0 && pkg.answers.size != 0 &&
|
||||
(pkg.flags and MdnsConstants.FLAG_TRUNCATED) != 0},
|
||||
eq(src))
|
||||
doReturn(knownAnswersReply2).`when`(repository).getReply(
|
||||
argThat { pkg -> pkg.questions.size == 0 && pkg.answers.size != 0 &&
|
||||
(pkg.flags and MdnsConstants.FLAG_TRUNCATED) == 0},
|
||||
eq(src))
|
||||
|
||||
// Query obtained with:
|
||||
// scapy.raw(scapy.DNS(
|
||||
// tc = 1, qd = scapy.DNSQR(qtype='PTR', qname='_testservice._tcp.local'))
|
||||
// ).hex().upper()
|
||||
val query = HexDump.hexStringToByteArray(
|
||||
"0000030000010000000000000C5F7465737473657276696365045F746370056C6F63616C00000C0001"
|
||||
)
|
||||
|
||||
packetHandler.handlePacket(query, query.size, src)
|
||||
|
||||
val packetCaptor = ArgumentCaptor.forClass(MdnsPacket::class.java)
|
||||
verify(repository).getReply(packetCaptor.capture(), eq(src))
|
||||
|
||||
packetCaptor.value.let {
|
||||
assertTrue((it.flags and MdnsConstants.FLAG_TRUNCATED) != 0)
|
||||
assertEquals(1, it.questions.size)
|
||||
assertEquals(0, it.answers.size)
|
||||
assertEquals(0, it.authorityRecords.size)
|
||||
assertEquals(0, it.additionalRecords.size)
|
||||
|
||||
assertTrue(it.questions[0] is MdnsPointerRecord)
|
||||
assertContentEquals(arrayOf("_testservice", "_tcp", "local"), it.questions[0].name)
|
||||
}
|
||||
|
||||
verify(replySender).queueReply(testReply)
|
||||
|
||||
// Known-Answer packet with truncated bit set obtained with:
|
||||
// scapy.raw(scapy.DNS(
|
||||
// tc = 1, qd = None, an = scapy.DNSRR(type='PTR', rrname='_testtype._tcp.local',
|
||||
// rdata='othertestservice._testtype._tcp.local', rclass='IN', ttl=4500))
|
||||
// ).hex().upper()
|
||||
val knownAnswers = HexDump.hexStringToByteArray(
|
||||
"000003000000000100000000095F7465737474797065045F746370056C6F63616C00000C0001000" +
|
||||
"011940027106F746865727465737473657276696365095F7465737474797065045F7463" +
|
||||
"70056C6F63616C00"
|
||||
)
|
||||
|
||||
packetHandler.handlePacket(knownAnswers, knownAnswers.size, src)
|
||||
|
||||
verify(repository, times(2)).getReply(packetCaptor.capture(), eq(src))
|
||||
|
||||
packetCaptor.value.let {
|
||||
assertTrue((it.flags and MdnsConstants.FLAG_TRUNCATED) != 0)
|
||||
assertEquals(0, it.questions.size)
|
||||
assertEquals(1, it.answers.size)
|
||||
assertEquals(0, it.authorityRecords.size)
|
||||
assertEquals(0, it.additionalRecords.size)
|
||||
|
||||
assertTrue(it.answers[0] is MdnsPointerRecord)
|
||||
assertContentEquals(arrayOf("_testtype", "_tcp", "local"), it.answers[0].name)
|
||||
}
|
||||
|
||||
verify(replySender).queueReply(knownAnswersReply)
|
||||
|
||||
// Known-Answer packet obtained with:
|
||||
// scapy.raw(scapy.DNS(
|
||||
// qd = None, an = scapy.DNSRR(type='PTR', rrname='_testtype._tcp.local',
|
||||
// rdata='testservice._testtype._tcp.local', rclass='IN', ttl=4500))
|
||||
// ).hex().upper()
|
||||
val knownAnswers2 = HexDump.hexStringToByteArray(
|
||||
"000001000000000100000000095F7465737474797065045F746370056C6F63616C00000C0001000" +
|
||||
"0119400220B7465737473657276696365095F7465737474797065045F746370056C6F63" +
|
||||
"616C00"
|
||||
)
|
||||
|
||||
packetHandler.handlePacket(knownAnswers2, knownAnswers2.size, src)
|
||||
|
||||
verify(repository, times(3)).getReply(packetCaptor.capture(), eq(src))
|
||||
|
||||
packetCaptor.value.let {
|
||||
assertTrue((it.flags and MdnsConstants.FLAG_TRUNCATED) == 0)
|
||||
assertEquals(0, it.questions.size)
|
||||
assertEquals(1, it.answers.size)
|
||||
assertEquals(0, it.authorityRecords.size)
|
||||
assertEquals(0, it.additionalRecords.size)
|
||||
|
||||
assertTrue(it.answers[0] is MdnsPointerRecord)
|
||||
assertContentEquals(arrayOf("_testtype", "_tcp", "local"), it.answers[0].name)
|
||||
}
|
||||
|
||||
verify(replySender).queueReply(knownAnswersReply2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testConflict() {
|
||||
addServiceAndFinishProbing(TEST_SERVICE_ID_1, TEST_SERVICE_1)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ class MdnsProberTest {
|
|||
private val cb = mock(MdnsPacketRepeater.PacketRepeaterCallback::class.java)
|
||||
as MdnsPacketRepeater.PacketRepeaterCallback<ProbingInfo>
|
||||
private val buffer = ByteArray(1500)
|
||||
private val flags = MdnsFeatureFlags.newBuilder().build()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
|
@ -120,7 +121,7 @@ class MdnsProberTest {
|
|||
@Test
|
||||
fun testProbe() {
|
||||
val replySender = MdnsReplySender(
|
||||
thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */)
|
||||
thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */, flags)
|
||||
val prober = TestProber(thread.looper, replySender, cb, sharedLog)
|
||||
val probeInfo = TestProbeInfo(
|
||||
listOf(makeServiceRecord(TEST_SERVICE_NAME_1, 37890)))
|
||||
|
|
@ -145,7 +146,7 @@ class MdnsProberTest {
|
|||
@Test
|
||||
fun testProbeMultipleRecords() {
|
||||
val replySender = MdnsReplySender(
|
||||
thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */)
|
||||
thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */, flags)
|
||||
val prober = TestProber(thread.looper, replySender, cb, sharedLog)
|
||||
val probeInfo = TestProbeInfo(listOf(
|
||||
makeServiceRecord(TEST_SERVICE_NAME_1, 37890),
|
||||
|
|
@ -184,7 +185,7 @@ class MdnsProberTest {
|
|||
@Test
|
||||
fun testStopProbing() {
|
||||
val replySender = MdnsReplySender(
|
||||
thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */)
|
||||
thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */, flags)
|
||||
val prober = TestProber(thread.looper, replySender, cb, sharedLog)
|
||||
val probeInfo = TestProbeInfo(
|
||||
listOf(makeServiceRecord(TEST_SERVICE_NAME_1, 37890)),
|
||||
|
|
|
|||
|
|
@ -175,8 +175,8 @@ class MdnsRecordRepositoryTest {
|
|||
|
||||
val queriedName = arrayOf(TEST_SUBTYPE, "_sub", "_testservice", "_tcp", "local")
|
||||
val questions = listOf(MdnsPointerRecord(queriedName, false /* isUnicast */))
|
||||
val query = MdnsPacket(0 /* flags */, questions, listOf() /* answers */,
|
||||
listOf() /* authorityRecords */, listOf() /* additionalRecords */)
|
||||
val query = MdnsPacket(0 /* flags */, questions, emptyList() /* answers */,
|
||||
emptyList() /* authorityRecords */, emptyList() /* additionalRecords */)
|
||||
val src = InetSocketAddress(parseNumericAddress("192.0.2.123"), 5353)
|
||||
val reply = repository.getReply(query, src)
|
||||
|
||||
|
|
@ -510,8 +510,8 @@ class MdnsRecordRepositoryTest {
|
|||
val questionsCaseInSensitive = listOf(
|
||||
MdnsPointerRecord(arrayOf("_TESTSERVICE", "_TCP", "local"), false /* isUnicast */))
|
||||
val queryCaseInsensitive = MdnsPacket(0 /* flags */, questionsCaseInSensitive,
|
||||
listOf() /* answers */, listOf() /* authorityRecords */,
|
||||
listOf() /* additionalRecords */)
|
||||
emptyList() /* answers */, emptyList() /* authorityRecords */,
|
||||
emptyList() /* additionalRecords */)
|
||||
val src = InetSocketAddress(parseNumericAddress("192.0.2.123"), 5353)
|
||||
val replyCaseInsensitive = repository.getReply(queryCaseInsensitive, src)
|
||||
assertNotNull(replyCaseInsensitive)
|
||||
|
|
@ -524,8 +524,8 @@ class MdnsRecordRepositoryTest {
|
|||
*/
|
||||
private fun makeQuery(vararg queries: Pair<Int, Array<String>>): MdnsPacket {
|
||||
val questions = queries.map { (type, name) -> makeQuestionRecord(name, type) }
|
||||
return MdnsPacket(0 /* flags */, questions, listOf() /* answers */,
|
||||
listOf() /* authorityRecords */, listOf() /* additionalRecords */)
|
||||
return MdnsPacket(0 /* flags */, questions, emptyList() /* answers */,
|
||||
emptyList() /* authorityRecords */, emptyList() /* additionalRecords */)
|
||||
}
|
||||
|
||||
private fun makeQuestionRecord(name: Array<String>, type: Int): MdnsRecord {
|
||||
|
|
@ -554,7 +554,7 @@ class MdnsRecordRepositoryTest {
|
|||
arrayOf("_testservice", "_tcp", "local"), 0L, false, LONG_TTL, serviceName)),
|
||||
reply.answers)
|
||||
assertEquals(listOf(
|
||||
MdnsTextRecord(serviceName, 0L, true, LONG_TTL, listOf()),
|
||||
MdnsTextRecord(serviceName, 0L, true, LONG_TTL, emptyList()),
|
||||
MdnsServiceRecord(serviceName, 0L, true, SHORT_TTL, 0, 0, TEST_PORT, TEST_HOSTNAME),
|
||||
MdnsInetAddressRecord(
|
||||
TEST_HOSTNAME, 0L, true, SHORT_TTL, TEST_ADDRESSES[0].address),
|
||||
|
|
@ -587,7 +587,7 @@ class MdnsRecordRepositoryTest {
|
|||
LONG_TTL, serviceName)),
|
||||
reply.answers)
|
||||
assertEquals(listOf(
|
||||
MdnsTextRecord(serviceName, 0L, true, LONG_TTL, listOf()),
|
||||
MdnsTextRecord(serviceName, 0L, true, LONG_TTL, emptyList()),
|
||||
MdnsServiceRecord(serviceName, 0L, true, SHORT_TTL, 0, 0, TEST_PORT, TEST_HOSTNAME),
|
||||
MdnsInetAddressRecord(
|
||||
TEST_HOSTNAME, 0L, true, SHORT_TTL, TEST_ADDRESSES[0].address),
|
||||
|
|
@ -620,7 +620,7 @@ class MdnsRecordRepositoryTest {
|
|||
arrayOf("_testservice", "_tcp", "local"), 0L, false, LONG_TTL, serviceName)),
|
||||
reply.answers)
|
||||
assertEquals(listOf(
|
||||
MdnsTextRecord(serviceName, 0L, true, LONG_TTL, listOf()),
|
||||
MdnsTextRecord(serviceName, 0L, true, LONG_TTL, emptyList()),
|
||||
MdnsServiceRecord(serviceName, 0L, true, SHORT_TTL, 0, 0, TEST_PORT, TEST_HOSTNAME),
|
||||
MdnsInetAddressRecord(
|
||||
TEST_HOSTNAME, 0L, true, SHORT_TTL, TEST_ADDRESSES[0].address),
|
||||
|
|
@ -656,7 +656,7 @@ class MdnsRecordRepositoryTest {
|
|||
0L, false, LONG_TTL, serviceName)),
|
||||
reply.answers)
|
||||
assertEquals(listOf(
|
||||
MdnsTextRecord(serviceName, 0L, true, LONG_TTL, listOf()),
|
||||
MdnsTextRecord(serviceName, 0L, true, LONG_TTL, emptyList()),
|
||||
MdnsServiceRecord(serviceName, 0L, true, SHORT_TTL, 0, 0, TEST_PORT, TEST_HOSTNAME),
|
||||
MdnsInetAddressRecord(
|
||||
TEST_HOSTNAME, 0L, true, SHORT_TTL, TEST_ADDRESSES[0].address),
|
||||
|
|
@ -682,7 +682,7 @@ class MdnsRecordRepositoryTest {
|
|||
val reply = repository.getReply(query, src)
|
||||
|
||||
assertNotNull(reply)
|
||||
assertEquals(listOf(MdnsTextRecord(serviceName, 0L, true, LONG_TTL, listOf())),
|
||||
assertEquals(listOf(MdnsTextRecord(serviceName, 0L, true, LONG_TTL, emptyList())),
|
||||
reply.answers)
|
||||
// No NSEC records because the reply doesn't include the SRV record
|
||||
assertTrue(reply.additionalAnswers.isEmpty())
|
||||
|
|
@ -747,7 +747,7 @@ class MdnsRecordRepositoryTest {
|
|||
assertNotNull(reply)
|
||||
assertEquals(listOf(
|
||||
MdnsServiceRecord(serviceName, 0L, true, SHORT_TTL, 0, 0, TEST_PORT, TEST_HOSTNAME),
|
||||
MdnsTextRecord(serviceName, 0L, true, LONG_TTL, listOf()),
|
||||
MdnsTextRecord(serviceName, 0L, true, LONG_TTL, emptyList()),
|
||||
MdnsInetAddressRecord(
|
||||
TEST_HOSTNAME, 0L, true, SHORT_TTL, TEST_ADDRESSES[0].address),
|
||||
MdnsInetAddressRecord(
|
||||
|
|
@ -915,8 +915,8 @@ class MdnsRecordRepositoryTest {
|
|||
|
||||
val questions = listOf(
|
||||
MdnsPointerRecord(arrayOf("_testservice", "_tcp", "local"), false /* isUnicast */))
|
||||
val query = MdnsPacket(0 /* flags */, questions, listOf() /* answers */,
|
||||
listOf() /* authorityRecords */, listOf() /* additionalRecords */)
|
||||
val query = MdnsPacket(0 /* flags */, questions, emptyList() /* answers */,
|
||||
emptyList() /* authorityRecords */, emptyList() /* additionalRecords */)
|
||||
val src = InetSocketAddress(parseNumericAddress("192.0.2.123"), 5353)
|
||||
|
||||
// Reply to the question and verify there is one packet replied.
|
||||
|
|
@ -994,18 +994,17 @@ class MdnsRecordRepositoryTest {
|
|||
questions: List<MdnsRecord>,
|
||||
knownAnswers: List<MdnsRecord>,
|
||||
replyAnswers: List<MdnsRecord>,
|
||||
additionalAnswers: List<MdnsRecord>,
|
||||
expectReply: Boolean
|
||||
additionalAnswers: List<MdnsRecord>
|
||||
) {
|
||||
val repository = MdnsRecordRepository(thread.looper, deps, TEST_HOSTNAME,
|
||||
makeFlags(isKnownAnswerSuppressionEnabled = true))
|
||||
repository.initWithService(TEST_SERVICE_ID_1, TEST_SERVICE_1)
|
||||
val query = MdnsPacket(0 /* flags */, questions, knownAnswers,
|
||||
listOf() /* authorityRecords */, listOf() /* additionalRecords */)
|
||||
emptyList() /* authorityRecords */, emptyList() /* additionalRecords */)
|
||||
val src = InetSocketAddress(parseNumericAddress("192.0.2.123"), 5353)
|
||||
val reply = repository.getReply(query, src)
|
||||
|
||||
if (!expectReply) {
|
||||
if (replyAnswers.isEmpty() || additionalAnswers.isEmpty()) {
|
||||
assertNull(reply)
|
||||
return
|
||||
}
|
||||
|
|
@ -1016,6 +1015,7 @@ class MdnsRecordRepositoryTest {
|
|||
assertEquals(MdnsConstants.MDNS_PORT, reply.destination.port)
|
||||
assertEquals(replyAnswers, reply.answers)
|
||||
assertEquals(additionalAnswers, reply.additionalAnswers)
|
||||
assertEquals(knownAnswers, reply.knownAnswers)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -1028,8 +1028,8 @@ class MdnsRecordRepositoryTest {
|
|||
false /* cacheFlush */,
|
||||
LONG_TTL,
|
||||
arrayOf("MyTestService", "_testservice", "_tcp", "local")))
|
||||
doGetReplyWithAnswersTest(questions, knownAnswers, listOf() /* replyAnswers */,
|
||||
listOf() /* additionalAnswers */, false /* expectReply */)
|
||||
doGetReplyWithAnswersTest(questions, knownAnswers, emptyList() /* replyAnswers */,
|
||||
emptyList() /* additionalAnswers */)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -1055,7 +1055,7 @@ class MdnsRecordRepositoryTest {
|
|||
0L /* receiptTimeMillis */,
|
||||
true /* cacheFlush */,
|
||||
LONG_TTL,
|
||||
listOf() /* entries */),
|
||||
emptyList() /* entries */),
|
||||
MdnsServiceRecord(
|
||||
serviceName,
|
||||
0L /* receiptTimeMillis */,
|
||||
|
|
@ -1097,8 +1097,7 @@ class MdnsRecordRepositoryTest {
|
|||
SHORT_TTL,
|
||||
TEST_HOSTNAME /* nextDomain */,
|
||||
intArrayOf(MdnsRecord.TYPE_A, MdnsRecord.TYPE_AAAA)))
|
||||
doGetReplyWithAnswersTest(questions, knownAnswers, replyAnswers, additionalAnswers,
|
||||
true /* expectReply */)
|
||||
doGetReplyWithAnswersTest(questions, knownAnswers, replyAnswers, additionalAnswers)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -1124,7 +1123,7 @@ class MdnsRecordRepositoryTest {
|
|||
0L /* receiptTimeMillis */,
|
||||
true /* cacheFlush */,
|
||||
LONG_TTL,
|
||||
listOf() /* entries */),
|
||||
emptyList() /* entries */),
|
||||
MdnsServiceRecord(
|
||||
serviceName,
|
||||
0L /* receiptTimeMillis */,
|
||||
|
|
@ -1166,8 +1165,7 @@ class MdnsRecordRepositoryTest {
|
|||
SHORT_TTL,
|
||||
TEST_HOSTNAME /* nextDomain */,
|
||||
intArrayOf(MdnsRecord.TYPE_A, MdnsRecord.TYPE_AAAA)))
|
||||
doGetReplyWithAnswersTest(questions, knownAnswers, replyAnswers, additionalAnswers,
|
||||
true /* expectReply */)
|
||||
doGetReplyWithAnswersTest(questions, knownAnswers, replyAnswers, additionalAnswers)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -1218,8 +1216,7 @@ class MdnsRecordRepositoryTest {
|
|||
SHORT_TTL,
|
||||
TEST_HOSTNAME /* nextDomain */,
|
||||
intArrayOf(MdnsRecord.TYPE_A, MdnsRecord.TYPE_AAAA)))
|
||||
doGetReplyWithAnswersTest(questions, knownAnswers, replyAnswers, additionalAnswers,
|
||||
true /* expectReply */)
|
||||
doGetReplyWithAnswersTest(questions, knownAnswers, replyAnswers, additionalAnswers)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -1248,10 +1245,8 @@ class MdnsRecordRepositoryTest {
|
|||
TEST_HOSTNAME
|
||||
)
|
||||
)
|
||||
doGetReplyWithAnswersTest(
|
||||
questions, knownAnswers, listOf() /* replyAnswers */,
|
||||
listOf() /* additionalAnswers */, false /* expectReply */
|
||||
)
|
||||
doGetReplyWithAnswersTest(questions, knownAnswers, emptyList() /* replyAnswers */,
|
||||
emptyList() /* additionalAnswers */)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -1263,8 +1258,8 @@ class MdnsRecordRepositoryTest {
|
|||
val questions = listOf(
|
||||
MdnsPointerRecord(arrayOf("_testservice", "_tcp", "local"), true /* isUnicast */),
|
||||
MdnsPointerRecord(arrayOf("_otherservice", "_tcp", "local"), true /* isUnicast */))
|
||||
val query = MdnsPacket(0 /* flags */, questions, listOf() /* answers */,
|
||||
listOf() /* authorityRecords */, listOf() /* additionalRecords */)
|
||||
val query = MdnsPacket(0 /* flags */, questions, emptyList() /* answers */,
|
||||
emptyList() /* authorityRecords */, emptyList() /* additionalRecords */)
|
||||
val src = InetSocketAddress(parseNumericAddress("2001:db8::123"), 5353)
|
||||
|
||||
// Reply to the question and verify it is sent to the source.
|
||||
|
|
@ -1287,8 +1282,8 @@ class MdnsRecordRepositoryTest {
|
|||
val questions = listOf(
|
||||
MdnsPointerRecord(arrayOf("_testservice", "_tcp", "local"), true /* isUnicast */),
|
||||
MdnsPointerRecord(arrayOf("_otherservice", "_tcp", "local"), false /* isUnicast */))
|
||||
val query = MdnsPacket(0 /* flags */, questions, listOf() /* answers */,
|
||||
listOf() /* authorityRecords */, listOf() /* additionalRecords */)
|
||||
val query = MdnsPacket(0 /* flags */, questions, emptyList() /* answers */,
|
||||
emptyList() /* authorityRecords */, emptyList() /* additionalRecords */)
|
||||
val src = InetSocketAddress(parseNumericAddress("2001:db8::123"), 5353)
|
||||
|
||||
// Reply to the question and verify it is sent multicast.
|
||||
|
|
@ -1306,8 +1301,8 @@ class MdnsRecordRepositoryTest {
|
|||
val questions = listOf(
|
||||
MdnsPointerRecord(arrayOf("_otherservice", "_tcp", "local"), true /* isUnicast */),
|
||||
MdnsPointerRecord(arrayOf("_testservice", "_tcp", "local"), false /* isUnicast */))
|
||||
val query = MdnsPacket(0 /* flags */, questions, listOf() /* answers */,
|
||||
listOf() /* authorityRecords */, listOf() /* additionalRecords */)
|
||||
val query = MdnsPacket(0 /* flags */, questions, emptyList() /* answers */,
|
||||
emptyList() /* authorityRecords */, emptyList() /* additionalRecords */)
|
||||
val src = InetSocketAddress(parseNumericAddress("2001:db8::123"), 5353)
|
||||
|
||||
// Reply to the question and verify it is sent multicast.
|
||||
|
|
@ -1325,8 +1320,8 @@ class MdnsRecordRepositoryTest {
|
|||
// The service is known and requests unicast reply, but the feature is disabled
|
||||
val questions = listOf(
|
||||
MdnsPointerRecord(arrayOf("_testservice", "_tcp", "local"), true /* isUnicast */))
|
||||
val query = MdnsPacket(0 /* flags */, questions, listOf() /* answers */,
|
||||
listOf() /* authorityRecords */, listOf() /* additionalRecords */)
|
||||
val query = MdnsPacket(0 /* flags */, questions, emptyList() /* answers */,
|
||||
emptyList() /* authorityRecords */, emptyList() /* additionalRecords */)
|
||||
val src = InetSocketAddress(parseNumericAddress("2001:db8::123"), 5353)
|
||||
|
||||
// Reply to the question and verify it is sent multicast.
|
||||
|
|
@ -1334,6 +1329,28 @@ class MdnsRecordRepositoryTest {
|
|||
assertNotNull(reply)
|
||||
assertEquals(MdnsConstants.getMdnsIPv6Address(), reply.destination.address)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetReply_OnlyKnownAnswers() {
|
||||
val repository = MdnsRecordRepository(thread.looper, deps, TEST_HOSTNAME,
|
||||
makeFlags(isKnownAnswerSuppressionEnabled = true))
|
||||
repository.initWithService(TEST_SERVICE_ID_1, TEST_SERVICE_1)
|
||||
val knownAnswers = listOf(MdnsPointerRecord(
|
||||
arrayOf("_testservice", "_tcp", "local"),
|
||||
0L /* receiptTimeMillis */,
|
||||
false /* cacheFlush */,
|
||||
LONG_TTL - 1000L,
|
||||
arrayOf("MyTestService", "_testservice", "_tcp", "local")))
|
||||
val query = MdnsPacket(MdnsConstants.FLAG_TRUNCATED /* flags */, emptyList(),
|
||||
knownAnswers, emptyList() /* authorityRecords */,
|
||||
emptyList() /* additionalRecords */)
|
||||
val src = InetSocketAddress(parseNumericAddress("192.0.2.123"), 5353)
|
||||
val reply = repository.getReply(query, src)
|
||||
assertNotNull(reply)
|
||||
assertEquals(0, reply.answers.size)
|
||||
assertEquals(0, reply.additionalAnswers.size)
|
||||
assertEquals(knownAnswers, reply.knownAnswers)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MdnsRecordRepository.initWithService(
|
||||
|
|
|
|||
|
|
@ -24,21 +24,28 @@ import android.os.HandlerThread
|
|||
import android.os.Message
|
||||
import com.android.net.module.util.SharedLog
|
||||
import com.android.server.connectivity.mdns.MdnsConstants.IPV4_SOCKET_ADDR
|
||||
import com.android.server.connectivity.mdns.MdnsConstants.IPV6_SOCKET_ADDR
|
||||
import com.android.server.connectivity.mdns.MdnsReplySender.getReplyDestination
|
||||
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
|
||||
import com.android.testutils.DevSdkIgnoreRunner
|
||||
import java.net.DatagramPacket
|
||||
import java.net.InetSocketAddress
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.test.assertEquals
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.Mockito.any
|
||||
import org.mockito.Mockito.anyLong
|
||||
import org.mockito.Mockito.argThat
|
||||
import org.mockito.Mockito.doReturn
|
||||
import org.mockito.Mockito.eq
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.timeout
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
|
||||
private const val TEST_PORT = 12345
|
||||
|
|
@ -50,8 +57,12 @@ private const val SHORT_TTL = 120_000L
|
|||
@IgnoreUpTo(Build.VERSION_CODES.S_V2)
|
||||
class MdnsReplySenderTest {
|
||||
private val serviceName = arrayOf("MyTestService", "_testservice", "_tcp", "local")
|
||||
private val otherServiceName = arrayOf("OtherTestService", "_testservice", "_tcp", "local")
|
||||
private val serviceType = arrayOf("_testservice", "_tcp", "local")
|
||||
private val source = InetSocketAddress(
|
||||
InetAddresses.parseNumericAddress("192.0.2.1"), TEST_PORT)
|
||||
private val hostname = arrayOf("Android_000102030405060708090A0B0C0D0E0F", "local")
|
||||
private val otherHostname = arrayOf("Android_0F0E0D0C0B0A09080706050403020100", "local")
|
||||
private val hostAddresses = listOf(
|
||||
LinkAddress(InetAddresses.parseNumericAddress("192.0.2.111"), 24),
|
||||
LinkAddress(InetAddresses.parseNumericAddress("2001:db8::111"), 64),
|
||||
|
|
@ -59,9 +70,12 @@ class MdnsReplySenderTest {
|
|||
private val answers = listOf(
|
||||
MdnsPointerRecord(serviceType, 0L /* receiptTimeMillis */, false /* cacheFlush */,
|
||||
LONG_TTL, serviceName))
|
||||
private val otherAnswers = listOf(
|
||||
MdnsPointerRecord(serviceType, 0L /* receiptTimeMillis */, false /* cacheFlush */,
|
||||
LONG_TTL, otherServiceName))
|
||||
private val additionalAnswers = listOf(
|
||||
MdnsTextRecord(serviceName, 0L /* receiptTimeMillis */, true /* cacheFlush */, LONG_TTL,
|
||||
listOf() /* entries */),
|
||||
emptyList() /* entries */),
|
||||
MdnsServiceRecord(serviceName, 0L /* receiptTimeMillis */, true /* cacheFlush */,
|
||||
SHORT_TTL, 0 /* servicePriority */, 0 /* serviceWeight */, TEST_PORT, hostname),
|
||||
MdnsInetAddressRecord(hostname, 0L /* receiptTimeMillis */, true /* cacheFlush */,
|
||||
|
|
@ -75,15 +89,30 @@ class MdnsReplySenderTest {
|
|||
intArrayOf(MdnsRecord.TYPE_TXT, MdnsRecord.TYPE_SRV)),
|
||||
MdnsNsecRecord(hostname, 0L /* receiptTimeMillis */, true /* cacheFlush */, SHORT_TTL,
|
||||
hostname /* nextDomain */, intArrayOf(MdnsRecord.TYPE_A, MdnsRecord.TYPE_AAAA)))
|
||||
private val otherAdditionalAnswers = listOf(
|
||||
MdnsTextRecord(otherServiceName, 0L /* receiptTimeMillis */, true /* cacheFlush */,
|
||||
LONG_TTL, emptyList() /* entries */),
|
||||
MdnsServiceRecord(otherServiceName, 0L /* receiptTimeMillis */, true /* cacheFlush */,
|
||||
SHORT_TTL, 0 /* servicePriority */, 0 /* serviceWeight */, TEST_PORT,
|
||||
otherHostname),
|
||||
MdnsInetAddressRecord(otherHostname, 0L /* receiptTimeMillis */, true /* cacheFlush */,
|
||||
SHORT_TTL, hostAddresses[0].address),
|
||||
MdnsInetAddressRecord(otherHostname, 0L /* receiptTimeMillis */, true /* cacheFlush */,
|
||||
SHORT_TTL, hostAddresses[1].address),
|
||||
MdnsInetAddressRecord(otherHostname, 0L /* receiptTimeMillis */, true /* cacheFlush */,
|
||||
SHORT_TTL, hostAddresses[2].address),
|
||||
MdnsNsecRecord(otherServiceName, 0L /* receiptTimeMillis */, true /* cacheFlush */,
|
||||
LONG_TTL, otherServiceName /* nextDomain */,
|
||||
intArrayOf(MdnsRecord.TYPE_TXT, MdnsRecord.TYPE_SRV)),
|
||||
MdnsNsecRecord(otherHostname, 0L /* receiptTimeMillis */, true /* cacheFlush */,
|
||||
SHORT_TTL, otherHostname /* nextDomain */,
|
||||
intArrayOf(MdnsRecord.TYPE_A, MdnsRecord.TYPE_AAAA)))
|
||||
private val thread = HandlerThread(MdnsReplySenderTest::class.simpleName)
|
||||
private val socket = mock(MdnsInterfaceSocket::class.java)
|
||||
private val buffer = ByteArray(1500)
|
||||
private val sharedLog = SharedLog(MdnsReplySenderTest::class.simpleName)
|
||||
private val deps = mock(MdnsReplySender.Dependencies::class.java)
|
||||
private val handler by lazy { Handler(thread.looper) }
|
||||
private val replySender by lazy {
|
||||
MdnsReplySender(thread.looper, socket, buffer, sharedLog, false /* enableDebugLog */, deps)
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
|
@ -106,37 +135,180 @@ class MdnsReplySenderTest {
|
|||
return future.get(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS)
|
||||
}
|
||||
|
||||
private fun sendNow(packet: MdnsPacket, destination: InetSocketAddress):
|
||||
Unit = runningOnHandlerAndReturn { replySender.sendNow(packet, destination) }
|
||||
private fun sendNow(sender: MdnsReplySender, packet: MdnsPacket, dest: InetSocketAddress):
|
||||
Unit = runningOnHandlerAndReturn { sender.sendNow(packet, dest) }
|
||||
|
||||
private fun queueReply(reply: MdnsReplyInfo):
|
||||
Unit = runningOnHandlerAndReturn { replySender.queueReply(reply) }
|
||||
private fun queueReply(sender: MdnsReplySender, reply: MdnsReplyInfo):
|
||||
Unit = runningOnHandlerAndReturn { sender.queueReply(reply) }
|
||||
|
||||
private fun buildFlags(enableKAS: Boolean): MdnsFeatureFlags {
|
||||
return MdnsFeatureFlags.newBuilder()
|
||||
.setIsKnownAnswerSuppressionEnabled(enableKAS).build()
|
||||
}
|
||||
|
||||
private fun createSender(enableKAS: Boolean): MdnsReplySender =
|
||||
MdnsReplySender(thread.looper, socket, buffer, sharedLog, false /* enableDebugLog */,
|
||||
deps, buildFlags(enableKAS))
|
||||
|
||||
@Test
|
||||
fun testSendNow() {
|
||||
val replySender = createSender(enableKAS = false)
|
||||
val packet = MdnsPacket(0x8400,
|
||||
listOf() /* questions */,
|
||||
emptyList() /* questions */,
|
||||
answers,
|
||||
listOf() /* authorityRecords */,
|
||||
emptyList() /* authorityRecords */,
|
||||
additionalAnswers)
|
||||
sendNow(packet, IPV4_SOCKET_ADDR)
|
||||
sendNow(replySender, packet, IPV4_SOCKET_ADDR)
|
||||
verify(socket).send(argThat{ it.socketAddress.equals(IPV4_SOCKET_ADDR) })
|
||||
}
|
||||
|
||||
private fun verifyMessageQueued(
|
||||
sender: MdnsReplySender,
|
||||
replies: List<MdnsReplyInfo>
|
||||
): Pair<Handler, Message> {
|
||||
val handlerCaptor = ArgumentCaptor.forClass(Handler::class.java)
|
||||
val messageCaptor = ArgumentCaptor.forClass(Message::class.java)
|
||||
for (reply in replies) {
|
||||
queueReply(sender, reply)
|
||||
verify(deps).sendMessageDelayed(
|
||||
handlerCaptor.capture(), messageCaptor.capture(), eq(reply.sendDelayMs))
|
||||
}
|
||||
return Pair(handlerCaptor.value, messageCaptor.value)
|
||||
}
|
||||
|
||||
private fun verifyReplySent(
|
||||
realHandler: Handler,
|
||||
delayMessage: Message,
|
||||
remainingAnswers: List<MdnsRecord>
|
||||
) {
|
||||
val datagramPacketCaptor = ArgumentCaptor.forClass(DatagramPacket::class.java)
|
||||
realHandler.sendMessage(delayMessage)
|
||||
verify(socket, timeout(DEFAULT_TIMEOUT_MS)).send(datagramPacketCaptor.capture())
|
||||
|
||||
val dPacket = datagramPacketCaptor.value
|
||||
val mdnsPacket = MdnsPacket.parse(MdnsPacketReader(
|
||||
dPacket.data, dPacket.length, buildFlags(enableKAS = false)))
|
||||
assertEquals(mdnsPacket.answers.toSet(), remainingAnswers.toSet())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testQueueReply() {
|
||||
val replySender = createSender(enableKAS = false)
|
||||
val reply = MdnsReplyInfo(answers, additionalAnswers, 20L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR)
|
||||
val handlerCaptor = ArgumentCaptor.forClass(Handler::class.java)
|
||||
val messageCaptor = ArgumentCaptor.forClass(Message::class.java)
|
||||
queueReply(reply)
|
||||
verify(deps).sendMessageDelayed(handlerCaptor.capture(), messageCaptor.capture(), eq(20L))
|
||||
IPV4_SOCKET_ADDR, source, emptyList())
|
||||
val (handler, message) = verifyMessageQueued(replySender, listOf(reply))
|
||||
verifyReplySent(handler, message, answers)
|
||||
}
|
||||
|
||||
val realHandler = handlerCaptor.value
|
||||
val delayMessage = messageCaptor.value
|
||||
realHandler.sendMessage(delayMessage)
|
||||
verify(socket, timeout(DEFAULT_TIMEOUT_MS)).send(argThat{
|
||||
it.socketAddress.equals(IPV4_SOCKET_ADDR)
|
||||
})
|
||||
@Test
|
||||
fun testQueueReply_KnownAnswerSuppressionEnabled() {
|
||||
val replySender = createSender(enableKAS = true)
|
||||
val reply = MdnsReplyInfo(answers, additionalAnswers, 20L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, emptyList())
|
||||
val (handler, message) = verifyMessageQueued(replySender, listOf(reply))
|
||||
verifyReplySent(handler, message, answers)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testQueueReply_MultiplePacket() {
|
||||
val replySender = createSender(enableKAS = true)
|
||||
val reply = MdnsReplyInfo(answers, additionalAnswers, 400L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, emptyList())
|
||||
verifyMessageQueued(replySender, listOf(reply))
|
||||
|
||||
// Receive a known-answer packet and verify no message queued.
|
||||
val knownAnswersReply = MdnsReplyInfo(emptyList(), emptyList(), 0L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, answers)
|
||||
queueReply(replySender, knownAnswersReply)
|
||||
verify(deps, times(1)).sendMessageDelayed(any(), any(), anyLong())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testQueueReply_MultiplePacket_LostSubsequentPacket() {
|
||||
val replySender = createSender(enableKAS = true)
|
||||
val reply = MdnsReplyInfo(answers, additionalAnswers, 400L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, emptyList())
|
||||
val (handler, message) = verifyMessageQueued(replySender, listOf(reply))
|
||||
|
||||
// No subsequent packets
|
||||
verifyReplySent(handler, message, answers)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testQueueReply_MultiplePacket_OtherKnownAnswer() {
|
||||
val replySender = createSender(enableKAS = true)
|
||||
val reply = MdnsReplyInfo(answers, additionalAnswers, 400L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, emptyList())
|
||||
// Other known-answer service
|
||||
val otherKnownAnswersReply = MdnsReplyInfo(emptyList(), emptyList(), 0L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, otherAnswers)
|
||||
val (handler, message) = verifyMessageQueued(
|
||||
replySender, listOf(reply, otherKnownAnswersReply))
|
||||
verifyReplySent(handler, message, answers)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testQueueReply_MultiplePacket_TwoKnownAnswerPackets() {
|
||||
val replySender = createSender(enableKAS = true)
|
||||
val reply = MdnsReplyInfo(answers, additionalAnswers, 400L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, emptyList())
|
||||
val firstKnownAnswerReply = MdnsReplyInfo(emptyList(), emptyList(), 401L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, otherAnswers)
|
||||
verifyMessageQueued(replySender, listOf(reply, firstKnownAnswerReply))
|
||||
|
||||
// Second known-answer service
|
||||
val secondKnownAnswerReply = MdnsReplyInfo(emptyList(), emptyList(), 0L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, answers)
|
||||
queueReply(replySender, secondKnownAnswerReply)
|
||||
|
||||
// Verify that no reply is queued, as all answers are known.
|
||||
verify(deps, times(2)).sendMessageDelayed(any(), any(), anyLong())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testQueueReply_MultiplePacket_LostSecondaryPacket() {
|
||||
val replySender = createSender(enableKAS = true)
|
||||
val reply = MdnsReplyInfo(answers, additionalAnswers, 400L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, emptyList())
|
||||
val firstKnownAnswerReply = MdnsReplyInfo(emptyList(), emptyList(), 401L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, otherAnswers)
|
||||
val (handler, message) = verifyMessageQueued(
|
||||
replySender, listOf(reply, firstKnownAnswerReply))
|
||||
|
||||
// Second known-answer service lost
|
||||
verifyReplySent(handler, message, answers)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testQueueReply_MultiplePacket_WithMultipleQuestions() {
|
||||
val replySender = createSender(enableKAS = true)
|
||||
val twoAnswers = listOf(
|
||||
MdnsPointerRecord(serviceType, 0L /* receiptTimeMillis */, false /* cacheFlush */,
|
||||
LONG_TTL, serviceName),
|
||||
MdnsServiceRecord(otherServiceName, 0L /* receiptTimeMillis */,
|
||||
true /* cacheFlush */, SHORT_TTL, 0 /* servicePriority */,
|
||||
0 /* serviceWeight */, TEST_PORT, otherHostname))
|
||||
val reply = MdnsReplyInfo(twoAnswers, additionalAnswers, 400L /* sendDelayMs */,
|
||||
IPV4_SOCKET_ADDR, source, emptyList())
|
||||
val knownAnswersReply = MdnsReplyInfo(otherAnswers, otherAdditionalAnswers,
|
||||
20L /* sendDelayMs */, IPV4_SOCKET_ADDR, source, answers)
|
||||
val (handler, message) = verifyMessageQueued(replySender, listOf(reply, knownAnswersReply))
|
||||
|
||||
val remainingAnswers = listOf(
|
||||
MdnsPointerRecord(serviceType, 0L /* receiptTimeMillis */, false /* cacheFlush */,
|
||||
LONG_TTL, otherServiceName),
|
||||
MdnsServiceRecord(otherServiceName, 0L /* receiptTimeMillis */,
|
||||
true /* cacheFlush */, SHORT_TTL, 0 /* servicePriority */,
|
||||
0 /* serviceWeight */, TEST_PORT, otherHostname))
|
||||
verifyReplySent(handler, message, remainingAnswers)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetReplyDestination() {
|
||||
assertEquals(IPV4_SOCKET_ADDR, getReplyDestination(IPV4_SOCKET_ADDR, IPV4_SOCKET_ADDR))
|
||||
assertEquals(IPV6_SOCKET_ADDR, getReplyDestination(IPV6_SOCKET_ADDR, IPV6_SOCKET_ADDR))
|
||||
assertEquals(IPV4_SOCKET_ADDR, getReplyDestination(source, IPV4_SOCKET_ADDR))
|
||||
assertEquals(IPV6_SOCKET_ADDR, getReplyDestination(source, IPV6_SOCKET_ADDR))
|
||||
assertEquals(source, getReplyDestination(source, source))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue