diff options
-rw-r--r-- | src/android/net/ip/IpClient.java | 19 | ||||
-rw-r--r-- | tests/integration/src/android/net/ip/IpClientIntegrationTest.java | 37 | ||||
-rw-r--r-- | tests/unit/src/android/net/ip/IpClientTest.java | 6 |
3 files changed, 48 insertions, 14 deletions
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java index ebb31c6..74a4070 100644 --- a/src/android/net/ip/IpClient.java +++ b/src/android/net/ip/IpClient.java @@ -765,14 +765,6 @@ public class IpClient extends StateMachine { return; } - mInterfaceParams = mDependencies.getInterfaceParams(mInterfaceName); - if (mInterfaceParams == null) { - logError("Failed to find InterfaceParams for " + mInterfaceName); - doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND); - return; - } - - mCallback.setNeighborDiscoveryOffload(true); sendMessage(CMD_START, new android.net.shared.ProvisioningConfiguration(req)); } @@ -1636,6 +1628,17 @@ public class IpClient extends StateMachine { // tethering or during an IpClient restart. stopAllIP(); } + + // Ensure that interface parameters are fetched on the handler thread so they are + // properly ordered with other events, such as restoring the interface MTU on teardown. + mInterfaceParams = mDependencies.getInterfaceParams(mInterfaceName); + if (mInterfaceParams == null) { + logError("Failed to find InterfaceParams for " + mInterfaceName); + doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND); + transitionTo(mStoppedState); + return; + } + mCallback.setNeighborDiscoveryOffload(true); } @Override diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java index f60e311..9f0ef99 100644 --- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java +++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java @@ -525,7 +525,6 @@ public class IpClientIntegrationTest { mDependencies.setHostnameConfiguration(isHostnameConfigurationEnabled, hostname); mIpc.setL2KeyAndGroupHint(TEST_L2KEY, TEST_GROUPHINT); mIpc.startProvisioning(builder.build()); - verify(mCb).setNeighborDiscoveryOffload(true); if (!isPreconnectionEnabled) { verify(mCb, timeout(TEST_TIMEOUT_MS)).setFallbackMulticastFilter(false); } @@ -643,7 +642,6 @@ public class IpClientIntegrationTest { ArgumentCaptor.forClass(LinkProperties.class); verifyProvisioningSuccess(captor, Collections.singletonList(CLIENT_ADDR)); } - return packetList; } } @@ -732,6 +730,12 @@ public class IpClientIntegrationTest { assertEquals(NetworkInterface.getByName(mIfaceName).getMTU(), mtu); } + // Sometimes, IpClient receives an update with an empty LinkProperties during startup, + // when the link-local address is deleted after interface bringup. Reset expectations + // here to ensure that verifyAfterIpClientShutdown does not fail because it sees two + // empty LinkProperties changes instead of one. + reset(mCb); + if (shouldRemoveTapInterface) removeTapInterface(mTapFd); try { mIpc.shutdown(); @@ -1096,10 +1100,37 @@ public class IpClientIntegrationTest { .build(); mIpc.startProvisioning(config); - verify(mCb).onProvisioningFailure(any()); + verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningFailure(any()); verify(mCb, never()).setNeighborDiscoveryOffload(true); } + @Test + public void testRestoreInitialInterfaceMtu_stopIpClientAndRestart() throws Exception { + long currentTime = System.currentTimeMillis(); + + performDhcpHandshake(true /* isSuccessLease */, TEST_LEASE_DURATION_S, + true /* isDhcpLeaseCacheEnabled */, false /* shouldReplyRapidCommitAck */, + TEST_MIN_MTU, false /* isDhcpIpConflictDetectEnabled */); + assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime, TEST_MIN_MTU); + + // Pretend that ConnectivityService set the MTU. + mNetd.interfaceSetMtu(mIfaceName, TEST_MIN_MTU); + assertEquals(NetworkInterface.getByName(mIfaceName).getMTU(), TEST_MIN_MTU); + + reset(mCb); + reset(mIpMemoryStore); + + // Stop IpClient and then restart provisioning immediately. + mIpc.stop(); + currentTime = System.currentTimeMillis(); + // Intend to set mtu option to 0, then verify that won't influence interface mtu restore. + performDhcpHandshake(true /* isSuccessLease */, TEST_LEASE_DURATION_S, + true /* isDhcpLeaseCacheEnabled */, false /* shouldReplyRapidCommitAck */, + 0 /* mtu */, false /* isDhcpIpConflictDetectEnabled */); + assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime, 0 /* mtu */); + assertEquals(NetworkInterface.getByName(mIfaceName).getMTU(), TEST_DEFAULT_MTU); + } + private boolean isRouterSolicitation(final byte[] packetBytes) { ByteBuffer packet = ByteBuffer.wrap(packetBytes); return packet.getShort(ETHER_TYPE_OFFSET) == (short) ETH_P_IPV6 diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java index 4be5442..5fa5a6c 100644 --- a/tests/unit/src/android/net/ip/IpClientTest.java +++ b/tests/unit/src/android/net/ip/IpClientTest.java @@ -221,7 +221,7 @@ public class IpClientTest { final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mObserverRegistry, mNetworkStackServiceManager, mDependencies); ipc.startProvisioning(new ProvisioningConfiguration()); - verify(mCb, times(1)).onProvisioningFailure(any()); + verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningFailure(any()); verify(mIpMemoryStore, never()).storeNetworkAttributes(any(), any(), any()); ipc.shutdown(); } @@ -249,7 +249,7 @@ public class IpClientTest { .build(); ipc.startProvisioning(config); - verify(mCb, times(1)).setNeighborDiscoveryOffload(true); + verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setNeighborDiscoveryOffload(true); verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false); final LinkProperties lp = makeIPv6ProvisionedLinkProperties(); @@ -364,7 +364,7 @@ public class IpClientTest { .build(); ipc.startProvisioning(config); - verify(mCb, times(1)).setNeighborDiscoveryOffload(true); + verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setNeighborDiscoveryOffload(true); verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false); verify(mCb, never()).onProvisioningFailure(any()); ipc.setL2KeyAndGroupHint(l2Key, groupHint); |