Merge "Implement conflict detection"

This commit is contained in:
Remi NGUYEN VAN
2023-01-20 06:00:54 +00:00
committed by Gerrit Code Review
5 changed files with 211 additions and 5 deletions

View File

@@ -203,6 +203,59 @@ class MdnsInterfaceAdvertiserTest {
verify(replySender).queueReply(mockReply)
}
@Test
fun testConflict() {
addServiceAndFinishProbing(TEST_SERVICE_ID_1, TEST_SERVICE_1)
doReturn(setOf(TEST_SERVICE_ID_1)).`when`(repository).getConflictingServices(any())
// Reply obtained with:
// scapy.raw(scapy.DNS(
// qd = None,
// an = scapy.DNSRR(type='TXT', rrname='_testservice._tcp.local'))
// ).hex().upper()
val query = HexDump.hexStringToByteArray("0000010000000001000000000C5F7465737473657276696" +
"365045F746370056C6F63616C0000100001000000000000")
val src = InetSocketAddress(parseNumericAddress("2001:db8::456"), MdnsConstants.MDNS_PORT)
packetHandler.handlePacket(query, query.size, src)
val packetCaptor = ArgumentCaptor.forClass(MdnsPacket::class.java)
verify(repository).getConflictingServices(packetCaptor.capture())
packetCaptor.value.let {
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 MdnsTextRecord)
assertContentEquals(arrayOf("_testservice", "_tcp", "local"), it.answers[0].name)
}
thread.waitForIdle(TIMEOUT_MS)
verify(cb).onServiceConflict(advertiser, TEST_SERVICE_ID_1)
}
@Test
fun testRestartProbingForConflict() {
val mockProbingInfo = mock(ProbingInfo::class.java)
doReturn(mockProbingInfo).`when`(repository).setServiceProbing(TEST_SERVICE_ID_1)
advertiser.restartProbingForConflict(TEST_SERVICE_ID_1)
verify(prober).restartForConflict(mockProbingInfo)
}
@Test
fun testRenameServiceForConflict() {
val mockProbingInfo = mock(ProbingInfo::class.java)
doReturn(mockProbingInfo).`when`(repository).renameServiceForConflict(
TEST_SERVICE_ID_1, TEST_SERVICE_1)
advertiser.renameServiceForConflict(TEST_SERVICE_ID_1, TEST_SERVICE_1)
verify(prober).restartForConflict(mockProbingInfo)
}
private fun addServiceAndFinishProbing(serviceId: Int, serviceInfo: NsdServiceInfo):
AnnouncementInfo {
val testProbingInfo = mock(ProbingInfo::class.java)

View File

@@ -24,6 +24,7 @@ import android.os.HandlerThread
import com.android.server.connectivity.mdns.MdnsAnnouncer.AnnouncementInfo
import com.android.server.connectivity.mdns.MdnsRecordRepository.Dependencies
import com.android.server.connectivity.mdns.MdnsRecordRepository.getReverseDnsAddress
import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import java.net.InetSocketAddress
@@ -400,6 +401,63 @@ class MdnsRecordRepositoryTest {
intArrayOf(MdnsRecord.TYPE_A, MdnsRecord.TYPE_AAAA)),
), reply.additionalAnswers)
}
@Test
fun testGetConflictingServices() {
val repository = MdnsRecordRepository(thread.looper, deps)
repository.addService(TEST_SERVICE_ID_1, TEST_SERVICE_1)
repository.addService(TEST_SERVICE_ID_2, TEST_SERVICE_2)
val packet = MdnsPacket(
0 /* flags */,
emptyList() /* questions */,
listOf(
MdnsServiceRecord(
arrayOf("MyTestService", "_testservice", "_tcp", "local"),
0L /* receiptTimeMillis */, true /* cacheFlush */, 0L /* ttlMillis */,
0 /* servicePriority */, 0 /* serviceWeight */,
TEST_SERVICE_1.port + 1,
TEST_HOSTNAME),
MdnsTextRecord(
arrayOf("MyOtherTestService", "_testservice", "_tcp", "local"),
0L /* receiptTimeMillis */, true /* cacheFlush */, 0L /* ttlMillis */,
listOf(TextEntry.fromString("somedifferent=entry"))),
) /* answers */,
emptyList() /* authorityRecords */,
emptyList() /* additionalRecords */)
assertEquals(setOf(TEST_SERVICE_ID_1, TEST_SERVICE_ID_2),
repository.getConflictingServices(packet))
}
@Test
fun testGetConflictingServices_IdenticalService() {
val repository = MdnsRecordRepository(thread.looper, deps)
repository.addService(TEST_SERVICE_ID_1, TEST_SERVICE_1)
repository.addService(TEST_SERVICE_ID_2, TEST_SERVICE_2)
val otherTtlMillis = 1234L
val packet = MdnsPacket(
0 /* flags */,
emptyList() /* questions */,
listOf(
MdnsServiceRecord(
arrayOf("MyTestService", "_testservice", "_tcp", "local"),
0L /* receiptTimeMillis */, true /* cacheFlush */,
otherTtlMillis, 0 /* servicePriority */, 0 /* serviceWeight */,
TEST_SERVICE_1.port,
TEST_HOSTNAME),
MdnsTextRecord(
arrayOf("MyOtherTestService", "_testservice", "_tcp", "local"),
0L /* receiptTimeMillis */, true /* cacheFlush */,
otherTtlMillis, emptyList()),
) /* answers */,
emptyList() /* authorityRecords */,
emptyList() /* additionalRecords */)
// Above records are identical to the actual registrations: no conflict
assertEquals(emptySet(), repository.getConflictingServices(packet))
}
}
private fun MdnsRecordRepository.initWithService(serviceId: Int, serviceInfo: NsdServiceInfo):