Assign specific client address to dhcp server
Bug: 141256482
Test: manual
atest TetheringTests
Merged-In: Ief76c98c843ba5420224cbf0f34464f366c891b7
Change-Id: Ief76c98c843ba5420224cbf0f34464f366c891b7
diff --git a/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java b/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
index d6bc063..82a26be 100644
--- a/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
+++ b/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
@@ -18,10 +18,12 @@
import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import android.annotation.NonNull;
import android.net.LinkAddress;
import android.util.ArraySet;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import java.net.Inet4Address;
import java.util.Collection;
import java.util.Collections;
@@ -160,6 +162,17 @@
return this;
}
+ /**
+ * Set the client address to tell DHCP server only offer this address.
+ * The client's prefix length is the same as server's.
+ *
+ * <p>If not set, the default value is null.
+ */
+ public DhcpServingParamsParcelExt setSingleClientAddr(@Nullable Inet4Address clientAddr) {
+ this.clientAddr = clientAddr == null ? 0 : inet4AddressToIntHTH(clientAddr);
+ return this;
+ }
+
private static int[] toIntArray(@NonNull Collection<Inet4Address> addrs) {
int[] res = new int[addrs.size()];
int i = 0;
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index 5b6fe91..1dac5b7 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -18,6 +18,7 @@
import static android.net.InetAddresses.parseNumericAddress;
import static android.net.RouteInfo.RTN_UNICAST;
+import static android.net.TetheringManager.TetheringRequest.checkStaticAddressConfiguration;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
import static android.net.util.NetworkConstants.FF;
@@ -511,17 +512,24 @@
}
}
- private boolean startDhcp(Inet4Address addr, int prefixLen) {
+ private boolean startDhcp(final LinkAddress serverLinkAddr, final LinkAddress clientLinkAddr) {
if (mUsingLegacyDhcp) {
return true;
}
+
+ final Inet4Address addr = (Inet4Address) serverLinkAddr.getAddress();
+ final int prefixLen = serverLinkAddr.getPrefixLength();
+ final Inet4Address clientAddr = clientLinkAddr == null ? null :
+ (Inet4Address) clientLinkAddr.getAddress();
+
final DhcpServingParamsParcel params;
params = new DhcpServingParamsParcelExt()
.setDefaultRouters(addr)
.setDhcpLeaseTimeSecs(DHCP_LEASE_TIME_SECS)
.setDnsServers(addr)
- .setServerAddr(new LinkAddress(addr, prefixLen))
- .setMetered(true);
+ .setServerAddr(serverLinkAddr)
+ .setMetered(true)
+ .setSingleClientAddr(clientAddr);
// TODO: also advertise link MTU
mDhcpServerStartIndex++;
@@ -556,9 +564,10 @@
}
}
- private boolean configureDhcp(boolean enable, Inet4Address addr, int prefixLen) {
+ private boolean configureDhcp(boolean enable, final LinkAddress serverAddr,
+ final LinkAddress clientAddr) {
if (enable) {
- return startDhcp(addr, prefixLen);
+ return startDhcp(serverAddr, clientAddr);
} else {
stopDhcp();
return true;
@@ -606,7 +615,7 @@
// code that calls into NetworkManagementService directly.
srvAddr = (Inet4Address) parseNumericAddress(BLUETOOTH_IFACE_ADDR);
mIpv4Address = new LinkAddress(srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
- return configureDhcp(enabled, srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
+ return configureDhcp(enabled, mIpv4Address, null /* clientAddress */);
}
mIpv4Address = new LinkAddress(srvAddr, prefixLen);
} catch (IllegalArgumentException e) {
@@ -643,7 +652,7 @@
mLinkProperties.removeRoute(route);
}
- return configureDhcp(enabled, srvAddr, prefixLen);
+ return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr);
}
private String getRandomWifiIPv4Address() {
@@ -962,7 +971,14 @@
}
private void maybeConfigureStaticIp(final TetheringRequestParcel request) {
- if (request == null) return;
+ // Ignore static address configuration if they are invalid or null. In theory, static
+ // addresses should not be invalid here because TetheringManager do not allow caller to
+ // specify invalid static address configuration.
+ if (request == null || request.localIPv4Address == null
+ || request.staticClientAddress == null || !checkStaticAddressConfiguration(
+ request.localIPv4Address, request.staticClientAddress)) {
+ return;
+ }
mStaticIpv4ServerAddr = request.localIPv4Address;
mStaticIpv4ClientAddr = request.staticClientAddress;