summaryrefslogtreecommitdiff
path: root/src/android/net/dhcp/DhcpLeaseRepository.java
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2020-02-18 00:47:21 +0900
committerLorenzo Colitti <lorenzo@google.com>2020-02-18 10:49:59 +0900
commitb4af853264c8d0083491e35b2e157355bf8919bd (patch)
tree175f96b1e33b7fe92e52ab6246415fa45b8dbab8 /src/android/net/dhcp/DhcpLeaseRepository.java
parent886e641f32fd6487fe3cecdf1c8f9a056237e030 (diff)
Revert "Revert "Add DhcpLeaseCallbacks""
This reverts commit e8fff42022f8c22e84d51bc093189d469bdd9af1. Bug: 135411507 Test: atest NetworkStackTests Change-Id: I0609301d7b37309a35c764a7551b0ca93b3faeee
Diffstat (limited to 'src/android/net/dhcp/DhcpLeaseRepository.java')
-rw-r--r--src/android/net/dhcp/DhcpLeaseRepository.java66
1 files changed, 57 insertions, 9 deletions
diff --git a/src/android/net/dhcp/DhcpLeaseRepository.java b/src/android/net/dhcp/DhcpLeaseRepository.java
index 4e74dc8..1dc2f7f 100644
--- a/src/android/net/dhcp/DhcpLeaseRepository.java
+++ b/src/android/net/dhcp/DhcpLeaseRepository.java
@@ -31,6 +31,8 @@ import android.net.IpPrefix;
import android.net.MacAddress;
import android.net.dhcp.DhcpServer.Clock;
import android.net.util.SharedLog;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
import android.util.ArrayMap;
import androidx.annotation.NonNull;
@@ -45,6 +47,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
@@ -73,6 +76,7 @@ class DhcpLeaseRepository {
@NonNull
private Set<Inet4Address> mReservedAddrs;
private int mSubnetAddr;
+ private int mPrefixLength;
private int mSubnetMask;
private int mNumAddresses;
private long mLeaseTimeMs;
@@ -84,6 +88,9 @@ class DhcpLeaseRepository {
*/
private long mNextExpirationCheck = EXPIRATION_NEVER;
+ @NonNull
+ private RemoteCallbackList<IDhcpLeaseCallbacks> mLeaseCallbacks = new RemoteCallbackList<>();
+
static class DhcpLeaseException extends Exception {
DhcpLeaseException(String message) {
super(message);
@@ -131,27 +138,34 @@ class DhcpLeaseRepository {
long leaseTimeMs) {
mPrefix = prefix;
mReservedAddrs = Collections.unmodifiableSet(new HashSet<>(reservedAddrs));
- mSubnetMask = prefixLengthToV4NetmaskIntHTH(prefix.getPrefixLength());
+ mPrefixLength = prefix.getPrefixLength();
+ mSubnetMask = prefixLengthToV4NetmaskIntHTH(mPrefixLength);
mSubnetAddr = inet4AddressToIntHTH((Inet4Address) prefix.getAddress()) & mSubnetMask;
mNumAddresses = 1 << (IPV4_ADDR_BITS - prefix.getPrefixLength());
mLeaseTimeMs = leaseTimeMs;
- cleanMap(mCommittedLeases);
cleanMap(mDeclinedAddrs);
+ if (cleanMap(mCommittedLeases)) {
+ notifyLeasesChanged();
+ }
}
/**
* From a map keyed by {@link Inet4Address}, remove entries where the key is invalid (as
* specified by {@link #isValidAddress(Inet4Address)}), or is a reserved address.
+ * @return true iff at least one entry was removed.
*/
- private <T> void cleanMap(Map<Inet4Address, T> map) {
+ private <T> boolean cleanMap(Map<Inet4Address, T> map) {
final Iterator<Entry<Inet4Address, T>> it = map.entrySet().iterator();
+ boolean removed = false;
while (it.hasNext()) {
final Inet4Address addr = it.next().getKey();
if (!isValidAddress(addr) || mReservedAddrs.contains(addr)) {
it.remove();
+ removed = true;
}
}
+ return removed;
}
/**
@@ -181,7 +195,7 @@ class DhcpLeaseRepository {
mLog.log("Offering extended lease " + newLease);
// Do not update lease time in the map: the offer is not committed yet.
} else if (reqAddr != null && isValidAddress(reqAddr) && isAvailable(reqAddr)) {
- newLease = new DhcpLease(clientId, hwAddr, reqAddr, expTime, hostname);
+ newLease = new DhcpLease(clientId, hwAddr, reqAddr, mPrefixLength, expTime, hostname);
mLog.log("Offering requested lease " + newLease);
} else {
newLease = makeNewOffer(clientId, hwAddr, expTime, hostname);
@@ -267,7 +281,8 @@ class DhcpLeaseRepository {
if (assignedLease != null) {
if (sidSet && reqAddr != null) {
// Client in SELECTING state; remove any current lease before creating a new one.
- mCommittedLeases.remove(assignedLease.getNetAddr());
+ // Do not notify of change as it will be done when the new lease is committed.
+ removeLease(assignedLease.getNetAddr(), false /* notifyChange */);
} else if (!assignedLease.getNetAddr().equals(leaseAddr)) {
// reqAddr null (RENEWING/REBINDING): client renewing its own lease for clientAddr.
// reqAddr set with sid not set (INIT-REBOOT): client verifying configuration.
@@ -314,7 +329,7 @@ class DhcpLeaseRepository {
final DhcpLease lease;
if (currentLease == null) {
if (isValidAddress(addr) && !mReservedAddrs.contains(addr)) {
- lease = new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
+ lease = new DhcpLease(clientId, hwAddr, addr, mPrefixLength, expTime, hostname);
} else {
throw new InvalidAddressException("Lease not found and address unavailable");
}
@@ -328,6 +343,13 @@ class DhcpLeaseRepository {
private void commitLease(@NonNull DhcpLease lease) {
mCommittedLeases.put(lease.getNetAddr(), lease);
maybeUpdateEarliestExpiration(lease.getExpTime());
+ notifyLeasesChanged();
+ }
+
+ private void removeLease(@NonNull Inet4Address address, boolean notifyChange) {
+ // Earliest expiration remains <= the first expiry time on remove, so no need to update it.
+ mCommittedLeases.remove(address);
+ if (notifyChange) notifyLeasesChanged();
}
/**
@@ -343,8 +365,8 @@ class DhcpLeaseRepository {
return false;
}
if (currentLease.matchesClient(clientId, hwAddr)) {
- mCommittedLeases.remove(addr);
mLog.log("Released lease " + currentLease);
+ removeLease(addr, true /* notifyChange */);
return true;
}
mLog.w(String.format("Not releasing lease %s: does not match client (cid %s, hwAddr %s)",
@@ -352,6 +374,24 @@ class DhcpLeaseRepository {
return false;
}
+ private void notifyLeasesChanged() {
+ final List<DhcpLeaseParcelable> leaseParcelables =
+ new ArrayList<>(mCommittedLeases.size());
+ for (DhcpLease committedLease : mCommittedLeases.values()) {
+ leaseParcelables.add(committedLease.toParcelable());
+ }
+
+ final int cbCount = mLeaseCallbacks.beginBroadcast();
+ for (int i = 0; i < cbCount; i++) {
+ try {
+ mLeaseCallbacks.getBroadcastItem(i).onLeasesChanged(leaseParcelables);
+ } catch (RemoteException e) {
+ mLog.e("Could not send lease callback", e);
+ }
+ }
+ mLeaseCallbacks.finishBroadcast();
+ }
+
public void markLeaseDeclined(@NonNull Inet4Address addr) {
if (mDeclinedAddrs.containsKey(addr) || !isValidAddress(addr)) {
mLog.logf("Not marking %s as declined: already declined or not assignable",
@@ -383,6 +423,14 @@ class DhcpLeaseRepository {
}
/**
+ * Add callbacks that will be called on leases update.
+ */
+ public void addLeaseCallbacks(@NonNull IDhcpLeaseCallbacks cb) {
+ Objects.requireNonNull(cb, "Callbacks must be non-null");
+ mLeaseCallbacks.register(cb);
+ }
+
+ /**
* Given the expiration time of a new committed lease or declined address, update
* {@link #mNextExpirationCheck} so it stays lower than or equal to the time for the first lease
* to expire.
@@ -541,7 +589,7 @@ class DhcpLeaseRepository {
for (int i = 0; i < mNumAddresses; i++) {
final Inet4Address addr = intToInet4AddressHTH(intAddr);
if (isAvailable(addr) && !mDeclinedAddrs.containsKey(addr)) {
- return new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
+ return new DhcpLease(clientId, hwAddr, addr, mPrefixLength, expTime, hostname);
}
intAddr = getNextAddress(intAddr);
}
@@ -557,7 +605,7 @@ class DhcpLeaseRepository {
// However declined addresses may have been requested (typically by the machine that was
// already using the address) after being declined.
if (isAvailable(addr)) {
- return new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
+ return new DhcpLease(clientId, hwAddr, addr, mPrefixLength, expTime, hostname);
}
}