summaryrefslogtreecommitdiffstats
path: root/services/net
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2015-06-02 13:15:50 +0900
committerLorenzo Colitti <lorenzo@google.com>2015-06-02 16:21:17 +0900
commitd973537ee1bd013b4233d3369d66821e124a2e65 (patch)
tree57f67609e47e2964b1726b700042425bffe5134c /services/net
parent99fbb56a0ab81ead404480f0c2df529332a93a32 (diff)
downloadframeworks_base-d973537ee1bd013b4233d3369d66821e124a2e65.zip
frameworks_base-d973537ee1bd013b4233d3369d66821e124a2e65.tar.gz
frameworks_base-d973537ee1bd013b4233d3369d66821e124a2e65.tar.bz2
Fix DHCP lease time parsing.
Currently we treat a lease time larger than 2**31-1 as a negative value, which causes DhcpClient to attempt to renew its IP address constantly. Fix this by properly handling large and infinite lifetimes, and while we're at it, impose a minimum lease time of 60 seconds. Bug: 21352084 Change-Id: If62c9efeffad6222e2fe0c110f77d0e4c70de96d
Diffstat (limited to 'services/net')
-rw-r--r--services/net/java/android/net/dhcp/DhcpClient.java28
-rw-r--r--services/net/java/android/net/dhcp/DhcpPacket.java22
2 files changed, 38 insertions, 12 deletions
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index e1d1787..1ee34cc 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -390,11 +390,15 @@ public class DhcpClient extends BaseDhcpStateMachine {
}
private void scheduleRenew() {
- long now = SystemClock.elapsedRealtime();
- long alarmTime = (now + mDhcpLeaseExpiry) / 2;
mAlarmManager.cancel(mRenewIntent);
- mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime, mRenewIntent);
- Log.d(TAG, "Scheduling renewal in " + ((alarmTime - now) / 1000) + "s");
+ if (mDhcpLeaseExpiry != 0) {
+ long now = SystemClock.elapsedRealtime();
+ long alarmTime = (now + mDhcpLeaseExpiry) / 2;
+ mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime, mRenewIntent);
+ Log.d(TAG, "Scheduling renewal in " + ((alarmTime - now) / 1000) + "s");
+ } else {
+ Log.d(TAG, "Infinite lease, no renewal needed");
+ }
}
private void notifyLease() {
@@ -586,6 +590,12 @@ public class DhcpClient extends BaseDhcpStateMachine {
return true;
}
+ public void setDhcpLeaseExpiry(DhcpPacket packet) {
+ long leaseTimeMillis = packet.getLeaseTimeMillis();
+ mDhcpLeaseExpiry =
+ (leaseTimeMillis > 0) ? SystemClock.elapsedRealtime() + leaseTimeMillis : 0;
+ }
+
/**
* Retransmits packets using jittered exponential backoff with an optional timeout. Packet
* transmission is triggered by CMD_KICK, which is sent by an AlarmManager alarm.
@@ -723,10 +733,9 @@ public class DhcpClient extends BaseDhcpStateMachine {
DhcpResults results = packet.toDhcpResults();
if (results != null) {
mDhcpLease = results;
- Log.d(TAG, "Confirmed lease: " + mDhcpLease);
- mDhcpLeaseExpiry = SystemClock.elapsedRealtime() +
- mDhcpLease.leaseDuration * 1000;
mOffer = null;
+ Log.d(TAG, "Confirmed lease: " + mDhcpLease);
+ setDhcpLeaseExpiry(packet);
transitionTo(mDhcpBoundState);
}
} else if (packet instanceof DhcpNakPacket) {
@@ -797,10 +806,7 @@ public class DhcpClient extends BaseDhcpStateMachine {
protected void receivePacket(DhcpPacket packet) {
if (!isValidPacket(packet)) return;
if ((packet instanceof DhcpAckPacket)) {
- DhcpResults results = packet.toDhcpResults();
- mDhcpLease.leaseDuration = results.leaseDuration;
- mDhcpLeaseExpiry = SystemClock.elapsedRealtime() +
- mDhcpLease.leaseDuration * 1000;
+ setDhcpLeaseExpiry(packet);
transitionTo(mDhcpBoundState);
} else if (packet instanceof DhcpNakPacket) {
transitionTo(mDhcpInitState);
diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java
index b923b1b..2a25d30 100644
--- a/services/net/java/android/net/dhcp/DhcpPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpPacket.java
@@ -28,6 +28,12 @@ import java.util.List;
abstract class DhcpPacket {
protected static final String TAG = "DhcpPacket";
+ // dhcpcd has a minimum lease of 20 seconds, but DhcpStateMachine would refuse to wake up the
+ // CPU for anything shorter than 5 minutes. For sanity's sake, this must be higher than the
+ // DHCP client timeout.
+ public static final int MINIMUM_LEASE = 60;
+ public static final int INFINITE_LEASE = (int) 0xffffffff;
+
public static final Inet4Address INADDR_ANY = (Inet4Address) Inet4Address.ANY;
public static final Inet4Address INADDR_BROADCAST = (Inet4Address) Inet4Address.ALL;
public static final byte[] ETHER_BROADCAST = new byte[] {
@@ -1006,11 +1012,25 @@ abstract class DhcpPacket {
results.domains = mDomainName;
results.serverAddress = mServerIdentifier;
results.vendorInfo = mVendorId;
- results.leaseDuration = mLeaseTime;
+ results.leaseDuration = (mLeaseTime != null) ? mLeaseTime : INFINITE_LEASE;
return results;
}
/**
+ * Returns the parsed lease time, in milliseconds, or 0 for infinite.
+ */
+ public long getLeaseTimeMillis() {
+ // dhcpcd treats the lack of a lease time option as an infinite lease.
+ if (mLeaseTime == null || mLeaseTime == INFINITE_LEASE) {
+ return 0;
+ } else if (0 <= mLeaseTime && mLeaseTime < MINIMUM_LEASE) {
+ return MINIMUM_LEASE * 1000;
+ } else {
+ return (mLeaseTime & 0xffffffffL) * 1000;
+ }
+ }
+
+ /**
* Builds a DHCP-DISCOVER packet from the required specified
* parameters.
*/