Merge "Support DHCPv4 rebinding state" into nyc-dev
am: 4bf3157c45
* commit '4bf3157c4560148b9b3f2e6aec7ed0835f6af14a':
Support DHCPv4 rebinding state
Change-Id: I885181616444d19974085637f80f459c9152ac7d
This commit is contained in:
@@ -125,17 +125,18 @@ public class DhcpClient extends StateMachine {
|
|||||||
public static final int CMD_CONFIGURE_LINKADDRESS = PUBLIC_BASE + 8;
|
public static final int CMD_CONFIGURE_LINKADDRESS = PUBLIC_BASE + 8;
|
||||||
public static final int EVENT_LINKADDRESS_CONFIGURED = PUBLIC_BASE + 9;
|
public static final int EVENT_LINKADDRESS_CONFIGURED = PUBLIC_BASE + 9;
|
||||||
|
|
||||||
/* Message.arg1 arguments to CMD_POST_DHCP notification */
|
/* Message.arg1 arguments to CMD_POST_DHCP_ACTION notification */
|
||||||
public static final int DHCP_SUCCESS = 1;
|
public static final int DHCP_SUCCESS = 1;
|
||||||
public static final int DHCP_FAILURE = 2;
|
public static final int DHCP_FAILURE = 2;
|
||||||
|
|
||||||
// Messages.
|
// Internal messages.
|
||||||
private static final int PRIVATE_BASE = Protocol.BASE_DHCP + 100;
|
private static final int PRIVATE_BASE = Protocol.BASE_DHCP + 100;
|
||||||
private static final int CMD_KICK = PRIVATE_BASE + 1;
|
private static final int CMD_KICK = PRIVATE_BASE + 1;
|
||||||
private static final int CMD_RECEIVED_PACKET = PRIVATE_BASE + 2;
|
private static final int CMD_RECEIVED_PACKET = PRIVATE_BASE + 2;
|
||||||
private static final int CMD_TIMEOUT = PRIVATE_BASE + 3;
|
private static final int CMD_TIMEOUT = PRIVATE_BASE + 3;
|
||||||
private static final int CMD_RENEW_DHCP = PRIVATE_BASE + 4;
|
private static final int CMD_RENEW_DHCP = PRIVATE_BASE + 4;
|
||||||
private static final int CMD_EXPIRE_DHCP = PRIVATE_BASE + 5;
|
private static final int CMD_REBIND_DHCP = PRIVATE_BASE + 5;
|
||||||
|
private static final int CMD_EXPIRE_DHCP = PRIVATE_BASE + 6;
|
||||||
|
|
||||||
// For message logging.
|
// For message logging.
|
||||||
private static final Class[] sMessageClasses = { DhcpClient.class };
|
private static final Class[] sMessageClasses = { DhcpClient.class };
|
||||||
@@ -177,6 +178,7 @@ public class DhcpClient extends StateMachine {
|
|||||||
private final WakeupMessage mKickAlarm;
|
private final WakeupMessage mKickAlarm;
|
||||||
private final WakeupMessage mTimeoutAlarm;
|
private final WakeupMessage mTimeoutAlarm;
|
||||||
private final WakeupMessage mRenewAlarm;
|
private final WakeupMessage mRenewAlarm;
|
||||||
|
private final WakeupMessage mRebindAlarm;
|
||||||
private final WakeupMessage mExpiryAlarm;
|
private final WakeupMessage mExpiryAlarm;
|
||||||
private final String mIfaceName;
|
private final String mIfaceName;
|
||||||
|
|
||||||
@@ -241,8 +243,9 @@ public class DhcpClient extends StateMachine {
|
|||||||
mKickAlarm = makeWakeupMessage("KICK", CMD_KICK);
|
mKickAlarm = makeWakeupMessage("KICK", CMD_KICK);
|
||||||
// Used to time out PacketRetransmittingStates.
|
// Used to time out PacketRetransmittingStates.
|
||||||
mTimeoutAlarm = makeWakeupMessage("TIMEOUT", CMD_TIMEOUT);
|
mTimeoutAlarm = makeWakeupMessage("TIMEOUT", CMD_TIMEOUT);
|
||||||
// Used to schedule DHCP renews.
|
// Used to schedule DHCP reacquisition.
|
||||||
mRenewAlarm = makeWakeupMessage("RENEW", CMD_RENEW_DHCP);
|
mRenewAlarm = makeWakeupMessage("RENEW", CMD_RENEW_DHCP);
|
||||||
|
mRebindAlarm = makeWakeupMessage("REBIND", CMD_REBIND_DHCP);
|
||||||
mExpiryAlarm = makeWakeupMessage("EXPIRY", CMD_EXPIRE_DHCP);
|
mExpiryAlarm = makeWakeupMessage("EXPIRY", CMD_EXPIRE_DHCP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,6 +279,10 @@ public class DhcpClient extends StateMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean initSockets() {
|
private boolean initSockets() {
|
||||||
|
return initPacketSocket() && initUdpSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean initPacketSocket() {
|
||||||
try {
|
try {
|
||||||
mPacketSock = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IP);
|
mPacketSock = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IP);
|
||||||
PacketSocketAddress addr = new PacketSocketAddress((short) ETH_P_IP, mIface.getIndex());
|
PacketSocketAddress addr = new PacketSocketAddress((short) ETH_P_IP, mIface.getIndex());
|
||||||
@@ -285,6 +292,10 @@ public class DhcpClient extends StateMachine {
|
|||||||
Log.e(TAG, "Error creating packet socket", e);
|
Log.e(TAG, "Error creating packet socket", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean initUdpSocket() {
|
||||||
try {
|
try {
|
||||||
mUdpSock = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
mUdpSock = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_REUSEADDR, 1);
|
Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||||
@@ -363,16 +374,25 @@ public class DhcpClient extends StateMachine {
|
|||||||
return (short) ((SystemClock.elapsedRealtime() - mTransactionStartMillis) / 1000);
|
return (short) ((SystemClock.elapsedRealtime() - mTransactionStartMillis) / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean transmitPacket(ByteBuffer buf, String description, Inet4Address to) {
|
private boolean transmitPacket(ByteBuffer buf, String description, int encap, Inet4Address to) {
|
||||||
try {
|
try {
|
||||||
if (to.equals(INADDR_BROADCAST)) {
|
if (encap == DhcpPacket.ENCAP_L2) {
|
||||||
if (DBG) Log.d(TAG, "Broadcasting " + description);
|
if (DBG) Log.d(TAG, "Broadcasting " + description);
|
||||||
Os.sendto(mPacketSock, buf.array(), 0, buf.limit(), 0, mInterfaceBroadcastAddr);
|
Os.sendto(mPacketSock, buf.array(), 0, buf.limit(), 0, mInterfaceBroadcastAddr);
|
||||||
|
} else if (encap == DhcpPacket.ENCAP_BOOTP && to.equals(INADDR_BROADCAST)) {
|
||||||
|
if (DBG) Log.d(TAG, "Broadcasting " + description);
|
||||||
|
// We only send L3-encapped broadcasts in DhcpRebindingState,
|
||||||
|
// where we have an IP address and an unconnected UDP socket.
|
||||||
|
//
|
||||||
|
// N.B.: We only need this codepath because DhcpRequestPacket
|
||||||
|
// hardcodes the source IP address to 0.0.0.0. We could reuse
|
||||||
|
// the packet socket if this ever changes.
|
||||||
|
Os.sendto(mUdpSock, buf, 0, to, DhcpPacket.DHCP_SERVER);
|
||||||
} else {
|
} else {
|
||||||
// It's safe to call getpeername here, because we only send unicast packets if we
|
// It's safe to call getpeername here, because we only send unicast packets if we
|
||||||
// have an IP address, and we connect the UDP socket before
|
// have an IP address, and we connect the UDP socket in DhcpBoundState#enter.
|
||||||
// ConfiguringInterfaceState#exit.
|
if (DBG) Log.d(TAG, String.format("Unicasting %s to %s",
|
||||||
if (DBG) Log.d(TAG, "Unicasting " + description + " to " + Os.getpeername(mUdpSock));
|
description, Os.getpeername(mUdpSock)));
|
||||||
Os.write(mUdpSock, buf);
|
Os.write(mUdpSock, buf);
|
||||||
}
|
}
|
||||||
} catch(ErrnoException|IOException e) {
|
} catch(ErrnoException|IOException e) {
|
||||||
@@ -386,14 +406,15 @@ public class DhcpClient extends StateMachine {
|
|||||||
ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
|
ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
|
||||||
DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr,
|
DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr,
|
||||||
DO_UNICAST, REQUESTED_PARAMS);
|
DO_UNICAST, REQUESTED_PARAMS);
|
||||||
return transmitPacket(packet, "DHCPDISCOVER", INADDR_BROADCAST);
|
return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean sendRequestPacket(
|
private boolean sendRequestPacket(
|
||||||
Inet4Address clientAddress, Inet4Address requestedAddress,
|
Inet4Address clientAddress, Inet4Address requestedAddress,
|
||||||
Inet4Address serverAddress, Inet4Address to) {
|
Inet4Address serverAddress, Inet4Address to) {
|
||||||
// TODO: should we use the transaction ID from the server?
|
// TODO: should we use the transaction ID from the server?
|
||||||
int encap = to.equals(INADDR_BROADCAST) ? DhcpPacket.ENCAP_L2 : DhcpPacket.ENCAP_BOOTP;
|
final int encap = INADDR_ANY.equals(clientAddress)
|
||||||
|
? DhcpPacket.ENCAP_L2 : DhcpPacket.ENCAP_BOOTP;
|
||||||
|
|
||||||
ByteBuffer packet = DhcpPacket.buildRequestPacket(
|
ByteBuffer packet = DhcpPacket.buildRequestPacket(
|
||||||
encap, mTransactionId, getSecs(), clientAddress,
|
encap, mTransactionId, getSecs(), clientAddress,
|
||||||
@@ -403,7 +424,7 @@ public class DhcpClient extends StateMachine {
|
|||||||
String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() +
|
String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() +
|
||||||
" request=" + requestedAddress.getHostAddress() +
|
" request=" + requestedAddress.getHostAddress() +
|
||||||
" serverid=" + serverStr;
|
" serverid=" + serverStr;
|
||||||
return transmitPacket(packet, description, to);
|
return transmitPacket(packet, description, encap, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scheduleLeaseTimers() {
|
private void scheduleLeaseTimers() {
|
||||||
@@ -413,14 +434,21 @@ public class DhcpClient extends StateMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final long now = SystemClock.elapsedRealtime();
|
final long now = SystemClock.elapsedRealtime();
|
||||||
long renewTime = (now + mDhcpLeaseExpiry) / 2;
|
|
||||||
mRenewAlarm.schedule(renewTime);
|
|
||||||
long secondsHence = (renewTime - now) / 1000;
|
|
||||||
Log.d(TAG, "Scheduling renewal in " + secondsHence + "s");
|
|
||||||
|
|
||||||
mExpiryAlarm.schedule(mDhcpLeaseExpiry);
|
// TODO: consider getting the renew and rebind timers from T1 and T2.
|
||||||
secondsHence = (mDhcpLeaseExpiry - now) / 1000;
|
// See also:
|
||||||
Log.d(TAG, "Scheduling expiry in " + secondsHence + "s");
|
// https://tools.ietf.org/html/rfc2131#section-4.4.5
|
||||||
|
// https://tools.ietf.org/html/rfc1533#section-9.9
|
||||||
|
// https://tools.ietf.org/html/rfc1533#section-9.10
|
||||||
|
final long remainingDelay = mDhcpLeaseExpiry - now;
|
||||||
|
final long renewDelay = remainingDelay / 2;
|
||||||
|
final long rebindDelay = remainingDelay * 7 / 8;
|
||||||
|
mRenewAlarm.schedule(now + renewDelay);
|
||||||
|
mRebindAlarm.schedule(now + rebindDelay);
|
||||||
|
mExpiryAlarm.schedule(now + remainingDelay);
|
||||||
|
Log.d(TAG, "Scheduling renewal in " + (renewDelay / 1000) + "s");
|
||||||
|
Log.d(TAG, "Scheduling rebind in " + (rebindDelay / 1000) + "s");
|
||||||
|
Log.d(TAG, "Scheduling expiry in " + (remainingDelay / 1000) + "s");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifySuccess() {
|
private void notifySuccess() {
|
||||||
@@ -719,7 +747,6 @@ public class DhcpClient extends StateMachine {
|
|||||||
|
|
||||||
class DhcpRequestingState extends PacketRetransmittingState {
|
class DhcpRequestingState extends PacketRetransmittingState {
|
||||||
public DhcpRequestingState() {
|
public DhcpRequestingState() {
|
||||||
super();
|
|
||||||
mTimeout = DHCP_TIMEOUT_MS / 2;
|
mTimeout = DHCP_TIMEOUT_MS / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -777,7 +804,11 @@ public class DhcpClient extends StateMachine {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exit() {
|
public void exit() {
|
||||||
|
// Clear any extant alarms.
|
||||||
|
mRenewAlarm.cancel();
|
||||||
|
mRebindAlarm.cancel();
|
||||||
mExpiryAlarm.cancel();
|
mExpiryAlarm.cancel();
|
||||||
|
clearDhcpState();
|
||||||
// Tell IpManager to clear the IPv4 address. There is no need to
|
// Tell IpManager to clear the IPv4 address. There is no need to
|
||||||
// wait for confirmation since any subsequent packets are sent from
|
// wait for confirmation since any subsequent packets are sent from
|
||||||
// INADDR_ANY anyway (DISCOVER, REQUEST).
|
// INADDR_ANY anyway (DISCOVER, REQUEST).
|
||||||
@@ -797,21 +828,7 @@ public class DhcpClient extends StateMachine {
|
|||||||
super.processMessage(message);
|
super.processMessage(message);
|
||||||
switch (message.what) {
|
switch (message.what) {
|
||||||
case EVENT_LINKADDRESS_CONFIGURED:
|
case EVENT_LINKADDRESS_CONFIGURED:
|
||||||
if (mDhcpLease.serverAddress != null &&
|
transitionTo(mDhcpBoundState);
|
||||||
!connectUdpSock(mDhcpLease.serverAddress)) {
|
|
||||||
// There's likely no point in going into DhcpInitState here, we'll probably
|
|
||||||
// just repeat the transaction, get the same IP address as before, and fail.
|
|
||||||
//
|
|
||||||
// NOTE: It is observed that connectUdpSock() basically never fails, due to
|
|
||||||
// SO_BINDTODEVICE. Examining the local socket address shows it will happily
|
|
||||||
// return an IPv4 address from another interface, or even return "0.0.0.0".
|
|
||||||
//
|
|
||||||
// TODO: Consider deleting this check, following testing on several kernels.
|
|
||||||
notifyFailure();
|
|
||||||
transitionTo(mStoppedState);
|
|
||||||
} else {
|
|
||||||
transitionTo(mDhcpBoundState);
|
|
||||||
}
|
|
||||||
return HANDLED;
|
return HANDLED;
|
||||||
default:
|
default:
|
||||||
return NOT_HANDLED;
|
return NOT_HANDLED;
|
||||||
@@ -823,8 +840,19 @@ public class DhcpClient extends StateMachine {
|
|||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
super.enter();
|
super.enter();
|
||||||
// TODO: DhcpStateMachine only supported renewing at 50% of the lease time,
|
if (mDhcpLease.serverAddress != null && !connectUdpSock(mDhcpLease.serverAddress)) {
|
||||||
// and did not support rebinding. Now that the legacy DHCP client is gone, fix this.
|
// There's likely no point in going into DhcpInitState here, we'll probably
|
||||||
|
// just repeat the transaction, get the same IP address as before, and fail.
|
||||||
|
//
|
||||||
|
// NOTE: It is observed that connectUdpSock() basically never fails, due to
|
||||||
|
// SO_BINDTODEVICE. Examining the local socket address shows it will happily
|
||||||
|
// return an IPv4 address from another interface, or even return "0.0.0.0".
|
||||||
|
//
|
||||||
|
// TODO: Consider deleting this check, following testing on several kernels.
|
||||||
|
notifyFailure();
|
||||||
|
transitionTo(mStoppedState);
|
||||||
|
}
|
||||||
|
|
||||||
scheduleLeaseTimers();
|
scheduleLeaseTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -843,18 +871,10 @@ public class DhcpClient extends StateMachine {
|
|||||||
return NOT_HANDLED;
|
return NOT_HANDLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void exit() {
|
|
||||||
mRenewAlarm.cancel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DhcpRenewingState extends PacketRetransmittingState {
|
abstract class DhcpReacquiringState extends PacketRetransmittingState {
|
||||||
public DhcpRenewingState() {
|
protected String mLeaseMsg;
|
||||||
super();
|
|
||||||
mTimeout = DHCP_TIMEOUT_MS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
@@ -862,16 +882,14 @@ public class DhcpClient extends StateMachine {
|
|||||||
startNewTransaction();
|
startNewTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract protected Inet4Address packetDestination();
|
||||||
|
|
||||||
protected boolean sendPacket() {
|
protected boolean sendPacket() {
|
||||||
// Not specifying a SERVER_IDENTIFIER option is a violation of RFC 2131, but...
|
|
||||||
// http://b/25343517 . Try to make things work anyway by using broadcast renews.
|
|
||||||
Inet4Address to = (mDhcpLease.serverAddress != null) ?
|
|
||||||
mDhcpLease.serverAddress : INADDR_BROADCAST;
|
|
||||||
return sendRequestPacket(
|
return sendRequestPacket(
|
||||||
(Inet4Address) mDhcpLease.ipAddress.getAddress(), // ciaddr
|
(Inet4Address) mDhcpLease.ipAddress.getAddress(), // ciaddr
|
||||||
INADDR_ANY, // DHCP_REQUESTED_IP
|
INADDR_ANY, // DHCP_REQUESTED_IP
|
||||||
null, // DHCP_SERVER_IDENTIFIER
|
null, // DHCP_SERVER_IDENTIFIER
|
||||||
to); // packet destination address
|
packetDestination()); // packet destination address
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void receivePacket(DhcpPacket packet) {
|
protected void receivePacket(DhcpPacket packet) {
|
||||||
@@ -890,7 +908,7 @@ public class DhcpClient extends StateMachine {
|
|||||||
// in IpManager and by any overridden relevant handlers of
|
// in IpManager and by any overridden relevant handlers of
|
||||||
// the registered IpManager.Callback. IP address changes
|
// the registered IpManager.Callback. IP address changes
|
||||||
// are not supported here.
|
// are not supported here.
|
||||||
acceptDhcpResults(results, "Renewed");
|
acceptDhcpResults(results, mLeaseMsg);
|
||||||
transitionTo(mDhcpBoundState);
|
transitionTo(mDhcpBoundState);
|
||||||
}
|
}
|
||||||
} else if (packet instanceof DhcpNakPacket) {
|
} else if (packet instanceof DhcpNakPacket) {
|
||||||
@@ -901,8 +919,57 @@ public class DhcpClient extends StateMachine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not implemented--yet. DhcpStateMachine did not implement it either.
|
class DhcpRenewingState extends DhcpReacquiringState {
|
||||||
class DhcpRebindingState extends LoggingState {
|
public DhcpRenewingState() {
|
||||||
|
mLeaseMsg = "Renewed";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean processMessage(Message message) {
|
||||||
|
if (super.processMessage(message) == HANDLED) {
|
||||||
|
return HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (message.what) {
|
||||||
|
case CMD_REBIND_DHCP:
|
||||||
|
transitionTo(mDhcpRebindingState);
|
||||||
|
return HANDLED;
|
||||||
|
default:
|
||||||
|
return NOT_HANDLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Inet4Address packetDestination() {
|
||||||
|
// Not specifying a SERVER_IDENTIFIER option is a violation of RFC 2131, but...
|
||||||
|
// http://b/25343517 . Try to make things work anyway by using broadcast renews.
|
||||||
|
return (mDhcpLease.serverAddress != null) ?
|
||||||
|
mDhcpLease.serverAddress : INADDR_BROADCAST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DhcpRebindingState extends DhcpReacquiringState {
|
||||||
|
public DhcpRebindingState() {
|
||||||
|
mLeaseMsg = "Rebound";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enter() {
|
||||||
|
super.enter();
|
||||||
|
|
||||||
|
// We need to broadcast and possibly reconnect the socket to a
|
||||||
|
// completely different server.
|
||||||
|
closeQuietly(mUdpSock);
|
||||||
|
if (!initUdpSocket()) {
|
||||||
|
Log.e(TAG, "Failed to recreate UDP socket");
|
||||||
|
transitionTo(mDhcpInitState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Inet4Address packetDestination() {
|
||||||
|
return INADDR_BROADCAST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DhcpInitRebootState extends LoggingState {
|
class DhcpInitRebootState extends LoggingState {
|
||||||
|
|||||||
@@ -1027,6 +1027,8 @@ public class IpManager extends StateMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class StartedState extends State {
|
class StartedState extends State {
|
||||||
|
private boolean mDhcpActionInFlight;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
mStartTimeMillis = SystemClock.elapsedRealtime();
|
mStartTimeMillis = SystemClock.elapsedRealtime();
|
||||||
@@ -1066,7 +1068,7 @@ public class IpManager extends StateMachine {
|
|||||||
@Override
|
@Override
|
||||||
public void exit() {
|
public void exit() {
|
||||||
mProvisioningTimeoutAlarm.cancel();
|
mProvisioningTimeoutAlarm.cancel();
|
||||||
mDhcpActionTimeoutAlarm.cancel();
|
stopDhcpAction();
|
||||||
|
|
||||||
if (mIpReachabilityMonitor != null) {
|
if (mIpReachabilityMonitor != null) {
|
||||||
mIpReachabilityMonitor.stop();
|
mIpReachabilityMonitor.stop();
|
||||||
@@ -1086,16 +1088,22 @@ public class IpManager extends StateMachine {
|
|||||||
resetLinkProperties();
|
resetLinkProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startDhcpAction() {
|
private void ensureDhcpAction() {
|
||||||
mCallback.onPreDhcpAction();
|
if (!mDhcpActionInFlight) {
|
||||||
final long alarmTime = SystemClock.elapsedRealtime() +
|
mCallback.onPreDhcpAction();
|
||||||
mConfiguration.mRequestedPreDhcpActionMs;
|
mDhcpActionInFlight = true;
|
||||||
mDhcpActionTimeoutAlarm.schedule(alarmTime);
|
final long alarmTime = SystemClock.elapsedRealtime() +
|
||||||
|
mConfiguration.mRequestedPreDhcpActionMs;
|
||||||
|
mDhcpActionTimeoutAlarm.schedule(alarmTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopDhcpAction() {
|
private void stopDhcpAction() {
|
||||||
mDhcpActionTimeoutAlarm.cancel();
|
mDhcpActionTimeoutAlarm.cancel();
|
||||||
mCallback.onPostDhcpAction();
|
if (mDhcpActionInFlight) {
|
||||||
|
mCallback.onPostDhcpAction();
|
||||||
|
mDhcpActionInFlight = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1165,9 +1173,8 @@ public class IpManager extends StateMachine {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DhcpClient.CMD_PRE_DHCP_ACTION:
|
case DhcpClient.CMD_PRE_DHCP_ACTION:
|
||||||
if (VDBG) { Log.d(mTag, "onPreDhcpAction()"); }
|
|
||||||
if (mConfiguration.mRequestedPreDhcpActionMs > 0) {
|
if (mConfiguration.mRequestedPreDhcpActionMs > 0) {
|
||||||
startDhcpAction();
|
ensureDhcpAction();
|
||||||
} else {
|
} else {
|
||||||
sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
|
sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
|
||||||
}
|
}
|
||||||
@@ -1193,18 +1200,18 @@ public class IpManager extends StateMachine {
|
|||||||
// This message is only received when:
|
// This message is only received when:
|
||||||
//
|
//
|
||||||
// a) initial address acquisition succeeds,
|
// a) initial address acquisition succeeds,
|
||||||
// b) renew succeeds,
|
// b) renew succeeds or is NAK'd,
|
||||||
// c) renew fails,
|
// c) rebind succeeds or is NAK'd, or
|
||||||
|
// c) the lease expires,
|
||||||
//
|
//
|
||||||
// but never when initial address acquisition fails. The latter
|
// but never when initial address acquisition fails. The latter
|
||||||
// condition is now governed by the provisioning timeout.
|
// condition is now governed by the provisioning timeout.
|
||||||
case DhcpClient.CMD_POST_DHCP_ACTION: {
|
case DhcpClient.CMD_POST_DHCP_ACTION:
|
||||||
stopDhcpAction();
|
stopDhcpAction();
|
||||||
|
|
||||||
final DhcpResults dhcpResults = (DhcpResults) msg.obj;
|
|
||||||
switch (msg.arg1) {
|
switch (msg.arg1) {
|
||||||
case DhcpClient.DHCP_SUCCESS:
|
case DhcpClient.DHCP_SUCCESS:
|
||||||
handleIPv4Success(dhcpResults);
|
handleIPv4Success((DhcpResults) msg.obj);
|
||||||
break;
|
break;
|
||||||
case DhcpClient.DHCP_FAILURE:
|
case DhcpClient.DHCP_FAILURE:
|
||||||
handleIPv4Failure();
|
handleIPv4Failure();
|
||||||
@@ -1213,7 +1220,6 @@ public class IpManager extends StateMachine {
|
|||||||
Log.e(mTag, "Unknown CMD_POST_DHCP_ACTION status:" + msg.arg1);
|
Log.e(mTag, "Unknown CMD_POST_DHCP_ACTION status:" + msg.arg1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case DhcpClient.CMD_ON_QUIT:
|
case DhcpClient.CMD_ON_QUIT:
|
||||||
// DHCPv4 quit early for some reason.
|
// DHCPv4 quit early for some reason.
|
||||||
|
|||||||
Reference in New Issue
Block a user