Avoid creating a Network with INetd.LOCAL_NET_ID
INetd.LOCAL_NET_ID cannot be referred to by system SDK. To make the MdnsSocketProvider built with system SDK, the reference to INetd.LOCAL_NET_ID must be removed. This network is created in MdnsSocketProvider.java and propagated through MdnsSocketProvider.java -> MdnsMultinetworkSocketClient.java -> MdnsDiscoveryManager.java -> MdnsServiceTypeClient.java -> NsdService.java. In NsdService.java, it was used in handleMdnsDiscoveryManagerEvent() -> buildNsdServiceInfoFromMdnsEvent() -> setServiceNetworkForCallback(). The setServiceNetworkForCallback() is updated to handle the NETID_UNSET the same as LOCAL_NET_ID. Test: atest CtsNetTestCases FrameworksNetTests Bug: 272392042 Change-Id: I07c573948e9dc6249325f0733807bb7a7ffc281c
This commit is contained in:
@@ -1106,9 +1106,12 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
final String serviceName = serviceInfo.getServiceInstanceName();
|
final String serviceName = serviceInfo.getServiceInstanceName();
|
||||||
final NsdServiceInfo servInfo = new NsdServiceInfo(serviceName, serviceType);
|
final NsdServiceInfo servInfo = new NsdServiceInfo(serviceName, serviceType);
|
||||||
final Network network = serviceInfo.getNetwork();
|
final Network network = serviceInfo.getNetwork();
|
||||||
|
// In MdnsDiscoveryManagerEvent, the Network can be null which means it is a
|
||||||
|
// network for Tethering interface. In other words, the network == null means the
|
||||||
|
// network has netId = INetd.LOCAL_NET_ID.
|
||||||
setServiceNetworkForCallback(
|
setServiceNetworkForCallback(
|
||||||
servInfo,
|
servInfo,
|
||||||
network == null ? NETID_UNSET : network.netId,
|
network == null ? INetd.LOCAL_NET_ID : network.netId,
|
||||||
serviceInfo.getInterfaceIndex());
|
serviceInfo.getInterfaceIndex());
|
||||||
return servInfo;
|
return servInfo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public class MdnsMultinetworkSocketClient implements MdnsSocketClientBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSocketCreated(@NonNull Network network,
|
public void onSocketCreated(@Nullable Network network,
|
||||||
@NonNull MdnsInterfaceSocket socket, @NonNull List<LinkAddress> addresses) {
|
@NonNull MdnsInterfaceSocket socket, @NonNull List<LinkAddress> addresses) {
|
||||||
// The socket may be already created by other request before, try to get the stored
|
// The socket may be already created by other request before, try to get the stored
|
||||||
// ReadPacketHandler.
|
// ReadPacketHandler.
|
||||||
@@ -86,7 +86,7 @@ public class MdnsMultinetworkSocketClient implements MdnsSocketClientBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInterfaceDestroyed(@NonNull Network network,
|
public void onInterfaceDestroyed(@Nullable Network network,
|
||||||
@NonNull MdnsInterfaceSocket socket) {
|
@NonNull MdnsInterfaceSocket socket) {
|
||||||
mSocketPacketHandlers.remove(socket);
|
mSocketPacketHandlers.remove(socket);
|
||||||
mActiveNetworkSockets.remove(socket);
|
mActiveNetworkSockets.remove(socket);
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import android.annotation.Nullable;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
import android.net.INetd;
|
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
@@ -98,7 +97,7 @@ public class MdnsSocketProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void onLost(Network network) {
|
public void onLost(Network network) {
|
||||||
mActiveNetworksLinkProperties.remove(network);
|
mActiveNetworksLinkProperties.remove(network);
|
||||||
removeSocket(network, null /* interfaceName */);
|
removeNetworkSocket(network);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -235,7 +234,7 @@ public class MdnsSocketProvider {
|
|||||||
|
|
||||||
/*** Check whether the target network is matched current network */
|
/*** Check whether the target network is matched current network */
|
||||||
public static boolean isNetworkMatched(@Nullable Network targetNetwork,
|
public static boolean isNetworkMatched(@Nullable Network targetNetwork,
|
||||||
@NonNull Network currentNetwork) {
|
@Nullable Network currentNetwork) {
|
||||||
return targetNetwork == null || targetNetwork.equals(currentNetwork);
|
return targetNetwork == null || targetNetwork.equals(currentNetwork);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,9 +257,10 @@ public class MdnsSocketProvider {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final NetworkAsKey networkKey = new NetworkAsKey(network);
|
||||||
final SocketInfo socketInfo = mNetworkSockets.get(network);
|
final SocketInfo socketInfo = mNetworkSockets.get(network);
|
||||||
if (socketInfo == null) {
|
if (socketInfo == null) {
|
||||||
createSocket(network, lp);
|
createSocket(networkKey, lp);
|
||||||
} else {
|
} else {
|
||||||
// Update the addresses of this socket.
|
// Update the addresses of this socket.
|
||||||
final List<LinkAddress> addresses = lp.getLinkAddresses();
|
final List<LinkAddress> addresses = lp.getLinkAddresses();
|
||||||
@@ -295,16 +295,16 @@ public class MdnsSocketProvider {
|
|||||||
final CompareResult<String> interfaceDiff = new CompareResult<>(
|
final CompareResult<String> interfaceDiff = new CompareResult<>(
|
||||||
current, updated);
|
current, updated);
|
||||||
for (String name : interfaceDiff.added) {
|
for (String name : interfaceDiff.added) {
|
||||||
createSocket(new Network(INetd.LOCAL_NET_ID), createLPForTetheredInterface(name));
|
createSocket(LOCAL_NET, createLPForTetheredInterface(name));
|
||||||
}
|
}
|
||||||
for (String name : interfaceDiff.removed) {
|
for (String name : interfaceDiff.removed) {
|
||||||
removeSocket(new Network(INetd.LOCAL_NET_ID), name);
|
removeTetherInterfaceSocket(name);
|
||||||
}
|
}
|
||||||
current.clear();
|
current.clear();
|
||||||
current.addAll(updated);
|
current.addAll(updated);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createSocket(Network network, LinkProperties lp) {
|
private void createSocket(NetworkKey networkKey, LinkProperties lp) {
|
||||||
final String interfaceName = lp.getInterfaceName();
|
final String interfaceName = lp.getInterfaceName();
|
||||||
if (interfaceName == null) {
|
if (interfaceName == null) {
|
||||||
Log.e(TAG, "Can not create socket with null interface name.");
|
Log.e(TAG, "Can not create socket with null interface name.");
|
||||||
@@ -319,41 +319,52 @@ public class MdnsSocketProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
Log.d(TAG, "Create a socket on network:" + network
|
Log.d(TAG, "Create a socket on network:" + networkKey
|
||||||
+ " with interfaceName:" + interfaceName);
|
+ " with interfaceName:" + interfaceName);
|
||||||
}
|
}
|
||||||
final MdnsInterfaceSocket socket = mDependencies.createMdnsInterfaceSocket(
|
final MdnsInterfaceSocket socket = mDependencies.createMdnsInterfaceSocket(
|
||||||
networkInterface.getNetworkInterface(), MdnsConstants.MDNS_PORT, mLooper,
|
networkInterface.getNetworkInterface(), MdnsConstants.MDNS_PORT, mLooper,
|
||||||
mPacketReadBuffer);
|
mPacketReadBuffer);
|
||||||
final List<LinkAddress> addresses;
|
final List<LinkAddress> addresses;
|
||||||
if (network.netId == INetd.LOCAL_NET_ID) {
|
if (networkKey == LOCAL_NET) {
|
||||||
addresses = CollectionUtils.map(
|
addresses = CollectionUtils.map(
|
||||||
networkInterface.getInterfaceAddresses(), LinkAddress::new);
|
networkInterface.getInterfaceAddresses(),
|
||||||
|
i -> new LinkAddress(i.getAddress(), i.getNetworkPrefixLength()));
|
||||||
mTetherInterfaceSockets.put(interfaceName, new SocketInfo(socket, addresses));
|
mTetherInterfaceSockets.put(interfaceName, new SocketInfo(socket, addresses));
|
||||||
} else {
|
} else {
|
||||||
addresses = lp.getLinkAddresses();
|
addresses = lp.getLinkAddresses();
|
||||||
mNetworkSockets.put(network, new SocketInfo(socket, addresses));
|
mNetworkSockets.put(((NetworkAsKey) networkKey).mNetwork,
|
||||||
|
new SocketInfo(socket, addresses));
|
||||||
}
|
}
|
||||||
// Try to join IPv4/IPv6 group.
|
// Try to join IPv4/IPv6 group.
|
||||||
socket.joinGroup(addresses);
|
socket.joinGroup(addresses);
|
||||||
|
|
||||||
// Notify the listeners which need this socket.
|
// Notify the listeners which need this socket.
|
||||||
notifySocketCreated(network, socket, addresses);
|
if (networkKey == LOCAL_NET) {
|
||||||
|
notifySocketCreated(null /* network */, socket, addresses);
|
||||||
|
} else {
|
||||||
|
notifySocketCreated(((NetworkAsKey) networkKey).mNetwork, socket, addresses);
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(TAG, "Create a socket failed with interface=" + interfaceName, e);
|
Log.e(TAG, "Create a socket failed with interface=" + interfaceName, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeSocket(Network network, String interfaceName) {
|
private void removeNetworkSocket(Network network) {
|
||||||
final SocketInfo socketInfo = network.netId == INetd.LOCAL_NET_ID
|
final SocketInfo socketInfo = mNetworkSockets.remove(network);
|
||||||
? mTetherInterfaceSockets.remove(interfaceName)
|
|
||||||
: mNetworkSockets.remove(network);
|
|
||||||
if (socketInfo == null) return;
|
if (socketInfo == null) return;
|
||||||
|
|
||||||
socketInfo.mSocket.destroy();
|
socketInfo.mSocket.destroy();
|
||||||
notifyInterfaceDestroyed(network, socketInfo.mSocket);
|
notifyInterfaceDestroyed(network, socketInfo.mSocket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeTetherInterfaceSocket(String interfaceName) {
|
||||||
|
final SocketInfo socketInfo = mTetherInterfaceSockets.remove(interfaceName);
|
||||||
|
if (socketInfo == null) return;
|
||||||
|
socketInfo.mSocket.destroy();
|
||||||
|
notifyInterfaceDestroyed(null /* network */, socketInfo.mSocket);
|
||||||
|
}
|
||||||
|
|
||||||
private void notifySocketCreated(Network network, MdnsInterfaceSocket socket,
|
private void notifySocketCreated(Network network, MdnsInterfaceSocket socket,
|
||||||
List<LinkAddress> addresses) {
|
List<LinkAddress> addresses) {
|
||||||
for (int i = 0; i < mCallbacksToRequestedNetworks.size(); i++) {
|
for (int i = 0; i < mCallbacksToRequestedNetworks.size(); i++) {
|
||||||
@@ -393,7 +404,7 @@ public class MdnsSocketProvider {
|
|||||||
if (DBG) Log.d(TAG, "There is no LinkProperties for this network:" + network);
|
if (DBG) Log.d(TAG, "There is no LinkProperties for this network:" + network);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
createSocket(network, lp);
|
createSocket(new NetworkAsKey(network), lp);
|
||||||
} else {
|
} else {
|
||||||
// Notify the socket for requested network.
|
// Notify the socket for requested network.
|
||||||
cb.onSocketCreated(network, socketInfo.mSocket, socketInfo.mAddresses);
|
cb.onSocketCreated(network, socketInfo.mSocket, socketInfo.mAddresses);
|
||||||
@@ -403,12 +414,11 @@ public class MdnsSocketProvider {
|
|||||||
private void retrieveAndNotifySocketFromInterface(String interfaceName, SocketCallback cb) {
|
private void retrieveAndNotifySocketFromInterface(String interfaceName, SocketCallback cb) {
|
||||||
final SocketInfo socketInfo = mTetherInterfaceSockets.get(interfaceName);
|
final SocketInfo socketInfo = mTetherInterfaceSockets.get(interfaceName);
|
||||||
if (socketInfo == null) {
|
if (socketInfo == null) {
|
||||||
createSocket(
|
createSocket(LOCAL_NET, createLPForTetheredInterface(interfaceName));
|
||||||
new Network(INetd.LOCAL_NET_ID), createLPForTetheredInterface(interfaceName));
|
|
||||||
} else {
|
} else {
|
||||||
// Notify the socket for requested network.
|
// Notify the socket for requested network.
|
||||||
cb.onSocketCreated(
|
cb.onSocketCreated(
|
||||||
new Network(INetd.LOCAL_NET_ID), socketInfo.mSocket, socketInfo.mAddresses);
|
null /* network */, socketInfo.mSocket, socketInfo.mAddresses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,7 +477,7 @@ public class MdnsSocketProvider {
|
|||||||
final SocketInfo info = mTetherInterfaceSockets.valueAt(i);
|
final SocketInfo info = mTetherInterfaceSockets.valueAt(i);
|
||||||
info.mSocket.destroy();
|
info.mSocket.destroy();
|
||||||
// Still notify to unrequester for socket destroy.
|
// Still notify to unrequester for socket destroy.
|
||||||
cb.onInterfaceDestroyed(new Network(INetd.LOCAL_NET_ID), info.mSocket);
|
cb.onInterfaceDestroyed(null /* network */, info.mSocket);
|
||||||
}
|
}
|
||||||
mTetherInterfaceSockets.clear();
|
mTetherInterfaceSockets.clear();
|
||||||
|
|
||||||
@@ -478,13 +488,49 @@ public class MdnsSocketProvider {
|
|||||||
/*** Callbacks for listening socket changes */
|
/*** Callbacks for listening socket changes */
|
||||||
public interface SocketCallback {
|
public interface SocketCallback {
|
||||||
/*** Notify the socket is created */
|
/*** Notify the socket is created */
|
||||||
default void onSocketCreated(@NonNull Network network, @NonNull MdnsInterfaceSocket socket,
|
default void onSocketCreated(@Nullable Network network, @NonNull MdnsInterfaceSocket socket,
|
||||||
@NonNull List<LinkAddress> addresses) {}
|
@NonNull List<LinkAddress> addresses) {}
|
||||||
/*** Notify the interface is destroyed */
|
/*** Notify the interface is destroyed */
|
||||||
default void onInterfaceDestroyed(@NonNull Network network,
|
default void onInterfaceDestroyed(@Nullable Network network,
|
||||||
@NonNull MdnsInterfaceSocket socket) {}
|
@NonNull MdnsInterfaceSocket socket) {}
|
||||||
/*** Notify the addresses is changed on the network */
|
/*** Notify the addresses is changed on the network */
|
||||||
default void onAddressesChanged(@NonNull Network network,
|
default void onAddressesChanged(@Nullable Network network,
|
||||||
@NonNull MdnsInterfaceSocket socket, @NonNull List<LinkAddress> addresses) {}
|
@NonNull MdnsInterfaceSocket socket, @NonNull List<LinkAddress> addresses) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private interface NetworkKey {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final NetworkKey LOCAL_NET = new NetworkKey() {
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "NetworkKey:LOCAL_NET";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static class NetworkAsKey implements NetworkKey {
|
||||||
|
private final Network mNetwork;
|
||||||
|
|
||||||
|
NetworkAsKey(Network network) {
|
||||||
|
this.mNetwork = network;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return mNetwork.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object other) {
|
||||||
|
if (!(other instanceof NetworkAsKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return mNetwork.equals(((NetworkAsKey) other).mNetwork);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "NetworkAsKey{ network=" + mNetwork + " }";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import static org.mockito.Mockito.verify;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
import android.net.INetd;
|
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
@@ -74,8 +73,6 @@ public class MdnsSocketProviderTest {
|
|||||||
private static final LinkAddress LINKADDRV6 =
|
private static final LinkAddress LINKADDRV6 =
|
||||||
new LinkAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334/64");
|
new LinkAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334/64");
|
||||||
private static final Network TEST_NETWORK = new Network(123);
|
private static final Network TEST_NETWORK = new Network(123);
|
||||||
private static final Network LOCAL_NETWORK = new Network(INetd.LOCAL_NET_ID);
|
|
||||||
|
|
||||||
@Mock private Context mContext;
|
@Mock private Context mContext;
|
||||||
@Mock private Dependencies mDeps;
|
@Mock private Dependencies mDeps;
|
||||||
@Mock private ConnectivityManager mCm;
|
@Mock private ConnectivityManager mCm;
|
||||||
@@ -244,7 +241,7 @@ public class MdnsSocketProviderTest {
|
|||||||
verify(mLocalOnlyIfaceWrapper).getNetworkInterface();
|
verify(mLocalOnlyIfaceWrapper).getNetworkInterface();
|
||||||
testCallback1.expectedNoCallback();
|
testCallback1.expectedNoCallback();
|
||||||
testCallback2.expectedNoCallback();
|
testCallback2.expectedNoCallback();
|
||||||
testCallback3.expectedSocketCreatedForNetwork(LOCAL_NETWORK, List.of());
|
testCallback3.expectedSocketCreatedForNetwork(null /* network */, List.of());
|
||||||
|
|
||||||
mHandler.post(() -> mTetheringEventCallback.onTetheredInterfacesChanged(
|
mHandler.post(() -> mTetheringEventCallback.onTetheredInterfacesChanged(
|
||||||
List.of(TETHERED_IFACE_NAME)));
|
List.of(TETHERED_IFACE_NAME)));
|
||||||
@@ -252,7 +249,7 @@ public class MdnsSocketProviderTest {
|
|||||||
verify(mTetheredIfaceWrapper).getNetworkInterface();
|
verify(mTetheredIfaceWrapper).getNetworkInterface();
|
||||||
testCallback1.expectedNoCallback();
|
testCallback1.expectedNoCallback();
|
||||||
testCallback2.expectedNoCallback();
|
testCallback2.expectedNoCallback();
|
||||||
testCallback3.expectedSocketCreatedForNetwork(LOCAL_NETWORK, List.of());
|
testCallback3.expectedSocketCreatedForNetwork(null /* network */, List.of());
|
||||||
|
|
||||||
mHandler.post(() -> mSocketProvider.unrequestSocket(testCallback1));
|
mHandler.post(() -> mSocketProvider.unrequestSocket(testCallback1));
|
||||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||||
@@ -270,14 +267,14 @@ public class MdnsSocketProviderTest {
|
|||||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||||
testCallback1.expectedNoCallback();
|
testCallback1.expectedNoCallback();
|
||||||
testCallback2.expectedNoCallback();
|
testCallback2.expectedNoCallback();
|
||||||
testCallback3.expectedInterfaceDestroyedForNetwork(LOCAL_NETWORK);
|
testCallback3.expectedInterfaceDestroyedForNetwork(null /* network */);
|
||||||
|
|
||||||
mHandler.post(() -> mSocketProvider.unrequestSocket(testCallback3));
|
mHandler.post(() -> mSocketProvider.unrequestSocket(testCallback3));
|
||||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||||
testCallback1.expectedNoCallback();
|
testCallback1.expectedNoCallback();
|
||||||
testCallback2.expectedNoCallback();
|
testCallback2.expectedNoCallback();
|
||||||
// Expect the socket destroy for tethered interface.
|
// Expect the socket destroy for tethered interface.
|
||||||
testCallback3.expectedInterfaceDestroyedForNetwork(LOCAL_NETWORK);
|
testCallback3.expectedInterfaceDestroyedForNetwork(null /* network */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user