diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java index cbe6691d8c..c00f1aefcb 100644 --- a/service-t/src/com/android/server/NsdService.java +++ b/service-t/src/com/android/server/NsdService.java @@ -72,6 +72,7 @@ import com.android.server.connectivity.mdns.MdnsSocketProvider; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; @@ -1155,22 +1156,7 @@ public class NsdService extends INsdManager.Stub { Log.e(TAG, "Invalid attribute", e); } } - final List addresses = new ArrayList<>(); - for (String ipv4Address : serviceInfo.getIpv4Addresses()) { - try { - addresses.add(InetAddresses.parseNumericAddress(ipv4Address)); - } catch (IllegalArgumentException e) { - Log.wtf(TAG, "Invalid ipv4 address", e); - } - } - for (String ipv6Address : serviceInfo.getIpv6Addresses()) { - try { - addresses.add(InetAddresses.parseNumericAddress(ipv6Address)); - } catch (IllegalArgumentException e) { - Log.wtf(TAG, "Invalid ipv6 address", e); - } - } - + final List addresses = getInetAddresses(serviceInfo); if (addresses.size() != 0) { info.setHostAddresses(addresses); clientInfo.onResolveServiceSucceeded(clientId, info); @@ -1202,21 +1188,7 @@ public class NsdService extends INsdManager.Stub { } } - final List addresses = new ArrayList<>(); - for (String ipv4Address : serviceInfo.getIpv4Addresses()) { - try { - addresses.add(InetAddresses.parseNumericAddress(ipv4Address)); - } catch (IllegalArgumentException e) { - Log.wtf(TAG, "Invalid ipv4 address", e); - } - } - for (String ipv6Address : serviceInfo.getIpv6Addresses()) { - try { - addresses.add(InetAddresses.parseNumericAddress(ipv6Address)); - } catch (IllegalArgumentException e) { - Log.wtf(TAG, "Invalid ipv6 address", e); - } - } + final List addresses = getInetAddresses(serviceInfo); info.setHostAddresses(addresses); clientInfo.onServiceUpdated(clientId, info); break; @@ -1232,6 +1204,36 @@ public class NsdService extends INsdManager.Stub { } } + @NonNull + private static List getInetAddresses(@NonNull MdnsServiceInfo serviceInfo) { + final List v4Addrs = serviceInfo.getIpv4Addresses(); + final List v6Addrs = serviceInfo.getIpv6Addresses(); + final List addresses = new ArrayList<>(v4Addrs.size() + v6Addrs.size()); + for (String ipv4Address : v4Addrs) { + try { + addresses.add(InetAddresses.parseNumericAddress(ipv4Address)); + } catch (IllegalArgumentException e) { + Log.wtf(TAG, "Invalid ipv4 address", e); + } + } + for (String ipv6Address : v6Addrs) { + try { + final InetAddress addr = InetAddresses.parseNumericAddress(ipv6Address); + if (addr.isLinkLocalAddress()) { + final Inet6Address v6Addr = Inet6Address.getByAddress( + null /* host */, addr.getAddress(), + serviceInfo.getInterfaceIndex()); + addresses.add(v6Addr); + } else { + addresses.add(addr); + } + } catch (IllegalArgumentException | UnknownHostException e) { + Log.wtf(TAG, "Invalid ipv6 address", e); + } + } + return addresses; + } + private static void setServiceNetworkForCallback(NsdServiceInfo info, int netId, int ifaceIdx) { switch (netId) { case NETID_UNSET: diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt index db4f937f04..da0341a073 100644 --- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt +++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt @@ -96,6 +96,8 @@ import com.android.testutils.tryTest import com.android.testutils.waitForIdle import java.io.File import java.io.IOException +import java.net.Inet6Address +import java.net.InetAddress import java.net.NetworkInterface import java.net.ServerSocket import java.nio.charset.StandardCharsets @@ -132,6 +134,7 @@ private val nsdShim = NsdShimImpl.newInstance() @AppModeFull(reason = "Socket cannot bind in instant app mode") @RunWith(AndroidJUnit4::class) +@ConnectivityModuleTest class NsdManagerTest { // Rule used to filter CtsNetTestCasesMaxTargetSdkXX @get:Rule @@ -696,6 +699,20 @@ class NsdManagerTest { } } + private fun checkAddressScopeId(iface: TestNetworkInterface, address: List) { + val targetSdkVersion = context.packageManager + .getTargetSdkVersion(context.applicationInfo.packageName) + if (targetSdkVersion <= Build.VERSION_CODES.TIRAMISU) { + return + } + val ifaceIdx = NetworkInterface.getByName(iface.interfaceName).index + address.forEach { + if (it is Inet6Address && it.isLinkLocalAddress) { + assertEquals(ifaceIdx, it.scopeId) + } + } + } + @Test fun testNsdManager_ResolveOnNetwork() { // This test requires shims supporting T+ APIs (NsdServiceInfo.network) @@ -731,6 +748,7 @@ class NsdManagerTest { assertEquals(registeredInfo.serviceName, it.serviceName) assertEquals(si.port, it.port) assertEquals(testNetwork1.network, nsdShim.getNetwork(it)) + checkAddressScopeId(testNetwork1.iface, it.hostAddresses) } // TODO: check that MDNS packets are sent only on testNetwork1. } cleanupStep { @@ -970,6 +988,7 @@ class NsdManagerTest { for (hostAddress in hostAddresses) { assertTrue(addresses.contains(hostAddress)) } + checkAddressScopeId(testNetwork1.iface, serviceInfoCb.serviceInfo.hostAddresses) } cleanupStep { nsdManager.unregisterService(registrationRecord) registrationRecord.expectCallback()