Support SAP and LOHS enabled at the same time

Use type + scope as key to build cached address map so that
SAP (key: TETHERING_WIFI + INTERNET) and LOHS
(key: TETHERING_WIFI + LOCAL) can use different address.

Bug: 233175023
Test: atest TetheringTests
Change-Id: I46a4b3ee919628092b7540202a43d79f407b09b6
This commit is contained in:
Mark
2023-03-15 06:45:04 +00:00
parent ae3abdfa4b
commit 49649c9aea
4 changed files with 143 additions and 69 deletions

View File

@@ -17,6 +17,8 @@
package android.net.ip;
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_LOCAL;
import static android.net.TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
@@ -405,8 +407,8 @@ public class IpServer extends StateMachine {
/** Internals. */
private boolean startIPv4() {
return configureIPv4(true);
private boolean startIPv4(int scope) {
return configureIPv4(true, scope);
}
/**
@@ -616,7 +618,7 @@ public class IpServer extends StateMachine {
}
private void stopIPv4() {
configureIPv4(false);
configureIPv4(false /* enabled */, CONNECTIVITY_SCOPE_GLOBAL /* not used */);
// NOTE: All of configureIPv4() will be refactored out of existence
// into calls to InterfaceController, shared with startIPv4().
mInterfaceCtrl.clearIPv4Address();
@@ -627,11 +629,11 @@ public class IpServer extends StateMachine {
mStaticIpv4ClientAddr = null;
}
private boolean configureIPv4(boolean enabled) {
private boolean configureIPv4(boolean enabled, int scope) {
if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")");
if (enabled) {
mIpv4Address = requestIpv4Address(true /* useLastAddress */);
mIpv4Address = requestIpv4Address(scope, true /* useLastAddress */);
}
if (mIpv4Address == null) {
@@ -679,12 +681,12 @@ public class IpServer extends StateMachine {
return (mInterfaceType == TetheringManager.TETHERING_BLUETOOTH) && !SdkLevel.isAtLeastT();
}
private LinkAddress requestIpv4Address(final boolean useLastAddress) {
private LinkAddress requestIpv4Address(final int scope, final boolean useLastAddress) {
if (mStaticIpv4ServerAddr != null) return mStaticIpv4ServerAddr;
if (shouldNotConfigureBluetoothInterface()) return new LinkAddress(BLUETOOTH_IFACE_ADDR);
return mPrivateAddressCoordinator.requestDownstreamAddress(this, useLastAddress);
return mPrivateAddressCoordinator.requestDownstreamAddress(this, scope, useLastAddress);
}
private boolean startIPv6() {
@@ -1133,8 +1135,16 @@ public class IpServer extends StateMachine {
sendInterfaceState(mDesiredInterfaceState);
}
private int getScope() {
if (mDesiredInterfaceState == STATE_TETHERED) {
return CONNECTIVITY_SCOPE_GLOBAL;
}
return CONNECTIVITY_SCOPE_LOCAL;
}
private void startServingInterface() {
if (!startIPv4()) {
if (!startIPv4(getScope())) {
mLastError = TETHER_ERROR_IFACE_CFG_ERROR;
return;
}
@@ -1222,7 +1232,7 @@ public class IpServer extends StateMachine {
}
final LinkAddress deprecatedLinkAddress = mIpv4Address;
mIpv4Address = requestIpv4Address(false);
mIpv4Address = requestIpv4Address(getScope(), false);
if (mIpv4Address == null) {
mLog.e("Fail to request a new downstream prefix");
return;

View File

@@ -16,6 +16,8 @@
package com.android.networkstack.tethering;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_LOCAL;
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
import static android.net.TetheringManager.TETHERING_WIFI_P2P;
@@ -34,7 +36,6 @@ import android.net.Network;
import android.net.ip.IpServer;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.SparseArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -77,7 +78,7 @@ public class PrivateAddressCoordinator {
private final ConnectivityManager mConnectivityMgr;
private final TetheringConfiguration mConfig;
// keyed by downstream type(TetheringManager.TETHERING_*).
private final SparseArray<LinkAddress> mCachedAddresses;
private final ArrayMap<AddressKey, LinkAddress> mCachedAddresses;
public PrivateAddressCoordinator(Context context, TetheringConfiguration config) {
mDownstreams = new ArraySet<>();
@@ -85,10 +86,12 @@ public class PrivateAddressCoordinator {
mConnectivityMgr = (ConnectivityManager) context.getSystemService(
Context.CONNECTIVITY_SERVICE);
mConfig = config;
mCachedAddresses = new SparseArray<>();
mCachedAddresses = new ArrayMap<AddressKey, LinkAddress>();
// Reserved static addresses for bluetooth and wifi p2p.
mCachedAddresses.put(TETHERING_BLUETOOTH, new LinkAddress(LEGACY_BLUETOOTH_IFACE_ADDRESS));
mCachedAddresses.put(TETHERING_WIFI_P2P, new LinkAddress(LEGACY_WIFI_P2P_IFACE_ADDRESS));
mCachedAddresses.put(new AddressKey(TETHERING_BLUETOOTH, CONNECTIVITY_SCOPE_GLOBAL),
new LinkAddress(LEGACY_BLUETOOTH_IFACE_ADDRESS));
mCachedAddresses.put(new AddressKey(TETHERING_WIFI_P2P, CONNECTIVITY_SCOPE_LOCAL),
new LinkAddress(LEGACY_WIFI_P2P_IFACE_ADDRESS));
mTetheringPrefixes = new ArrayList<>(Arrays.asList(new IpPrefix("192.168.0.0/16"),
new IpPrefix("172.16.0.0/12"), new IpPrefix("10.0.0.0/8")));
@@ -166,16 +169,18 @@ public class PrivateAddressCoordinator {
* returns null if there is no available address.
*/
@Nullable
public LinkAddress requestDownstreamAddress(final IpServer ipServer, boolean useLastAddress) {
public LinkAddress requestDownstreamAddress(final IpServer ipServer, final int scope,
boolean useLastAddress) {
if (mConfig.shouldEnableWifiP2pDedicatedIp()
&& ipServer.interfaceType() == TETHERING_WIFI_P2P) {
return new LinkAddress(LEGACY_WIFI_P2P_IFACE_ADDRESS);
}
final AddressKey addrKey = new AddressKey(ipServer.interfaceType(), scope);
// This ensures that tethering isn't started on 2 different interfaces with the same type.
// Once tethering could support multiple interface with the same type,
// TetheringSoftApCallback would need to handle it among others.
final LinkAddress cachedAddress = mCachedAddresses.get(ipServer.interfaceType());
final LinkAddress cachedAddress = mCachedAddresses.get(addrKey);
if (useLastAddress && cachedAddress != null
&& !isConflictWithUpstream(asIpPrefix(cachedAddress))) {
mDownstreams.add(ipServer);
@@ -186,7 +191,7 @@ public class PrivateAddressCoordinator {
final LinkAddress newAddress = chooseDownstreamAddress(prefixRange);
if (newAddress != null) {
mDownstreams.add(ipServer);
mCachedAddresses.put(ipServer.interfaceType(), newAddress);
mCachedAddresses.put(addrKey, newAddress);
return newAddress;
}
}
@@ -384,6 +389,34 @@ public class PrivateAddressCoordinator {
return asIpPrefix(address);
}
private static class AddressKey {
private final int mTetheringType;
private final int mScope;
private AddressKey(int type, int scope) {
mTetheringType = type;
mScope = scope;
}
@Override
public int hashCode() {
return (mTetheringType << 16) + mScope;
}
@Override
public boolean equals(@Nullable Object obj) {
if (!(obj instanceof AddressKey)) return false;
final AddressKey other = (AddressKey) obj;
return mTetheringType == other.mTetheringType && mScope == other.mScope;
}
@Override
public String toString() {
return "AddressKey(" + mTetheringType + ", " + mScope + ")";
}
}
void dump(final IndentingPrintWriter pw) {
pw.println("mTetheringPrefixes:");
pw.increaseIndent();

View File

@@ -19,6 +19,8 @@ package android.net.ip;
import static android.net.INetd.IF_STATE_DOWN;
import static android.net.INetd.IF_STATE_UP;
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_LOCAL;
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
import static android.net.TetheringManager.TETHERING_NCM;
import static android.net.TetheringManager.TETHERING_USB;
@@ -48,6 +50,7 @@ import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
@@ -271,8 +274,8 @@ public class IpServerTest {
dispatchTetherConnectionChanged(upstreamIface, lp, 0);
}
reset(mNetd, mCallback, mAddressCoordinator, mBpfCoordinator);
when(mAddressCoordinator.requestDownstreamAddress(any(), anyBoolean())).thenReturn(
mTestAddress);
when(mAddressCoordinator.requestDownstreamAddress(any(), anyInt(),
anyBoolean())).thenReturn(mTestAddress);
}
@SuppressWarnings("DoNotCall") // Ignore warning for synchronous to call to Thread.run()
@@ -293,8 +296,8 @@ public class IpServerTest {
@Before public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(mSharedLog.forSubComponent(anyString())).thenReturn(mSharedLog);
when(mAddressCoordinator.requestDownstreamAddress(any(), anyBoolean())).thenReturn(
mTestAddress);
when(mAddressCoordinator.requestDownstreamAddress(any(), anyInt(),
anyBoolean())).thenReturn(mTestAddress);
when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(DEFAULT_USING_BPF_OFFLOAD);
when(mTetherConfig.useLegacyDhcpServer()).thenReturn(false /* default value */);
@@ -428,7 +431,8 @@ public class IpServerTest {
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
InOrder inOrder = inOrder(mCallback, mNetd, mAddressCoordinator);
if (isAtLeastT()) {
inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(), eq(true));
inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(),
eq(CONNECTIVITY_SCOPE_GLOBAL), eq(true));
inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
}
@@ -477,7 +481,8 @@ public class IpServerTest {
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
InOrder inOrder = inOrder(mCallback, mNetd, mAddressCoordinator);
inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(), eq(true));
inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(),
eq(CONNECTIVITY_SCOPE_GLOBAL), eq(true));
inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
@@ -498,7 +503,8 @@ public class IpServerTest {
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
InOrder inOrder = inOrder(mCallback, mNetd, mAddressCoordinator);
inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(), eq(true));
inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(),
eq(CONNECTIVITY_SCOPE_LOCAL), eq(true));
inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
IFACE_NAME.equals(cfg.ifName) && assertNotContainsFlag(cfg.flags, IF_STATE_UP)));
inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
@@ -766,7 +772,8 @@ public class IpServerTest {
final ArgumentCaptor<LinkProperties> lpCaptor =
ArgumentCaptor.forClass(LinkProperties.class);
InOrder inOrder = inOrder(mNetd, mCallback, mAddressCoordinator);
inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(), eq(true));
inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(),
eq(CONNECTIVITY_SCOPE_LOCAL), eq(true));
inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
// One for ipv4 route, one for ipv6 link local route.
inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
@@ -779,12 +786,13 @@ public class IpServerTest {
// Simulate the DHCP server receives DHCPDECLINE on MirrorLink and then signals
// onNewPrefixRequest callback.
final LinkAddress newAddress = new LinkAddress("192.168.100.125/24");
when(mAddressCoordinator.requestDownstreamAddress(any(), anyBoolean())).thenReturn(
newAddress);
when(mAddressCoordinator.requestDownstreamAddress(any(), anyInt(),
anyBoolean())).thenReturn(newAddress);
eventCallbacks.onNewPrefixRequest(new IpPrefix("192.168.42.0/24"));
mLooper.dispatchAll();
inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(), eq(false));
inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(),
eq(CONNECTIVITY_SCOPE_LOCAL), eq(false));
inOrder.verify(mNetd).tetherApplyDnsInterfaces();
inOrder.verify(mCallback).updateLinkProperties(eq(mIpServer), lpCaptor.capture());
verifyNoMoreInteractions(mCallback);

View File

@@ -19,6 +19,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_LOCAL;
import static android.net.TetheringManager.TETHERING_ETHERNET;
import static android.net.TetheringManager.TETHERING_USB;
import static android.net.TetheringManager.TETHERING_WIFI;
@@ -61,6 +63,7 @@ public final class PrivateAddressCoordinatorTest {
private static final String TEST_IFNAME = "test0";
@Mock private IpServer mHotspotIpServer;
@Mock private IpServer mLocalHotspotIpServer;
@Mock private IpServer mUsbIpServer;
@Mock private IpServer mEthernetIpServer;
@Mock private IpServer mWifiP2pIpServer;
@@ -90,6 +93,7 @@ public final class PrivateAddressCoordinatorTest {
when(mUsbIpServer.interfaceType()).thenReturn(TETHERING_USB);
when(mEthernetIpServer.interfaceType()).thenReturn(TETHERING_ETHERNET);
when(mHotspotIpServer.interfaceType()).thenReturn(TETHERING_WIFI);
when(mLocalHotspotIpServer.interfaceType()).thenReturn(TETHERING_WIFI);
when(mWifiP2pIpServer.interfaceType()).thenReturn(TETHERING_WIFI_P2P);
}
@@ -104,9 +108,10 @@ public final class PrivateAddressCoordinatorTest {
mPrivateAddressCoordinator = spy(new PrivateAddressCoordinator(mContext, mConfig));
}
private LinkAddress requestDownstreamAddress(final IpServer ipServer, boolean useLastAddress) {
private LinkAddress requestDownstreamAddress(final IpServer ipServer, int scope,
boolean useLastAddress) {
final LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress(
ipServer, useLastAddress);
ipServer, scope, useLastAddress);
when(ipServer.getAddress()).thenReturn(address);
return address;
}
@@ -115,19 +120,19 @@ public final class PrivateAddressCoordinatorTest {
public void testRequestDownstreamAddressWithoutUsingLastAddress() throws Exception {
final IpPrefix bluetoothPrefix = asIpPrefix(mBluetoothAddress);
final LinkAddress address = requestDownstreamAddress(mHotspotIpServer,
false /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, false /* useLastAddress */);
final IpPrefix hotspotPrefix = asIpPrefix(address);
assertNotEquals(hotspotPrefix, bluetoothPrefix);
final LinkAddress newAddress = requestDownstreamAddress(mHotspotIpServer,
false /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, false /* useLastAddress */);
final IpPrefix testDupRequest = asIpPrefix(newAddress);
assertNotEquals(hotspotPrefix, testDupRequest);
assertNotEquals(bluetoothPrefix, testDupRequest);
mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
final LinkAddress usbAddress = requestDownstreamAddress(mUsbIpServer,
false /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, false /* useLastAddress */);
final IpPrefix usbPrefix = asIpPrefix(usbAddress);
assertNotEquals(usbPrefix, bluetoothPrefix);
assertNotEquals(usbPrefix, hotspotPrefix);
@@ -139,25 +144,28 @@ public final class PrivateAddressCoordinatorTest {
int fakeSubAddr = 0x2b00; // 43.0.
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeSubAddr);
LinkAddress actualAddress = requestDownstreamAddress(mHotspotIpServer,
false /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, false /* useLastAddress */);
assertEquals(new LinkAddress("192.168.43.2/24"), actualAddress);
mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
fakeSubAddr = 0x2d01; // 45.1.
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeSubAddr);
actualAddress = requestDownstreamAddress(mHotspotIpServer, false /* useLastAddress */);
actualAddress = requestDownstreamAddress(mHotspotIpServer,
CONNECTIVITY_SCOPE_GLOBAL, false /* useLastAddress */);
assertEquals(new LinkAddress("192.168.45.2/24"), actualAddress);
mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
fakeSubAddr = 0x2eff; // 46.255.
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeSubAddr);
actualAddress = requestDownstreamAddress(mHotspotIpServer, false /* useLastAddress */);
actualAddress = requestDownstreamAddress(mHotspotIpServer,
CONNECTIVITY_SCOPE_GLOBAL, false /* useLastAddress */);
assertEquals(new LinkAddress("192.168.46.254/24"), actualAddress);
mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
fakeSubAddr = 0x2f05; // 47.5.
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeSubAddr);
actualAddress = requestDownstreamAddress(mHotspotIpServer, false /* useLastAddress */);
actualAddress = requestDownstreamAddress(mHotspotIpServer,
CONNECTIVITY_SCOPE_GLOBAL, false /* useLastAddress */);
assertEquals(new LinkAddress("192.168.47.5/24"), actualAddress);
mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
}
@@ -168,7 +176,7 @@ public final class PrivateAddressCoordinatorTest {
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(
getSubAddress(mBluetoothAddress.getAddress().getAddress()));
final LinkAddress hotspotAddress = requestDownstreamAddress(mHotspotIpServer,
false /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, false /* useLastAddress */);
final IpPrefix hotspotPrefix = asIpPrefix(hotspotAddress);
assertNotEquals(asIpPrefix(mBluetoothAddress), hotspotPrefix);
mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
@@ -177,7 +185,7 @@ public final class PrivateAddressCoordinatorTest {
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(
getSubAddress(hotspotAddress.getAddress().getAddress()));
final LinkAddress usbAddress = requestDownstreamAddress(mUsbIpServer,
false /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, false /* useLastAddress */);
final IpPrefix usbPrefix = asIpPrefix(usbAddress);
assertNotEquals(asIpPrefix(mBluetoothAddress), usbPrefix);
assertNotEquals(hotspotPrefix, usbPrefix);
@@ -187,7 +195,7 @@ public final class PrivateAddressCoordinatorTest {
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(
getSubAddress(mLegacyWifiP2pAddress.getAddress().getAddress()));
final LinkAddress etherAddress = requestDownstreamAddress(mEthernetIpServer,
false /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, false /* useLastAddress */);
final IpPrefix etherPrefix = asIpPrefix(etherAddress);
assertNotEquals(asIpPrefix(mLegacyWifiP2pAddress), etherPrefix);
assertNotEquals(asIpPrefix(mBluetoothAddress), etherPrefix);
@@ -200,11 +208,11 @@ public final class PrivateAddressCoordinatorTest {
final int fakeHotspotSubAddr = 0x2b05; // 43.5
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeHotspotSubAddr);
final LinkAddress hotspotAddress = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong wifi prefix: ", new LinkAddress("192.168.43.5/24"), hotspotAddress);
final LinkAddress usbAddress = requestDownstreamAddress(mUsbIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong wifi prefix: ", new LinkAddress("192.168.45.5/24"), usbAddress);
mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
@@ -214,10 +222,10 @@ public final class PrivateAddressCoordinatorTest {
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeHotspotSubAddr);
final LinkAddress newHotspotAddress = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals(hotspotAddress, newHotspotAddress);
final LinkAddress newUsbAddress = requestDownstreamAddress(mUsbIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals(usbAddress, newUsbAddress);
final UpstreamNetworkState wifiUpstream = buildUpstreamNetworkState(mWifiNetwork,
@@ -257,7 +265,7 @@ public final class PrivateAddressCoordinatorTest {
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeHotspotSubAddr);
// - Enable hotspot with prefix 192.168.43.0/24
final LinkAddress hotspotAddr = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
final IpPrefix hotspotPrefix = asIpPrefix(hotspotAddr);
assertEquals("Wrong wifi prefix: ", predefinedPrefix, hotspotPrefix);
// - test mobile network with null NetworkCapabilities. Ideally this should not happen
@@ -311,21 +319,21 @@ public final class PrivateAddressCoordinatorTest {
// - Restart hotspot again and its prefix is different previous.
mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer);
final LinkAddress hotspotAddr2 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
final IpPrefix hotspotPrefix2 = asIpPrefix(hotspotAddr2);
assertNotEquals(hotspotPrefix, hotspotPrefix2);
mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyWifi);
verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT);
// - Usb tethering can be enabled and its prefix is different with conflict one.
final LinkAddress usbAddr = requestDownstreamAddress(mUsbIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
final IpPrefix usbPrefix = asIpPrefix(usbAddr);
assertNotEquals(predefinedPrefix, usbPrefix);
assertNotEquals(hotspotPrefix2, usbPrefix);
// - Disable wifi upstream, then wifi's prefix can be selected again.
mPrivateAddressCoordinator.removeUpstreamPrefix(mWifiNetwork);
final LinkAddress ethAddr = requestDownstreamAddress(mEthernetIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
final IpPrefix ethPrefix = asIpPrefix(ethAddr);
assertEquals(predefinedPrefix, ethPrefix);
}
@@ -335,7 +343,7 @@ public final class PrivateAddressCoordinatorTest {
final int randomAddress = 0x8605; // 134.5
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(randomAddress);
final LinkAddress addr0 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
// Check whether return address is prefix 192.168.0.0/16 + subAddress 0.0.134.5.
assertEquals("Wrong prefix: ", new LinkAddress("192.168.134.5/24"), addr0);
final UpstreamNetworkState wifiUpstream = buildUpstreamNetworkState(mWifiNetwork,
@@ -345,7 +353,7 @@ public final class PrivateAddressCoordinatorTest {
// Check whether return address is next prefix of 192.168.134.0/24.
final LinkAddress addr1 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("192.168.135.5/24"), addr1);
final UpstreamNetworkState wifiUpstream2 = buildUpstreamNetworkState(mWifiNetwork,
new LinkAddress("192.168.149.16/19"), null,
@@ -355,7 +363,7 @@ public final class PrivateAddressCoordinatorTest {
// The conflict range is 128 ~ 159, so the address is 192.168.160.5/24.
final LinkAddress addr2 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("192.168.160.5/24"), addr2);
final UpstreamNetworkState mobileUpstream = buildUpstreamNetworkState(mMobileNetwork,
new LinkAddress("192.168.129.53/18"), null,
@@ -370,7 +378,7 @@ public final class PrivateAddressCoordinatorTest {
// The conflict range are 128 ~ 159 and 159 ~ 191, so the address is 192.168.192.5/24.
final LinkAddress addr3 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("192.168.192.5/24"), addr3);
final UpstreamNetworkState mobileUpstream3 = buildUpstreamNetworkState(mMobileNetwork3,
new LinkAddress("192.168.188.133/17"), null,
@@ -380,7 +388,7 @@ public final class PrivateAddressCoordinatorTest {
// Conflict range: 128 ~ 255. The next available address is 192.168.0.5 because
// 192.168.134/24 ~ 192.168.255.255/24 is not available.
final LinkAddress addr4 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("192.168.0.5/24"), addr4);
final UpstreamNetworkState mobileUpstream4 = buildUpstreamNetworkState(mMobileNetwork4,
new LinkAddress("192.168.3.59/21"), null,
@@ -389,7 +397,7 @@ public final class PrivateAddressCoordinatorTest {
// Conflict ranges: 128 ~ 255 and 0 ~ 7, so the address is 192.168.8.5/24.
final LinkAddress addr5 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("192.168.8.5/24"), addr5);
final UpstreamNetworkState mobileUpstream5 = buildUpstreamNetworkState(mMobileNetwork5,
new LinkAddress("192.168.68.43/21"), null,
@@ -399,7 +407,7 @@ public final class PrivateAddressCoordinatorTest {
// Update an upstream that does *not* conflict, check whether return the same address
// 192.168.5/24.
final LinkAddress addr6 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("192.168.8.5/24"), addr6);
final UpstreamNetworkState mobileUpstream6 = buildUpstreamNetworkState(mMobileNetwork6,
new LinkAddress("192.168.10.97/21"), null,
@@ -408,7 +416,7 @@ public final class PrivateAddressCoordinatorTest {
// Conflict ranges: 0 ~ 15 and 128 ~ 255, so the address is 192.168.16.5/24.
final LinkAddress addr7 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("192.168.16.5/24"), addr7);
final UpstreamNetworkState mobileUpstream7 = buildUpstreamNetworkState(mMobileNetwork6,
new LinkAddress("192.168.0.0/17"), null,
@@ -417,7 +425,7 @@ public final class PrivateAddressCoordinatorTest {
// Choose prefix from next range(172.16.0.0/12) when no available prefix in 192.168.0.0/16.
final LinkAddress addr8 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("172.16.134.5/24"), addr8);
}
@@ -426,7 +434,7 @@ public final class PrivateAddressCoordinatorTest {
final int randomAddress = 0x1f2b2a; // 31.43.42
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(randomAddress);
final LinkAddress classC1 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
// Check whether return address is prefix 192.168.0.0/16 + subAddress 0.0.43.42.
assertEquals("Wrong prefix: ", new LinkAddress("192.168.43.42/24"), classC1);
final UpstreamNetworkState wifiUpstream = buildUpstreamNetworkState(mWifiNetwork,
@@ -437,7 +445,7 @@ public final class PrivateAddressCoordinatorTest {
// Check whether return address is next address of prefix 192.168.128.0/17.
final LinkAddress classC2 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("192.168.128.42/24"), classC2);
final UpstreamNetworkState mobileUpstream = buildUpstreamNetworkState(mMobileNetwork,
new LinkAddress("192.1.2.3/8"), null,
@@ -447,7 +455,7 @@ public final class PrivateAddressCoordinatorTest {
// Check whether return address is under prefix 172.16.0.0/12.
final LinkAddress classB1 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("172.31.43.42/24"), classB1);
final UpstreamNetworkState mobileUpstream2 = buildUpstreamNetworkState(mMobileNetwork2,
new LinkAddress("172.28.123.100/14"), null,
@@ -458,12 +466,12 @@ public final class PrivateAddressCoordinatorTest {
// 172.28.0.0 ~ 172.31.255.255 is not available.
// Check whether return address is next address of prefix 172.16.0.0/14.
final LinkAddress classB2 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("172.16.0.42/24"), classB2);
// Check whether new downstream is next address of address 172.16.0.42/24.
final LinkAddress classB3 = requestDownstreamAddress(mUsbIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("172.16.1.42/24"), classB3);
final UpstreamNetworkState mobileUpstream3 = buildUpstreamNetworkState(mMobileNetwork3,
new LinkAddress("172.16.0.1/24"), null,
@@ -474,7 +482,7 @@ public final class PrivateAddressCoordinatorTest {
// Check whether return address is next address of prefix 172.16.1.42/24.
final LinkAddress classB4 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("172.16.2.42/24"), classB4);
final UpstreamNetworkState mobileUpstream4 = buildUpstreamNetworkState(mMobileNetwork4,
new LinkAddress("172.16.0.1/13"), null,
@@ -485,11 +493,11 @@ public final class PrivateAddressCoordinatorTest {
// Check whether return address is next address of prefix 172.16.0.1/13.
final LinkAddress classB5 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("172.24.0.42/24"), classB5);
// Check whether return address is next address of prefix 172.24.0.42/24.
final LinkAddress classB6 = requestDownstreamAddress(mUsbIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("172.24.1.42/24"), classB6);
final UpstreamNetworkState mobileUpstream5 = buildUpstreamNetworkState(mMobileNetwork5,
new LinkAddress("172.24.0.1/12"), null,
@@ -500,11 +508,11 @@ public final class PrivateAddressCoordinatorTest {
// Check whether return address is prefix 10.0.0.0/8 + subAddress 0.31.43.42.
final LinkAddress classA1 = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("10.31.43.42/24"), classA1);
// Check whether new downstream is next address of address 10.31.43.42/24.
final LinkAddress classA2 = requestDownstreamAddress(mUsbIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong prefix: ", new LinkAddress("10.31.44.42/24"), classA2);
}
@@ -524,7 +532,7 @@ public final class PrivateAddressCoordinatorTest {
private void assertReseveredWifiP2pPrefix() throws Exception {
LinkAddress address = requestDownstreamAddress(mHotspotIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
final IpPrefix hotspotPrefix = asIpPrefix(address);
final IpPrefix legacyWifiP2pPrefix = asIpPrefix(mLegacyWifiP2pAddress);
assertNotEquals(legacyWifiP2pPrefix, hotspotPrefix);
@@ -544,8 +552,23 @@ public final class PrivateAddressCoordinatorTest {
// If #shouldEnableWifiP2pDedicatedIp() is enabled, wifi P2P gets the configured address.
LinkAddress address = requestDownstreamAddress(mWifiP2pIpServer,
true /* useLastAddress */);
CONNECTIVITY_SCOPE_LOCAL, true /* useLastAddress */);
assertEquals(mLegacyWifiP2pAddress, address);
mPrivateAddressCoordinator.releaseDownstream(mWifiP2pIpServer);
}
@Test
public void testEnableSapAndLohsConcurrently() throws Exception {
// 0x2b05 -> 43.5, 0x8605 -> 134.5
when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(0x2b05, 0x8605);
final LinkAddress hotspotAddress = requestDownstreamAddress(mHotspotIpServer,
CONNECTIVITY_SCOPE_GLOBAL, true /* useLastAddress */);
assertEquals("Wrong hotspot prefix: ", new LinkAddress("192.168.43.5/24"), hotspotAddress);
final LinkAddress localHotspotAddress = requestDownstreamAddress(mLocalHotspotIpServer,
CONNECTIVITY_SCOPE_LOCAL, true /* useLastAddress */);
assertEquals("Wrong local hotspot prefix: ", new LinkAddress("192.168.134.5/24"),
localHotspotAddress);
}
}