NsdService should set the Inet6Address scope ids
Link local Inet6Address cannot be used without scope id being set properly. NsdService should set the Inet6Address scopes everywhere NsdServiceInfo.setHost or NsdServiceInfo.setHostAddresses is used. Test: atest CtsNetTestCases:android.net.cts.NsdManagerTest Bug: 273391977 Change-Id: I45da6aebeba4e2e398e0b58ce3b88470fb60863b
This commit is contained in:
@@ -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<InetAddress> 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<InetAddress> 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<InetAddress> 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<InetAddress> 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<InetAddress> getInetAddresses(@NonNull MdnsServiceInfo serviceInfo) {
|
||||
final List<String> v4Addrs = serviceInfo.getIpv4Addresses();
|
||||
final List<String> v6Addrs = serviceInfo.getIpv6Addresses();
|
||||
final List<InetAddress> 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:
|
||||
|
||||
@@ -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<InetAddress>) {
|
||||
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<ServiceUnregistered>()
|
||||
|
||||
Reference in New Issue
Block a user