summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiao Ma <xiaom@google.com>2019-07-24 16:27:50 +0900
committerXiao Ma <xiaom@google.com>2019-12-11 11:26:49 +0900
commit859ceabd04daece392d42d37dbc2092cb88996f1 (patch)
tree2a2adec6473fee85f7aff6971238eb58beaff56e
parent762f239387423bf2250139f49972d2afa14c7428 (diff)
Add Rapid Commit option support in DHCP Server side.
Bug:136216415 Test: atest FrameworksNetTests NetworkStackTests Test: atest NetworkStackIntegrationTests Test: manual tethering Change-Id: I0f9483c72374bab271eb18549a1a41812f32f2dd
-rw-r--r--src/android/net/dhcp/DhcpAckPacket.java8
-rw-r--r--src/android/net/dhcp/DhcpClient.java3
-rw-r--r--src/android/net/dhcp/DhcpDiscoverPacket.java3
-rw-r--r--src/android/net/dhcp/DhcpLeaseRepository.java19
-rw-r--r--src/android/net/dhcp/DhcpPacket.java13
-rw-r--r--src/android/net/dhcp/DhcpServer.java62
-rw-r--r--src/android/net/util/NetworkStackUtils.java9
-rw-r--r--src/com/android/server/NetworkStackService.java1
-rw-r--r--tests/integration/src/android/net/ip/IpClientIntegrationTest.java35
-rw-r--r--tests/unit/src/android/net/dhcp/DhcpServerTest.java27
10 files changed, 120 insertions, 60 deletions
diff --git a/src/android/net/dhcp/DhcpAckPacket.java b/src/android/net/dhcp/DhcpAckPacket.java
index 052af35..9e981ef 100644
--- a/src/android/net/dhcp/DhcpAckPacket.java
+++ b/src/android/net/dhcp/DhcpAckPacket.java
@@ -30,10 +30,12 @@ public class DhcpAckPacket extends DhcpPacket {
private final Inet4Address mSrcIp;
DhcpAckPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress,
- Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
+ Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac,
+ boolean rapidCommit) {
super(transId, secs, clientIp, yourIp, serverAddress, relayIp, clientMac, broadcast);
mBroadcast = broadcast;
mSrcIp = serverAddress;
+ mRapidCommit = rapidCommit;
}
public String toString() {
@@ -70,8 +72,10 @@ public class DhcpAckPacket extends DhcpPacket {
void finishPacket(ByteBuffer buffer) {
addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_ACK);
addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-
addCommonServerTlvs(buffer);
+ if (mRapidCommit) {
+ addTlv(buffer, DHCP_RAPID_COMMIT);
+ }
addTlvEnd(buffer);
}
diff --git a/src/android/net/dhcp/DhcpClient.java b/src/android/net/dhcp/DhcpClient.java
index e7d53ee..dc0175e 100644
--- a/src/android/net/dhcp/DhcpClient.java
+++ b/src/android/net/dhcp/DhcpClient.java
@@ -1171,7 +1171,8 @@ public class DhcpClient extends StateMachine {
final DhcpResults results = packet.toDhcpResults();
if (results != null) {
confirmDhcpLease(packet, results);
- transitionTo(mConfiguringInterfaceState);
+ transitionTo(isDhcpIpConflictDetectEnabled()
+ ? mIpAddressConflictDetectingState : mConfiguringInterfaceState);
}
}
}
diff --git a/src/android/net/dhcp/DhcpDiscoverPacket.java b/src/android/net/dhcp/DhcpDiscoverPacket.java
index a749796..15c20cf 100644
--- a/src/android/net/dhcp/DhcpDiscoverPacket.java
+++ b/src/android/net/dhcp/DhcpDiscoverPacket.java
@@ -32,9 +32,10 @@ public class DhcpDiscoverPacket extends DhcpPacket {
* Generates a DISCOVER packet with the specified parameters.
*/
DhcpDiscoverPacket(int transId, short secs, Inet4Address relayIp, byte[] clientMac,
- boolean broadcast, Inet4Address srcIp) {
+ boolean broadcast, Inet4Address srcIp, boolean rapidCommit) {
super(transId, secs, INADDR_ANY, INADDR_ANY, INADDR_ANY, relayIp, clientMac, broadcast);
mSrcIp = srcIp;
+ mRapidCommit = rapidCommit;
}
public String toString() {
diff --git a/src/android/net/dhcp/DhcpLeaseRepository.java b/src/android/net/dhcp/DhcpLeaseRepository.java
index d22193b..4e74dc8 100644
--- a/src/android/net/dhcp/DhcpLeaseRepository.java
+++ b/src/android/net/dhcp/DhcpLeaseRepository.java
@@ -190,6 +190,25 @@ class DhcpLeaseRepository {
return newLease;
}
+ /**
+ * Get a rapid committed DHCP Lease, to reply to a DHCPDISCOVER w/ Rapid Commit option.
+ *
+ * @param clientId Client identifier option if specified, or {@link #CLIENTID_UNSPEC}
+ * @param relayAddr Internet address of the relay (giaddr), can be {@link Inet4Address#ANY}
+ * @param hostname Client-provided hostname, or {@link DhcpLease#HOSTNAME_NONE}
+ * @throws OutOfAddressesException The server does not have any available address
+ * @throws InvalidSubnetException The lease was requested from an unsupported subnet
+ */
+ @NonNull
+ public DhcpLease getCommittedLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
+ @NonNull Inet4Address relayAddr, @Nullable String hostname)
+ throws OutOfAddressesException, InvalidSubnetException {
+ final DhcpLease newLease = getOffer(clientId, hwAddr, relayAddr, null /* reqAddr */,
+ hostname);
+ commitLease(newLease);
+ return newLease;
+ }
+
private void checkValidRelayAddr(@Nullable Inet4Address relayAddr)
throws InvalidSubnetException {
// As per #4.3.1, addresses are assigned based on the relay address if present. This
diff --git a/src/android/net/dhcp/DhcpPacket.java b/src/android/net/dhcp/DhcpPacket.java
index 5ab769b..c5700b3 100644
--- a/src/android/net/dhcp/DhcpPacket.java
+++ b/src/android/net/dhcp/DhcpPacket.java
@@ -1179,7 +1179,7 @@ public abstract class DhcpPacket {
"No DHCP message type option");
case DHCP_MESSAGE_TYPE_DISCOVER:
newPacket = new DhcpDiscoverPacket(transactionId, secs, relayIp, clientMac,
- broadcast, ipSrc);
+ broadcast, ipSrc, rapidCommit);
break;
case DHCP_MESSAGE_TYPE_OFFER:
newPacket = new DhcpOfferPacket(
@@ -1196,7 +1196,8 @@ public abstract class DhcpPacket {
break;
case DHCP_MESSAGE_TYPE_ACK:
newPacket = new DhcpAckPacket(
- transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac);
+ transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac,
+ rapidCommit);
break;
case DHCP_MESSAGE_TYPE_NAK:
newPacket = new DhcpNakPacket(
@@ -1238,7 +1239,6 @@ public abstract class DhcpPacket {
newPacket.mT2 = T2;
newPacket.mVendorId = vendorId;
newPacket.mVendorInfo = vendorInfo;
- newPacket.mRapidCommit = rapidCommit;
if ((optionOverload & OPTION_OVERLOAD_SNAME) == 0) {
newPacket.mServerHostName = serverHostName;
} else {
@@ -1330,9 +1330,8 @@ public abstract class DhcpPacket {
short secs, byte[] clientMac, boolean broadcast, byte[] expectedParams,
boolean rapidCommit) {
DhcpPacket pkt = new DhcpDiscoverPacket(transactionId, secs, INADDR_ANY /* relayIp */,
- clientMac, broadcast, INADDR_ANY /* srcIp */);
+ clientMac, broadcast, INADDR_ANY /* srcIp */, rapidCommit);
pkt.mRequestedParams = expectedParams;
- pkt.mRapidCommit = rapidCommit;
return pkt.buildPacket(encap, DHCP_SERVER, DHCP_CLIENT);
}
@@ -1372,10 +1371,10 @@ public abstract class DhcpPacket {
Inet4Address requestClientIp, byte[] mac, Integer timeout, Inet4Address netMask,
Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers,
Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered,
- short mtu) {
+ short mtu, boolean rapidCommit) {
DhcpPacket pkt = new DhcpAckPacket(
transactionId, (short) 0, broadcast, serverIpAddr, relayIp, requestClientIp, yourIp,
- mac);
+ mac, rapidCommit);
pkt.mGateways = gateways;
pkt.mDnsServers = dnsServers;
pkt.mLeaseTime = timeout;
diff --git a/src/android/net/dhcp/DhcpServer.java b/src/android/net/dhcp/DhcpServer.java
index 37dd972..4fc213a 100644
--- a/src/android/net/dhcp/DhcpServer.java
+++ b/src/android/net/dhcp/DhcpServer.java
@@ -22,6 +22,8 @@ import static android.net.dhcp.DhcpPacket.DHCP_SERVER;
import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP;
import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
+import static android.net.util.NetworkStackUtils.DHCP_RAPID_COMMIT_VERSION;
+import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.IPPROTO_UDP;
import static android.system.OsConstants.SOCK_DGRAM;
@@ -38,6 +40,7 @@ import static com.android.server.util.PermissionUtil.enforceNetworkStackCallingP
import static java.lang.Integer.toUnsignedLong;
+import android.content.Context;
import android.net.INetworkStackStatusCallback;
import android.net.MacAddress;
import android.net.TrafficStats;
@@ -92,6 +95,8 @@ public class DhcpServer extends IDhcpServer.Stub {
private static final int CMD_UPDATE_PARAMS = 3;
@NonNull
+ private final Context mContext;
+ @NonNull
private final HandlerThread mHandlerThread;
@NonNull
private final String mIfName;
@@ -107,6 +112,8 @@ public class DhcpServer extends IDhcpServer.Stub {
@Nullable
private volatile ServerHandler mHandler;
+ private final boolean mDhcpRapidCommitEnabled;
+
// Accessed only on the handler thread
@Nullable
private DhcpPacketListener mPacketListener;
@@ -176,6 +183,14 @@ public class DhcpServer extends IDhcpServer.Stub {
* @throws SecurityException The caller is not allowed to call public methods on DhcpServer.
*/
void checkCaller() throws SecurityException;
+
+ /**
+ * Check whether or not one specific experimental feature for connectivity namespace is
+ * enabled.
+ * @param context The global context information about an app environment.
+ * @param name Specific experimental flag name.
+ */
+ boolean isFeatureEnabled(@NonNull Context context, @NonNull String name);
}
private class DependenciesImpl implements Dependencies {
@@ -214,6 +229,11 @@ public class DhcpServer extends IDhcpServer.Stub {
public void checkCaller() {
enforceNetworkStackCallingPermission();
}
+
+ @Override
+ public boolean isFeatureEnabled(@NonNull Context context, @NonNull String name) {
+ return NetworkStackUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name);
+ }
}
private static class MalformedPacketException extends Exception {
@@ -222,19 +242,20 @@ public class DhcpServer extends IDhcpServer.Stub {
}
}
- public DhcpServer(@NonNull String ifName,
+ public DhcpServer(@NonNull Context context, @NonNull String ifName,
@NonNull DhcpServingParams params, @NonNull SharedLog log) {
- this(new HandlerThread(DhcpServer.class.getSimpleName() + "." + ifName),
+ this(context, new HandlerThread(DhcpServer.class.getSimpleName() + "." + ifName),
ifName, params, log, null);
}
@VisibleForTesting
- DhcpServer(@NonNull HandlerThread handlerThread, @NonNull String ifName,
- @NonNull DhcpServingParams params, @NonNull SharedLog log,
+ DhcpServer(@NonNull Context context, @NonNull HandlerThread handlerThread,
+ @NonNull String ifName, @NonNull DhcpServingParams params, @NonNull SharedLog log,
@Nullable Dependencies deps) {
if (deps == null) {
deps = new DependenciesImpl();
}
+ mContext = context;
mHandlerThread = handlerThread;
mIfName = ifName;
mServingParams = params;
@@ -242,6 +263,7 @@ public class DhcpServer extends IDhcpServer.Stub {
mDeps = deps;
mClock = deps.makeClock();
mLeaseRepo = deps.makeLeaseRepository(mServingParams, mLog, mClock);
+ mDhcpRapidCommitEnabled = deps.isFeatureEnabled(context, DHCP_RAPID_COMMIT_VERSION);
}
/**
@@ -388,17 +410,20 @@ public class DhcpServer extends IDhcpServer.Stub {
final DhcpLease lease;
final MacAddress clientMac = getMacAddr(packet);
try {
- lease = mLeaseRepo.getOffer(packet.getExplicitClientIdOrNull(), clientMac,
- packet.mRelayIp, packet.mRequestedIp, packet.mHostName);
+ if (mDhcpRapidCommitEnabled && packet.mRapidCommit) {
+ lease = mLeaseRepo.getCommittedLease(packet.getExplicitClientIdOrNull(), clientMac,
+ packet.mRelayIp, packet.mHostName);
+ transmitAck(packet, lease, clientMac);
+ } else {
+ lease = mLeaseRepo.getOffer(packet.getExplicitClientIdOrNull(), clientMac,
+ packet.mRelayIp, packet.mRequestedIp, packet.mHostName);
+ transmitOffer(packet, lease, clientMac);
+ }
} catch (DhcpLeaseRepository.OutOfAddressesException e) {
transmitNak(packet, "Out of addresses to offer");
- return;
} catch (DhcpLeaseRepository.InvalidSubnetException e) {
logIgnoredPacketInvalidSubnet(e);
- return;
}
-
- transmitOffer(packet, lease, clientMac);
}
private void processRequest(@NonNull DhcpRequestPacket packet) throws MalformedPacketException {
@@ -492,23 +517,24 @@ public class DhcpServer extends IDhcpServer.Stub {
return transmitOfferOrAckPacket(offerPacket, request, lease, clientMac, broadcastFlag);
}
- private boolean transmitAck(@NonNull DhcpPacket request, @NonNull DhcpLease lease,
+ private boolean transmitAck(@NonNull DhcpPacket packet, @NonNull DhcpLease lease,
@NonNull MacAddress clientMac) {
// TODO: replace DhcpPacket's build methods with real builders and use common code with
// transmitOffer above
- final boolean broadcastFlag = getBroadcastFlag(request, lease);
+ final boolean broadcastFlag = getBroadcastFlag(packet, lease);
final int timeout = getLeaseTimeout(lease);
- final String hostname = getHostnameIfRequested(request, lease);
- final ByteBuffer ackPacket = DhcpPacket.buildAckPacket(ENCAP_BOOTP, request.mTransId,
- broadcastFlag, mServingParams.getServerInet4Addr(), request.mRelayIp,
- lease.getNetAddr(), request.mClientIp, request.mClientMac, timeout,
+ final String hostname = getHostnameIfRequested(packet, lease);
+ final ByteBuffer ackPacket = DhcpPacket.buildAckPacket(ENCAP_BOOTP, packet.mTransId,
+ broadcastFlag, mServingParams.getServerInet4Addr(), packet.mRelayIp,
+ lease.getNetAddr(), packet.mClientIp, packet.mClientMac, timeout,
mServingParams.getPrefixMaskAsAddress(), mServingParams.getBroadcastAddress(),
new ArrayList<>(mServingParams.defaultRouters),
new ArrayList<>(mServingParams.dnsServers),
mServingParams.getServerInet4Addr(), null /* domainName */, hostname,
- mServingParams.metered, (short) mServingParams.linkMtu);
+ mServingParams.metered, (short) mServingParams.linkMtu,
+ packet.mRapidCommit && mDhcpRapidCommitEnabled);
- return transmitOfferOrAckPacket(ackPacket, request, lease, clientMac, broadcastFlag);
+ return transmitOfferOrAckPacket(ackPacket, packet, lease, clientMac, broadcastFlag);
}
private boolean transmitNak(DhcpPacket request, String message) {
diff --git a/src/android/net/util/NetworkStackUtils.java b/src/android/net/util/NetworkStackUtils.java
index 993f3cb..45ed367 100644
--- a/src/android/net/util/NetworkStackUtils.java
+++ b/src/android/net/util/NetworkStackUtils.java
@@ -112,13 +112,18 @@ public class NetworkStackUtils {
public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
/**
- * Experiment flag to enable DHCP INIT-REBOOT state, default value is false.
+ * @deprecated Considering boolean experiment flag is likely to cause misconfiguration
+ * particularly when NetworkStack module rolls back to previous version. It's
+ * much safer to determine whether or not to enable one specific experimental
+ * feature by comparing flag version with module version.
*/
+ @Deprecated
public static final String DHCP_INIT_REBOOT_ENABLED = "dhcp_init_reboot_enabled";
/**
- * Experiment flag to enable DHCP Rapid Commit option, default value is false.
+ * @deprecated See above explanation.
*/
+ @Deprecated
public static final String DHCP_RAPID_COMMIT_ENABLED = "dhcp_rapid_commit_enabled";
/**
diff --git a/src/com/android/server/NetworkStackService.java b/src/com/android/server/NetworkStackService.java
index 74a5da0..0114e45 100644
--- a/src/com/android/server/NetworkStackService.java
+++ b/src/com/android/server/NetworkStackService.java
@@ -198,6 +198,7 @@ public class NetworkStackService extends Service {
final DhcpServer server;
try {
server = new DhcpServer(
+ mContext,
ifName,
DhcpServingParams.fromParcelableObject(params),
mLog.forSubComponent(ifName + ".DHCP"));
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
index c5f99c5..afd5929 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
@@ -118,7 +118,6 @@ import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -459,7 +458,7 @@ public class IpClientIntegrationTest {
}
private static ByteBuffer buildDhcpAckPacket(final DhcpPacket packet,
- final Integer leaseTimeSec, final short mtu) {
+ final Integer leaseTimeSec, final short mtu, final boolean rapidCommit) {
return DhcpPacket.buildAckPacket(DhcpPacket.ENCAP_L2, packet.getTransactionId(),
false /* broadcast */, SERVER_ADDR, INADDR_ANY /* relayIp */,
CLIENT_ADDR /* yourIp */, CLIENT_ADDR /* requestIp */, packet.getClientMac(),
@@ -467,7 +466,7 @@ public class IpClientIntegrationTest {
Collections.singletonList(SERVER_ADDR) /* gateways */,
Collections.singletonList(SERVER_ADDR) /* dnsServers */,
SERVER_ADDR /* dhcpServerIdentifier */, null /* domainName */, HOSTNAME,
- false /* metered */, mtu);
+ false /* metered */, mtu, rapidCommit);
}
private static ByteBuffer buildDhcpNakPacket(final DhcpPacket packet) {
@@ -560,13 +559,15 @@ public class IpClientIntegrationTest {
while ((packet = getNextDhcpPacket()) != null) {
if (packet instanceof DhcpDiscoverPacket) {
if (isDhcpRapidCommitEnabled) {
- sendResponse(buildDhcpAckPacket(packet, leaseTimeSec, (short) mtu));
+ sendResponse(buildDhcpAckPacket(packet, leaseTimeSec, (short) mtu,
+ true /* rapidCommit */));
} else {
sendResponse(buildDhcpOfferPacket(packet, leaseTimeSec, (short) mtu));
}
} else if (packet instanceof DhcpRequestPacket) {
final ByteBuffer byteBuffer = isSuccessLease
- ? buildDhcpAckPacket(packet, leaseTimeSec, (short) mtu)
+ ? buildDhcpAckPacket(packet, leaseTimeSec, (short) mtu,
+ false /* rapidCommit */)
: buildDhcpNakPacket(packet);
sendResponse(byteBuffer);
} else {
@@ -679,11 +680,9 @@ public class IpClientIntegrationTest {
packet = getNextDhcpPacket();
assertTrue(packet instanceof DhcpRequestPacket);
}
- // TODO: currently the DHCPACK packet doesn't include the Rapid Commit option.
- // This does not matter because the client will accept the ACK even if the Rapid Commit
- // option is not present. Fix the test code, and then change the client to ensure
- // it will only accept the ACK if the Rapid Commit option is present.
- sendResponse(buildDhcpAckPacket(packet, TEST_LEASE_DURATION_S, mtu));
+
+ sendResponse(buildDhcpAckPacket(packet, TEST_LEASE_DURATION_S, mtu,
+ isDhcpRapidCommitEnabled));
if (!shouldAbortPreconnection) {
mIpc.sendMessage(IpClient.CMD_COMPLETE_PRECONNECTION, 1 /* success */);
}
@@ -823,10 +822,8 @@ public class IpClientIntegrationTest {
assertIpMemoryNeverStoreNetworkAttributes();
}
- @Ignore
@Test
public void testHandleRapidCommitOption() throws Exception {
- // TODO: remove @Ignore after supporting rapid commit option in DHCP server
final long currentTime = System.currentTimeMillis();
performDhcpHandshake(true /* isSuccessLease */, TEST_LEASE_DURATION_S,
true /* isDhcpLeaseCacheEnabled */, true /* isDhcpRapidCommitEnabled */,
@@ -1170,18 +1167,12 @@ public class IpClientIntegrationTest {
false /* shouldAbortPreconnection */);
}
- // So far DHCPACK doesn't include Rapid Commit option(aosp/1092270 is adding the option), when
- // receiving the DHCPACK packet in DhcpPreconnectionState or DhcpInitState, dropping the DHCPACK
- // packet directly, which would cause test cases with enabled "isDhcpRapidCommitEnabled" flag
- // fail.
- @Ignore
@Test
public void testDhcpClientPreconnectionEnabled() throws Exception {
doIpClientProvisioningWithPreconnectionTest(true /* isDhcpRapidCommitEnabled */,
false /* shouldAbortPreconnection */);
}
- @Ignore
@Test
public void testDhcpClientPreconnectionEnabled_WithRapidCommit() throws Exception {
doIpClientProvisioningWithPreconnectionTest(true /* isDhcpRapidCommitEnabled */,
@@ -1215,11 +1206,6 @@ public class IpClientIntegrationTest {
false /* shouldResponseArpReply */);
}
- // So far Rapid Commit option has not been built within DHCPACK packet (implemention at
- // aosp/1092270), hence, client can't deal with DHCPACK in INIT state correctly and drop
- // the received DHCPACK, which causes the following verify checks fails. After checking in
- // aosp/1092270, remove all below @Ignore annotations.
- @Ignore
@Test
public void testDhcpDecline_WithRapidCommitWithoutIpConflict() throws Exception {
doIpAddressConflictDetectionTest(false /* causeIpAddressConflict */,
@@ -1227,7 +1213,6 @@ public class IpClientIntegrationTest {
false /* shouldResponseArpReply */);
}
- @Ignore
@Test
public void testDhcpDecline_WithRapidCommitConflictByArpReply() throws Exception {
doIpAddressConflictDetectionTest(true /* causeIpAddressConflict */,
@@ -1235,7 +1220,6 @@ public class IpClientIntegrationTest {
true /* shouldResponseArpReply */);
}
- @Ignore
@Test
public void testDhcpDecline_WithRapidCommitConflictByArpProbe() throws Exception {
doIpAddressConflictDetectionTest(true /* causeIpAddressConflict */,
@@ -1243,7 +1227,6 @@ public class IpClientIntegrationTest {
false /* shouldResponseArpReply */);
}
- @Ignore
@Test
public void testDhcpDecline_EnableFlagWithRapidCommitWithoutIpConflict() throws Exception {
doIpAddressConflictDetectionTest(false /* causeIpAddressConflict */,
diff --git a/tests/unit/src/android/net/dhcp/DhcpServerTest.java b/tests/unit/src/android/net/dhcp/DhcpServerTest.java
index f0e2f1b..5074f82 100644
--- a/tests/unit/src/android/net/dhcp/DhcpServerTest.java
+++ b/tests/unit/src/android/net/dhcp/DhcpServerTest.java
@@ -23,6 +23,7 @@ import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP;
import static android.net.dhcp.DhcpPacket.INADDR_ANY;
import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
+import static android.net.util.NetworkStackUtils.DHCP_RAPID_COMMIT_VERSION;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -42,6 +43,7 @@ import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.Context;
import android.net.INetworkStackStatusCallback;
import android.net.LinkAddress;
import android.net.MacAddress;
@@ -104,6 +106,8 @@ public class DhcpServerTest {
TEST_CLIENT_ADDR, TEST_LEASE_EXPTIME_SECS * 1000L + TEST_CLOCK_TIME, TEST_HOSTNAME);
@NonNull @Mock
+ private Context mContext;
+ @NonNull @Mock
private Dependencies mDeps;
@NonNull @Mock
private DhcpLeaseRepository mRepository;
@@ -147,6 +151,7 @@ public class DhcpServerTest {
when(mDeps.makeLeaseRepository(any(), any(), any())).thenReturn(mRepository);
when(mDeps.makeClock()).thenReturn(mClock);
when(mDeps.makePacketListener()).thenReturn(mPacketListener);
+ when(mDeps.isFeatureEnabled(eq(mContext), eq(DHCP_RAPID_COMMIT_VERSION))).thenReturn(true);
doNothing().when(mDeps)
.sendPacket(any(), mSentPacketCaptor.capture(), mResponseDstAddrCaptor.capture());
when(mClock.elapsedRealtime()).thenReturn(TEST_CLOCK_TIME);
@@ -163,7 +168,7 @@ public class DhcpServerTest {
mLooper = TestableLooper.get(this);
mHandlerThread = spy(new HandlerThread("TestDhcpServer"));
when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
- mServer = new DhcpServer(mHandlerThread, TEST_IFACE, servingParams,
+ mServer = new DhcpServer(mContext, mHandlerThread, TEST_IFACE, servingParams,
new SharedLog(DhcpServerTest.class.getSimpleName()), mDeps);
mServer.start(mAssertSuccessCallback);
@@ -192,7 +197,7 @@ public class DhcpServerTest {
final DhcpDiscoverPacket discover = new DhcpDiscoverPacket(TEST_TRANSACTION_ID,
(short) 0 /* secs */, INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES,
- false /* broadcast */, INADDR_ANY /* srcIp */);
+ false /* broadcast */, INADDR_ANY /* srcIp */, false /* rapidCommit */);
mServer.processPacket(discover, DHCP_CLIENT);
assertResponseSentTo(TEST_CLIENT_ADDR);
@@ -201,6 +206,22 @@ public class DhcpServerTest {
}
@Test
+ public void testDiscover_RapidCommit() throws Exception {
+ when(mDeps.isFeatureEnabled(eq(mContext), eq(DHCP_RAPID_COMMIT_VERSION))).thenReturn(true);
+ when(mRepository.getCommittedLease(isNull() /* clientId */, eq(TEST_CLIENT_MAC),
+ eq(INADDR_ANY) /* relayAddr */, isNull() /* hostname */)).thenReturn(TEST_LEASE);
+
+ final DhcpDiscoverPacket discover = new DhcpDiscoverPacket(TEST_TRANSACTION_ID,
+ (short) 0 /* secs */, INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES,
+ false /* broadcast */, INADDR_ANY /* srcIp */, true /* rapidCommit */);
+ mServer.processPacket(discover, DHCP_CLIENT);
+
+ assertResponseSentTo(TEST_CLIENT_ADDR);
+ final DhcpAckPacket packet = assertAck(getPacket());
+ assertMatchesTestLease(packet);
+ }
+
+ @Test
public void testDiscover_OutOfAddresses() throws Exception {
when(mRepository.getOffer(isNull() /* clientId */, eq(TEST_CLIENT_MAC),
eq(INADDR_ANY) /* relayAddr */, isNull() /* reqAddr */, isNull() /* hostname */))
@@ -208,7 +229,7 @@ public class DhcpServerTest {
final DhcpDiscoverPacket discover = new DhcpDiscoverPacket(TEST_TRANSACTION_ID,
(short) 0 /* secs */, INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES,
- false /* broadcast */, INADDR_ANY /* srcIp */);
+ false /* broadcast */, INADDR_ANY /* srcIp */, false /* rapidCommit */);
mServer.processPacket(discover, DHCP_CLIENT);
assertResponseSentTo(INADDR_BROADCAST);