Include/exclude mDNS interfaces based on transport

Regardless of IFF_MULTICAST (and IFF_BROADCAST), always include wifi
transport interfaces, and always exclude cellular transport interfaces.

Some interfaces do not have the multicast or broadcast flag set
properly. Use the transport to determine whether to use them, rather
than the interface flags.

Bug: 268138840
Test: atest MdnsSocketProviderTest
Change-Id: Idbddfa9d2cc05ce1850786aa634da4c38afd3fc0
This commit is contained in:
Remi NGUYEN VAN
2023-03-16 18:02:19 +09:00
committed by Yuyang Huang
parent e2294fb13e
commit 145b16cb5a
3 changed files with 160 additions and 21 deletions

View File

@@ -16,6 +16,11 @@
package com.android.server.connectivity.mdns;
import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static com.android.testutils.ContextUtils.mockService;
import static org.junit.Assert.assertEquals;
@@ -38,6 +43,7 @@ import android.net.ConnectivityManager.NetworkCallback;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.TetheringManager;
import android.net.TetheringManager.TetheringEventCallback;
import android.os.Build;
@@ -98,8 +104,13 @@ public class MdnsSocketProviderTest {
// Test is using mockito-extended
doCallRealMethod().when(mContext).getSystemService(TetheringManager.class);
}
doReturn(true).when(mDeps).canScanOnInterface(any());
doReturn(mTestNetworkIfaceWrapper).when(mDeps).getNetworkInterfaceByName(anyString());
doReturn(true).when(mTestNetworkIfaceWrapper).isUp();
doReturn(true).when(mLocalOnlyIfaceWrapper).isUp();
doReturn(true).when(mTetheredIfaceWrapper).isUp();
doReturn(true).when(mTestNetworkIfaceWrapper).supportsMulticast();
doReturn(true).when(mLocalOnlyIfaceWrapper).supportsMulticast();
doReturn(true).when(mTetheredIfaceWrapper).supportsMulticast();
doReturn(mLocalOnlyIfaceWrapper).when(mDeps)
.getNetworkInterfaceByName(LOCAL_ONLY_IFACE_NAME);
doReturn(mTetheredIfaceWrapper).when(mDeps).getNetworkInterfaceByName(TETHERED_IFACE_NAME);
@@ -205,6 +216,24 @@ public class MdnsSocketProviderTest {
}
}
private static NetworkCapabilities makeCapabilities(int... transports) {
final NetworkCapabilities nc = new NetworkCapabilities();
for (int transport : transports) {
nc.addTransportType(transport);
}
return nc;
}
private void postNetworkAvailable(int... transports) {
final LinkProperties testLp = new LinkProperties();
testLp.setInterfaceName(TEST_IFACE_NAME);
testLp.setLinkAddresses(List.of(LINKADDRV4));
final NetworkCapabilities testNc = makeCapabilities(transports);
mHandler.post(() -> mNetworkCallback.onCapabilitiesChanged(TEST_NETWORK, testNc));
mHandler.post(() -> mNetworkCallback.onLinkPropertiesChanged(TEST_NETWORK, testLp));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
}
@Test
public void testSocketRequestAndUnrequestSocket() {
startMonitoringSockets();
@@ -214,12 +243,7 @@ public class MdnsSocketProviderTest {
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback1.expectedNoCallback();
final LinkProperties testLp = new LinkProperties();
testLp.setInterfaceName(TEST_IFACE_NAME);
testLp.setLinkAddresses(List.of(LINKADDRV4));
mHandler.post(() -> mNetworkCallback.onLinkPropertiesChanged(TEST_NETWORK, testLp));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mTestNetworkIfaceWrapper).getNetworkInterface();
postNetworkAvailable(TRANSPORT_WIFI);
testCallback1.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4));
final TestSocketCallback testCallback2 = new TestSocketCallback();
@@ -286,12 +310,7 @@ public class MdnsSocketProviderTest {
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback.expectedNoCallback();
final LinkProperties testLp = new LinkProperties();
testLp.setInterfaceName(TEST_IFACE_NAME);
testLp.setLinkAddresses(List.of(LINKADDRV4));
mHandler.post(() -> mNetworkCallback.onLinkPropertiesChanged(TEST_NETWORK, testLp));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mTestNetworkIfaceWrapper, times(1)).getNetworkInterface();
postNetworkAvailable(TRANSPORT_WIFI);
testCallback.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4));
final LinkProperties newTestLp = new LinkProperties();
@@ -299,7 +318,6 @@ public class MdnsSocketProviderTest {
newTestLp.setLinkAddresses(List.of(LINKADDRV4, LINKADDRV6));
mHandler.post(() -> mNetworkCallback.onLinkPropertiesChanged(TEST_NETWORK, newTestLp));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mTestNetworkIfaceWrapper, times(1)).getNetworkInterface();
testCallback.expectedAddressesChangedForNetwork(
TEST_NETWORK, List.of(LINKADDRV4, LINKADDRV6));
}
@@ -403,4 +421,77 @@ public class MdnsSocketProviderTest {
verify(mTestNetworkIfaceWrapper, times(2)).getNetworkInterface();
testCallback.expectedSocketCreatedForNetwork(otherNetwork, List.of(otherAddress));
}
@Test
public void testNoSocketCreatedForCellular() {
startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_CELLULAR);
testCallback.expectedNoCallback();
}
@Test
public void testNoSocketCreatedForNonMulticastInterface() throws Exception {
doReturn(false).when(mTestNetworkIfaceWrapper).supportsMulticast();
startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_BLUETOOTH);
testCallback.expectedNoCallback();
}
@Test
public void testSocketCreatedForMulticastInterface() throws Exception {
doReturn(true).when(mTestNetworkIfaceWrapper).supportsMulticast();
startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_BLUETOOTH);
testCallback.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4));
}
@Test
public void testNoSocketCreatedForPTPInterface() throws Exception {
doReturn(true).when(mTestNetworkIfaceWrapper).isPointToPoint();
startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_BLUETOOTH);
testCallback.expectedNoCallback();
}
@Test
public void testNoSocketCreatedForVPNInterface() throws Exception {
// VPN interfaces generally also have IFF_POINTOPOINT, but even if they don't, they should
// not be included even with TRANSPORT_WIFI.
doReturn(false).when(mTestNetworkIfaceWrapper).supportsMulticast();
startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_VPN, TRANSPORT_WIFI);
testCallback.expectedNoCallback();
}
@Test
public void testSocketCreatedForWifiWithoutMulticastFlag() throws Exception {
doReturn(false).when(mTestNetworkIfaceWrapper).supportsMulticast();
startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_WIFI);
testCallback.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4));
}
}