[mdns] fix the logic of finding the existing service
When adding a service, the MdnsRecordRepository finds the
existing service solely by service name, which is wrong. it should check
both the service name and the service type.
Bug: 325862182
Change-Id: I72c6837d0dfb41fc9b2d7763e18b3f5415f8c0d9
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 fb45454..96a59e2 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java
@@ -388,7 +388,8 @@
"Service ID must not be reused across registrations: " + serviceId);
}
- final int existing = getServiceByName(serviceInfo.getServiceName());
+ final int existing =
+ getServiceByNameAndType(serviceInfo.getServiceName(), serviceInfo.getServiceType());
// It's OK to re-add a service that is exiting
if (existing >= 0 && !mServices.get(existing).exiting) {
throw new NameConflictException(existing);
@@ -405,16 +406,17 @@
}
/**
- * @return The ID of the service identified by its name, or -1 if none.
+ * @return The ID of the service identified by its name and type, or -1 if none.
*/
- private int getServiceByName(@Nullable String serviceName) {
- if (TextUtils.isEmpty(serviceName)) {
+ private int getServiceByNameAndType(
+ @Nullable String serviceName, @Nullable String serviceType) {
+ if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
return -1;
}
for (int i = 0; i < mServices.size(); i++) {
- final ServiceRegistration registration = mServices.valueAt(i);
- if (MdnsUtils.equalsIgnoreDnsCase(
- serviceName, registration.serviceInfo.getServiceName())) {
+ final NsdServiceInfo info = mServices.valueAt(i).serviceInfo;
+ if (MdnsUtils.equalsIgnoreDnsCase(serviceName, info.getServiceName())
+ && MdnsUtils.equalsIgnoreDnsCase(serviceType, info.getServiceType())) {
return mServices.keyAt(i);
}
}
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
index 43aa8a6..6db372f 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
@@ -684,6 +684,48 @@
}
}
+ @Test
+ fun testRegisterService_twoServicesWithSameNameButDifferentTypes_registeredAndDiscoverable() {
+ val si1 = NsdServiceInfo().also {
+ it.network = testNetwork1.network
+ it.serviceName = serviceName
+ it.serviceType = serviceType
+ it.port = TEST_PORT
+ }
+ val si2 = NsdServiceInfo().also {
+ it.network = testNetwork1.network
+ it.serviceName = serviceName
+ it.serviceType = serviceType2
+ it.port = TEST_PORT + 1
+ }
+ val registrationRecord1 = NsdRegistrationRecord()
+ val registrationRecord2 = NsdRegistrationRecord()
+ val discoveryRecord1 = NsdDiscoveryRecord()
+ val discoveryRecord2 = NsdDiscoveryRecord()
+ tryTest {
+ registerService(registrationRecord1, si1)
+ registerService(registrationRecord2, si2)
+
+ nsdManager.discoverServices(serviceType,
+ NsdManager.PROTOCOL_DNS_SD,
+ testNetwork1.network, Executor { it.run() }, discoveryRecord1)
+ nsdManager.discoverServices(serviceType2,
+ NsdManager.PROTOCOL_DNS_SD,
+ testNetwork1.network, Executor { it.run() }, discoveryRecord2)
+
+ discoveryRecord1.waitForServiceDiscovered(serviceName, serviceType,
+ testNetwork1.network)
+ discoveryRecord2.waitForServiceDiscovered(serviceName, serviceType2,
+ testNetwork1.network)
+ } cleanupStep {
+ nsdManager.stopServiceDiscovery(discoveryRecord1)
+ nsdManager.stopServiceDiscovery(discoveryRecord2)
+ } cleanup {
+ nsdManager.unregisterService(registrationRecord1)
+ nsdManager.unregisterService(registrationRecord2)
+ }
+ }
+
fun checkOffloadServiceInfo(serviceInfo: OffloadServiceInfo, si: NsdServiceInfo) {
val expectedServiceType = si.serviceType.split(",")[0]
assertEquals(si.serviceName, serviceInfo.key.serviceName)