Loading src/android/net/dhcp/DhcpClient.java +68 −23 Original line number Diff line number Diff line Loading @@ -179,7 +179,8 @@ public class DhcpClient extends StateMachine { private static final int EVENT_CONFIGURATION_INVALID = PRIVATE_BASE + 9; // constant to represent this DHCP lease has been expired. private static final long EXPIRED_LEASE = 1L; @VisibleForTesting public static final long EXPIRED_LEASE = 1L; // For message logging. private static final Class[] sMessageClasses = { DhcpClient.class }; Loading Loading @@ -239,7 +240,7 @@ public class DhcpClient extends StateMachine { private String mL2Key; private Inet4Address mLastAssignedIpv4Address; private long mLastAssignedIpv4AddressExpiry; private boolean mDhcpLeaseCacheEnabled; private Dependencies mDependencies; @NonNull private final NetworkStackIpMemoryStore mIpMemoryStore; Loading Loading @@ -271,15 +272,43 @@ public class DhcpClient extends StateMachine { return new WakeupMessage(mContext, getHandler(), cmdName, cmd); } /** * Encapsulates DhcpClient depencencies that's used for unit testing and * integration testing. */ public static class Dependencies { private final NetworkStackIpMemoryStore mNetworkStackIpMemoryStore; public Dependencies(NetworkStackIpMemoryStore store) { mNetworkStackIpMemoryStore = store; } /** * Get a IpMemoryStore instance. */ public NetworkStackIpMemoryStore getIpMemoryStore() { return mNetworkStackIpMemoryStore; } /** * Get the value of DHCP related experiment flags. */ public boolean getBooleanDeviceConfig(final String nameSpace, final String flagName) { return NetworkStackUtils.getDeviceConfigPropertyBoolean(nameSpace, flagName, false /* default value */); } } // TODO: Take an InterfaceParams instance instead of an interface name String. private DhcpClient(Context context, StateMachine controller, String iface, NetworkStackIpMemoryStore ipMemoryStore) { Dependencies deps) { super(TAG, controller.getHandler()); mDependencies = deps; mContext = context; mController = controller; mIfaceName = iface; mIpMemoryStore = ipMemoryStore; mIpMemoryStore = deps.getIpMemoryStore(); // CHECKSTYLE:OFF IndentationCheck addState(mStoppedState); Loading Loading @@ -320,8 +349,8 @@ public class DhcpClient extends StateMachine { public static DhcpClient makeDhcpClient( Context context, StateMachine controller, InterfaceParams ifParams, NetworkStackIpMemoryStore ipMemoryStore) { DhcpClient client = new DhcpClient(context, controller, ifParams.name, ipMemoryStore); Dependencies deps) { DhcpClient client = new DhcpClient(context, controller, ifParams.name, deps); client.mIface = ifParams; client.start(); return client; Loading @@ -332,19 +361,21 @@ public class DhcpClient extends StateMachine { * */ public boolean isDhcpLeaseCacheEnabled() { // TODO: call DeviceConfig.getProperty(DeviceConfig.NAMESPACE_CONNECTIVITY, // DeviceConfig.PROPERTY); // to fetch the dynamic experiment flag value. Return false by default. return mDhcpLeaseCacheEnabled; return mDependencies.getBooleanDeviceConfig(NetworkStackUtils.NAMESPACE_CONNECTIVITY, NetworkStackUtils.DHCP_INIT_REBOOT_ENABLED); } /** * set DHCP lease cached enabled experiment flag. * * check whether or not to support DHCP Rapid Commit option. */ @VisibleForTesting public void setDhcpLeaseCacheEnabled(final boolean enabled) { mDhcpLeaseCacheEnabled = enabled; public boolean isDhcpRapidCommitEnabled() { return mDependencies.getBooleanDeviceConfig(NetworkStackUtils.NAMESPACE_CONNECTIVITY, NetworkStackUtils.DHCP_RAPID_COMMIT_ENABLED); } private void confirmDhcpLease(DhcpPacket packet, DhcpResults results) { setDhcpLeaseExpiry(packet); acceptDhcpResults(results, "Confirmed"); } private boolean initInterface() { Loading Loading @@ -495,7 +526,7 @@ public class DhcpClient extends StateMachine { private boolean sendDiscoverPacket() { ByteBuffer packet = DhcpPacket.buildDiscoverPacket( DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr, DO_UNICAST, REQUESTED_PARAMS); DO_UNICAST, REQUESTED_PARAMS, isDhcpRapidCommitEnabled()); return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST); } Loading Loading @@ -959,12 +990,27 @@ public class DhcpClient extends StateMachine { protected void receivePacket(DhcpPacket packet) { if (!isValidPacket(packet)) return; if (!(packet instanceof DhcpOfferPacket)) return; // 1. received the DHCPOFFER packet, process it by following RFC2131. // 2. received the DHCPACK packet from DHCP Servers who support Rapid // Commit option, process it by following RFC4039. if (packet instanceof DhcpOfferPacket) { mOffer = packet.toDhcpResults(); if (mOffer != null) { Log.d(TAG, "Got pending lease: " + mOffer); transitionTo(mDhcpRequestingState); } } else if (packet instanceof DhcpAckPacket) { // If received DHCPACK packet w/o Rapid Commit option in this state, // just drop it and wait for the next DHCPOFFER packet or DHCPACK w/ // Rapid Commit option. if (!isDhcpRapidCommitEnabled() || !packet.mRapidCommit) return; final DhcpResults results = packet.toDhcpResults(); if (results != null) { confirmDhcpLease(packet, results); transitionTo(mConfiguringInterfaceState); } } } } Loading @@ -990,8 +1036,7 @@ public class DhcpClient extends StateMachine { if ((packet instanceof DhcpAckPacket)) { DhcpResults results = packet.toDhcpResults(); if (results != null) { setDhcpLeaseExpiry(packet); acceptDhcpResults(results, "Confirmed"); confirmDhcpLease(packet, results); transitionTo(mConfiguringInterfaceState); } } else if (packet instanceof DhcpNakPacket) { Loading src/android/net/dhcp/DhcpDiscoverPacket.java +3 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,9 @@ public class DhcpDiscoverPacket extends DhcpPacket { addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId()); addCommonClientTlvs(buffer); addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams); if (mRapidCommit) { addTlv(buffer, DHCP_RAPID_COMMIT); } addTlvEnd(buffer); } } src/android/net/dhcp/DhcpPacket.java +24 −1 Original line number Diff line number Diff line Loading @@ -280,6 +280,13 @@ public abstract class DhcpPacket { protected static final byte DHCP_CLIENT_IDENTIFIER = 61; protected byte[] mClientId; /** * DHCP zero-length Optional Type: Rapid Commit. Per RFC4039, both DHCPDISCOVER and DHCPACK * packet may include this option. */ protected static final byte DHCP_RAPID_COMMIT = 80; protected boolean mRapidCommit; /** * DHCP zero-length option code: pad */ Loading Loading @@ -604,6 +611,14 @@ public abstract class DhcpPacket { buf.put(value); } /** * Adds an optional parameter containing zero-length value. */ protected static void addTlv(ByteBuffer buf, byte type) { buf.put(type); buf.put((byte) 0); } /** * Adds an optional parameter containing an array of bytes. * Loading Loading @@ -858,6 +873,7 @@ public abstract class DhcpPacket { String message = null; String vendorId = null; String vendorInfo = null; boolean rapidCommit = false; byte[] expectedParams = null; String hostName = null; String domainName = null; Loading Loading @@ -1126,6 +1142,10 @@ public abstract class DhcpPacket { optionOverload = packet.get(); optionOverload &= OPTION_OVERLOAD_BOTH; break; case DHCP_RAPID_COMMIT: expectedLen = 0; rapidCommit = true; break; default: // ignore any other parameters for (int i = 0; i < optionLen; i++) { Loading Loading @@ -1216,6 +1236,7 @@ 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 { Loading Loading @@ -1304,10 +1325,12 @@ public abstract class DhcpPacket { * parameters. */ public static ByteBuffer buildDiscoverPacket(int encap, int transactionId, short secs, byte[] clientMac, boolean broadcast, byte[] expectedParams) { short secs, byte[] clientMac, boolean broadcast, byte[] expectedParams, boolean rapidCommit) { DhcpPacket pkt = new DhcpDiscoverPacket(transactionId, secs, INADDR_ANY /* relayIp */, clientMac, broadcast, INADDR_ANY /* srcIp */); pkt.mRequestedParams = expectedParams; pkt.mRapidCommit = rapidCommit; return pkt.buildPacket(encap, DHCP_SERVER, DHCP_CLIENT); } Loading src/android/net/ip/IpClient.java +9 −1 Original line number Diff line number Diff line Loading @@ -401,6 +401,14 @@ public class IpClient extends StateMachine { NetworkStackServiceManager nssManager) { return new NetworkStackIpMemoryStore(context, nssManager.getIpMemoryStoreService()); } /** * Get a DhcpClient Dependencies instance. */ public DhcpClient.Dependencies getDhcpClientDependencies( NetworkStackIpMemoryStore ipMemoryStore) { return new DhcpClient.Dependencies(ipMemoryStore); } } public IpClient(Context context, String ifName, IIpClientCallbacks callback, Loading Loading @@ -1190,7 +1198,7 @@ public class IpClient extends StateMachine { } else { // Start DHCPv4. mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpClient.this, mInterfaceParams, mIpMemoryStore); mDependencies.getDhcpClientDependencies(mIpMemoryStore)); mDhcpClient.registerForPreDhcpNotification(); mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP, mL2Key); } Loading src/android/net/util/NetworkStackUtils.java +24 −2 Original line number Diff line number Diff line Loading @@ -107,6 +107,16 @@ public class NetworkStackUtils { */ public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; /** * Experiment flag to enable DHCP INIT-REBOOT state, default value is false. */ public static final String DHCP_INIT_REBOOT_ENABLED = "dhcp_init_reboot_enabled"; /** * Experiment flag to enable DHCP Rapid Commit option, default value is false. */ public static final String DHCP_RAPID_COMMIT_ENABLED = "dhcp_rapid_commit_enabled"; static { System.loadLibrary("networkstackutilsjni"); } Loading Loading @@ -181,8 +191,7 @@ public class NetworkStackUtils { * Look up the value of a property for a particular namespace from {@link DeviceConfig}. * @param namespace The namespace containing the property to look up. * @param name The name of the property to look up. * @param defaultValue The value to return if the property does not exist or has no non-null * value. * @param defaultValue The value to return if the property does not exist or its value is null. * @return the corresponding value, or defaultValue if none exists. */ public static int getDeviceConfigPropertyInt(@NonNull String namespace, @NonNull String name, Loading @@ -195,6 +204,19 @@ public class NetworkStackUtils { } } /** * Look up the value of a property for a particular namespace from {@link DeviceConfig}. * @param namespace The namespace containing the property to look up. * @param name The name of the property to look up. * @param defaultValue The value to return if the property does not exist or its value is null. * @return the corresponding value, or defaultValue if none exists. */ public static boolean getDeviceConfigPropertyBoolean(@NonNull String namespace, @NonNull String name, boolean defaultValue) { String value = getDeviceConfigProperty(namespace, name, null /* defaultValue */); return (value != null) ? Boolean.parseBoolean(value) : defaultValue; } /** * Attaches a socket filter that accepts DHCP packets to the given socket. */ Loading Loading
src/android/net/dhcp/DhcpClient.java +68 −23 Original line number Diff line number Diff line Loading @@ -179,7 +179,8 @@ public class DhcpClient extends StateMachine { private static final int EVENT_CONFIGURATION_INVALID = PRIVATE_BASE + 9; // constant to represent this DHCP lease has been expired. private static final long EXPIRED_LEASE = 1L; @VisibleForTesting public static final long EXPIRED_LEASE = 1L; // For message logging. private static final Class[] sMessageClasses = { DhcpClient.class }; Loading Loading @@ -239,7 +240,7 @@ public class DhcpClient extends StateMachine { private String mL2Key; private Inet4Address mLastAssignedIpv4Address; private long mLastAssignedIpv4AddressExpiry; private boolean mDhcpLeaseCacheEnabled; private Dependencies mDependencies; @NonNull private final NetworkStackIpMemoryStore mIpMemoryStore; Loading Loading @@ -271,15 +272,43 @@ public class DhcpClient extends StateMachine { return new WakeupMessage(mContext, getHandler(), cmdName, cmd); } /** * Encapsulates DhcpClient depencencies that's used for unit testing and * integration testing. */ public static class Dependencies { private final NetworkStackIpMemoryStore mNetworkStackIpMemoryStore; public Dependencies(NetworkStackIpMemoryStore store) { mNetworkStackIpMemoryStore = store; } /** * Get a IpMemoryStore instance. */ public NetworkStackIpMemoryStore getIpMemoryStore() { return mNetworkStackIpMemoryStore; } /** * Get the value of DHCP related experiment flags. */ public boolean getBooleanDeviceConfig(final String nameSpace, final String flagName) { return NetworkStackUtils.getDeviceConfigPropertyBoolean(nameSpace, flagName, false /* default value */); } } // TODO: Take an InterfaceParams instance instead of an interface name String. private DhcpClient(Context context, StateMachine controller, String iface, NetworkStackIpMemoryStore ipMemoryStore) { Dependencies deps) { super(TAG, controller.getHandler()); mDependencies = deps; mContext = context; mController = controller; mIfaceName = iface; mIpMemoryStore = ipMemoryStore; mIpMemoryStore = deps.getIpMemoryStore(); // CHECKSTYLE:OFF IndentationCheck addState(mStoppedState); Loading Loading @@ -320,8 +349,8 @@ public class DhcpClient extends StateMachine { public static DhcpClient makeDhcpClient( Context context, StateMachine controller, InterfaceParams ifParams, NetworkStackIpMemoryStore ipMemoryStore) { DhcpClient client = new DhcpClient(context, controller, ifParams.name, ipMemoryStore); Dependencies deps) { DhcpClient client = new DhcpClient(context, controller, ifParams.name, deps); client.mIface = ifParams; client.start(); return client; Loading @@ -332,19 +361,21 @@ public class DhcpClient extends StateMachine { * */ public boolean isDhcpLeaseCacheEnabled() { // TODO: call DeviceConfig.getProperty(DeviceConfig.NAMESPACE_CONNECTIVITY, // DeviceConfig.PROPERTY); // to fetch the dynamic experiment flag value. Return false by default. return mDhcpLeaseCacheEnabled; return mDependencies.getBooleanDeviceConfig(NetworkStackUtils.NAMESPACE_CONNECTIVITY, NetworkStackUtils.DHCP_INIT_REBOOT_ENABLED); } /** * set DHCP lease cached enabled experiment flag. * * check whether or not to support DHCP Rapid Commit option. */ @VisibleForTesting public void setDhcpLeaseCacheEnabled(final boolean enabled) { mDhcpLeaseCacheEnabled = enabled; public boolean isDhcpRapidCommitEnabled() { return mDependencies.getBooleanDeviceConfig(NetworkStackUtils.NAMESPACE_CONNECTIVITY, NetworkStackUtils.DHCP_RAPID_COMMIT_ENABLED); } private void confirmDhcpLease(DhcpPacket packet, DhcpResults results) { setDhcpLeaseExpiry(packet); acceptDhcpResults(results, "Confirmed"); } private boolean initInterface() { Loading Loading @@ -495,7 +526,7 @@ public class DhcpClient extends StateMachine { private boolean sendDiscoverPacket() { ByteBuffer packet = DhcpPacket.buildDiscoverPacket( DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr, DO_UNICAST, REQUESTED_PARAMS); DO_UNICAST, REQUESTED_PARAMS, isDhcpRapidCommitEnabled()); return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST); } Loading Loading @@ -959,12 +990,27 @@ public class DhcpClient extends StateMachine { protected void receivePacket(DhcpPacket packet) { if (!isValidPacket(packet)) return; if (!(packet instanceof DhcpOfferPacket)) return; // 1. received the DHCPOFFER packet, process it by following RFC2131. // 2. received the DHCPACK packet from DHCP Servers who support Rapid // Commit option, process it by following RFC4039. if (packet instanceof DhcpOfferPacket) { mOffer = packet.toDhcpResults(); if (mOffer != null) { Log.d(TAG, "Got pending lease: " + mOffer); transitionTo(mDhcpRequestingState); } } else if (packet instanceof DhcpAckPacket) { // If received DHCPACK packet w/o Rapid Commit option in this state, // just drop it and wait for the next DHCPOFFER packet or DHCPACK w/ // Rapid Commit option. if (!isDhcpRapidCommitEnabled() || !packet.mRapidCommit) return; final DhcpResults results = packet.toDhcpResults(); if (results != null) { confirmDhcpLease(packet, results); transitionTo(mConfiguringInterfaceState); } } } } Loading @@ -990,8 +1036,7 @@ public class DhcpClient extends StateMachine { if ((packet instanceof DhcpAckPacket)) { DhcpResults results = packet.toDhcpResults(); if (results != null) { setDhcpLeaseExpiry(packet); acceptDhcpResults(results, "Confirmed"); confirmDhcpLease(packet, results); transitionTo(mConfiguringInterfaceState); } } else if (packet instanceof DhcpNakPacket) { Loading
src/android/net/dhcp/DhcpDiscoverPacket.java +3 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,9 @@ public class DhcpDiscoverPacket extends DhcpPacket { addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId()); addCommonClientTlvs(buffer); addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams); if (mRapidCommit) { addTlv(buffer, DHCP_RAPID_COMMIT); } addTlvEnd(buffer); } }
src/android/net/dhcp/DhcpPacket.java +24 −1 Original line number Diff line number Diff line Loading @@ -280,6 +280,13 @@ public abstract class DhcpPacket { protected static final byte DHCP_CLIENT_IDENTIFIER = 61; protected byte[] mClientId; /** * DHCP zero-length Optional Type: Rapid Commit. Per RFC4039, both DHCPDISCOVER and DHCPACK * packet may include this option. */ protected static final byte DHCP_RAPID_COMMIT = 80; protected boolean mRapidCommit; /** * DHCP zero-length option code: pad */ Loading Loading @@ -604,6 +611,14 @@ public abstract class DhcpPacket { buf.put(value); } /** * Adds an optional parameter containing zero-length value. */ protected static void addTlv(ByteBuffer buf, byte type) { buf.put(type); buf.put((byte) 0); } /** * Adds an optional parameter containing an array of bytes. * Loading Loading @@ -858,6 +873,7 @@ public abstract class DhcpPacket { String message = null; String vendorId = null; String vendorInfo = null; boolean rapidCommit = false; byte[] expectedParams = null; String hostName = null; String domainName = null; Loading Loading @@ -1126,6 +1142,10 @@ public abstract class DhcpPacket { optionOverload = packet.get(); optionOverload &= OPTION_OVERLOAD_BOTH; break; case DHCP_RAPID_COMMIT: expectedLen = 0; rapidCommit = true; break; default: // ignore any other parameters for (int i = 0; i < optionLen; i++) { Loading Loading @@ -1216,6 +1236,7 @@ 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 { Loading Loading @@ -1304,10 +1325,12 @@ public abstract class DhcpPacket { * parameters. */ public static ByteBuffer buildDiscoverPacket(int encap, int transactionId, short secs, byte[] clientMac, boolean broadcast, byte[] expectedParams) { short secs, byte[] clientMac, boolean broadcast, byte[] expectedParams, boolean rapidCommit) { DhcpPacket pkt = new DhcpDiscoverPacket(transactionId, secs, INADDR_ANY /* relayIp */, clientMac, broadcast, INADDR_ANY /* srcIp */); pkt.mRequestedParams = expectedParams; pkt.mRapidCommit = rapidCommit; return pkt.buildPacket(encap, DHCP_SERVER, DHCP_CLIENT); } Loading
src/android/net/ip/IpClient.java +9 −1 Original line number Diff line number Diff line Loading @@ -401,6 +401,14 @@ public class IpClient extends StateMachine { NetworkStackServiceManager nssManager) { return new NetworkStackIpMemoryStore(context, nssManager.getIpMemoryStoreService()); } /** * Get a DhcpClient Dependencies instance. */ public DhcpClient.Dependencies getDhcpClientDependencies( NetworkStackIpMemoryStore ipMemoryStore) { return new DhcpClient.Dependencies(ipMemoryStore); } } public IpClient(Context context, String ifName, IIpClientCallbacks callback, Loading Loading @@ -1190,7 +1198,7 @@ public class IpClient extends StateMachine { } else { // Start DHCPv4. mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpClient.this, mInterfaceParams, mIpMemoryStore); mDependencies.getDhcpClientDependencies(mIpMemoryStore)); mDhcpClient.registerForPreDhcpNotification(); mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP, mL2Key); } Loading
src/android/net/util/NetworkStackUtils.java +24 −2 Original line number Diff line number Diff line Loading @@ -107,6 +107,16 @@ public class NetworkStackUtils { */ public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; /** * Experiment flag to enable DHCP INIT-REBOOT state, default value is false. */ public static final String DHCP_INIT_REBOOT_ENABLED = "dhcp_init_reboot_enabled"; /** * Experiment flag to enable DHCP Rapid Commit option, default value is false. */ public static final String DHCP_RAPID_COMMIT_ENABLED = "dhcp_rapid_commit_enabled"; static { System.loadLibrary("networkstackutilsjni"); } Loading Loading @@ -181,8 +191,7 @@ public class NetworkStackUtils { * Look up the value of a property for a particular namespace from {@link DeviceConfig}. * @param namespace The namespace containing the property to look up. * @param name The name of the property to look up. * @param defaultValue The value to return if the property does not exist or has no non-null * value. * @param defaultValue The value to return if the property does not exist or its value is null. * @return the corresponding value, or defaultValue if none exists. */ public static int getDeviceConfigPropertyInt(@NonNull String namespace, @NonNull String name, Loading @@ -195,6 +204,19 @@ public class NetworkStackUtils { } } /** * Look up the value of a property for a particular namespace from {@link DeviceConfig}. * @param namespace The namespace containing the property to look up. * @param name The name of the property to look up. * @param defaultValue The value to return if the property does not exist or its value is null. * @return the corresponding value, or defaultValue if none exists. */ public static boolean getDeviceConfigPropertyBoolean(@NonNull String namespace, @NonNull String name, boolean defaultValue) { String value = getDeviceConfigProperty(namespace, name, null /* defaultValue */); return (value != null) ? Boolean.parseBoolean(value) : defaultValue; } /** * Attaches a socket filter that accepts DHCP packets to the given socket. */ Loading