diff options
author | Xiao Ma <xiaom@google.com> | 2020-05-07 12:26:24 +0000 |
---|---|---|
committer | Xiao Ma <xiaom@google.com> | 2020-05-07 13:28:00 +0000 |
commit | 1eb4c9d55b8e15badb58d0531c1b20c54a54d0f8 (patch) | |
tree | a50dc869bd64955803682b6b71dd074272b75b59 | |
parent | b12790b92269c9810122c414d77a592f9f17cc35 (diff) |
Fix the potential NPE when starting provisioning with FILS.
Starting provisioning with enabled FILS is unlike the normal case
that always happens after L2 connection has been established, at
this point we already know the current bssid. However, for FILS
connection, the current bssid is still null when starting prov.
Bug: 155696520
Test: atest NetworkStackTests NetworkStackIntegrationTests
Merged-In: I3c29c6ad95c23cea2b3f374fb9dc35a8f54a6427
Change-Id: I3c29c6ad95c23cea2b3f374fb9dc35a8f54a6427
-rw-r--r-- | common/moduleutils/src/android/net/shared/Layer2Information.java | 9 | ||||
-rw-r--r-- | tests/integration/src/android/net/ip/IpClientIntegrationTest.java | 45 |
2 files changed, 43 insertions, 11 deletions
diff --git a/common/moduleutils/src/android/net/shared/Layer2Information.java b/common/moduleutils/src/android/net/shared/Layer2Information.java index 6825a93..fa4f102 100644 --- a/common/moduleutils/src/android/net/shared/Layer2Information.java +++ b/common/moduleutils/src/android/net/shared/Layer2Information.java @@ -16,6 +16,7 @@ package android.net.shared; +import android.annotation.Nullable; import android.net.Layer2InformationParcelable; import android.net.MacAddress; @@ -23,14 +24,18 @@ import java.util.Objects; /** @hide */ public class Layer2Information { + @Nullable public final String mL2Key; + @Nullable public final String mGroupHint; + @Nullable public final MacAddress mBssid; /** * Create a Layer2Information with the specified configuration. */ - public Layer2Information(String l2Key, String groupHint, MacAddress bssid) { + public Layer2Information(@Nullable final String l2Key, @Nullable final String groupHint, + @Nullable final MacAddress bssid) { mL2Key = l2Key; mGroupHint = groupHint; mBssid = bssid; @@ -41,7 +46,7 @@ public class Layer2Information { StringBuffer str = new StringBuffer(); str.append("L2Key: ").append(mL2Key); str.append(", GroupHint: ").append(mGroupHint); - str.append(", bssid: ").append(mBssid.toString()); + str.append(", bssid: ").append(mBssid); return str.toString(); } diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java index 4a3f445..fc51065 100644 --- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java +++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java @@ -830,27 +830,32 @@ public class IpClientIntegrationTest { } } + private DhcpPacket assertDiscoverPacketOnPreconnectionStart() throws Exception { + final ArgumentCaptor<List<Layer2PacketParcelable>> l2PacketList = + ArgumentCaptor.forClass(List.class); + + verify(mCb, timeout(TEST_TIMEOUT_MS)).onPreconnectionStart(l2PacketList.capture()); + final byte[] payload = l2PacketList.getValue().get(0).payload; + DhcpPacket packet = DhcpPacket.decodeFullPacket(payload, payload.length, ENCAP_L2); + assertTrue(packet instanceof DhcpDiscoverPacket); + assertArrayEquals(INADDR_BROADCAST.getAddress(), + Arrays.copyOfRange(payload, IPV4_DST_ADDR_OFFSET, IPV4_DST_ADDR_OFFSET + 4)); + return packet; + } + private void doIpClientProvisioningWithPreconnectionTest( final boolean shouldReplyRapidCommitAck, final boolean shouldAbortPreconnection, final boolean shouldFirePreconnectionTimeout, final boolean timeoutBeforePreconnectionComplete) throws Exception { final long currentTime = System.currentTimeMillis(); - final ArgumentCaptor<List<Layer2PacketParcelable>> l2PacketList = - ArgumentCaptor.forClass(List.class); final ArgumentCaptor<InterfaceConfigurationParcel> ifConfig = ArgumentCaptor.forClass(InterfaceConfigurationParcel.class); startIpClientProvisioning(true /* isDhcpLeaseCacheEnabled */, shouldReplyRapidCommitAck, true /* isDhcpPreConnectionEnabled */, false /* isDhcpIpConflictDetectEnabled */); - verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)) - .onPreconnectionStart(l2PacketList.capture()); - final byte[] payload = l2PacketList.getValue().get(0).payload; - DhcpPacket packet = DhcpPacket.decodeFullPacket(payload, payload.length, ENCAP_L2); + DhcpPacket packet = assertDiscoverPacketOnPreconnectionStart(); final int preconnDiscoverTransId = packet.getTransactionId(); - assertTrue(packet instanceof DhcpDiscoverPacket); - assertArrayEquals(INADDR_BROADCAST.getAddress(), - Arrays.copyOfRange(payload, IPV4_DST_ADDR_OFFSET, IPV4_DST_ADDR_OFFSET + 4)); if (shouldAbortPreconnection) { if (shouldFirePreconnectionTimeout && timeoutBeforePreconnectionComplete) { @@ -1714,6 +1719,28 @@ public class IpClientIntegrationTest { } @Test + public void testDhcpClientPreconnection_WithoutLayer2InfoWhenStartingProv() throws Exception { + // For FILS connection, current bssid (also l2key and grouphint) is still null when + // starting provisioning since the L2 link hasn't been established yet. Ensure that + // IpClient won't crash even if initializing an Layer2Info class with null members. + ProvisioningConfiguration.Builder prov = new ProvisioningConfiguration.Builder() + .withoutIpReachabilityMonitor() + .withoutIPv6() + .withPreconnection() + .withLayer2Information(new Layer2Information(null /* l2key */, null /* grouphint */, + null /* bssid */)); + + mIpc.startProvisioning(prov.build()); + assertDiscoverPacketOnPreconnectionStart(); + verify(mCb).setNeighborDiscoveryOffload(true); + + // Force IpClient transition to RunningState from PreconnectionState. + mIpc.notifyPreconnectionComplete(false /* success */); + HandlerUtilsKt.waitForIdle(mDependencies.mDhcpClient.getHandler(), TEST_TIMEOUT_MS); + verify(mCb, timeout(TEST_TIMEOUT_MS)).setFallbackMulticastFilter(false); + } + + @Test public void testDhcpDecline_conflictByArpReply() throws Exception { doIpAddressConflictDetectionTest(true /* causeIpAddressConflict */, false /* shouldReplyRapidCommitAck */, true /* isDhcpIpConflictDetectEnabled */, |