Loading packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java +16 −7 Original line number Diff line number Diff line Loading @@ -571,9 +571,8 @@ public class TetheringManager { /** * Configure tethering with static IPv4 assignment. * * The clientAddress must be in the localIPv4Address prefix. A DHCP server will be * started, but will only be able to offer the client address. The two addresses must * be in the same prefix. * A DHCP server will be started, but will only be able to offer the client address. * The two addresses must be in the same prefix. * * @param localIPv4Address The preferred local IPv4 link address to use. * @param clientAddress The static client address. Loading @@ -584,10 +583,7 @@ public class TetheringManager { @NonNull final LinkAddress clientAddress) { Objects.requireNonNull(localIPv4Address); Objects.requireNonNull(clientAddress); if (localIPv4Address.getPrefixLength() != clientAddress.getPrefixLength() || !localIPv4Address.isIpv4() || !clientAddress.isIpv4() || !new IpPrefix(localIPv4Address.toString()).equals( new IpPrefix(clientAddress.toString()))) { if (!checkStaticAddressConfiguration(localIPv4Address, clientAddress)) { throw new IllegalArgumentException("Invalid server or client addresses"); } Loading Loading @@ -656,6 +652,19 @@ public class TetheringManager { return mRequestParcel.showProvisioningUi; } /** * Check whether the two addresses are ipv4 and in the same prefix. * @hide */ public static boolean checkStaticAddressConfiguration( @NonNull final LinkAddress localIPv4Address, @NonNull final LinkAddress clientAddress) { return localIPv4Address.getPrefixLength() == clientAddress.getPrefixLength() && localIPv4Address.isIpv4() && clientAddress.isIpv4() && new IpPrefix(localIPv4Address.toString()).equals( new IpPrefix(clientAddress.toString())); } /** * Get a TetheringRequestParcel from the configuration * @hide Loading packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java +14 −1 Original line number Diff line number Diff line Loading @@ -18,10 +18,12 @@ package android.net.dhcp; 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; Loading Loading @@ -160,6 +162,17 @@ public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel { 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; Loading packages/Tethering/src/android/net/ip/IpServer.java +24 −8 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.net.ip; 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; Loading Loading @@ -511,17 +512,24 @@ public class IpServer extends StateMachine { } } 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++; Loading Loading @@ -556,9 +564,10 @@ public class IpServer extends StateMachine { } } 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; Loading Loading @@ -606,7 +615,7 @@ public class IpServer extends StateMachine { // 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) { Loading Loading @@ -643,7 +652,7 @@ public class IpServer extends StateMachine { mLinkProperties.removeRoute(route); } return configureDhcp(enabled, srvAddr, prefixLen); return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr); } private String getRandomWifiIPv4Address() { Loading Loading @@ -962,7 +971,14 @@ public class IpServer extends StateMachine { } 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; Loading packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java +8 −0 Original line number Diff line number Diff line Loading @@ -42,7 +42,9 @@ import java.util.stream.IntStream; @SmallTest public class DhcpServingParamsParcelExtTest { private static final Inet4Address TEST_ADDRESS = inet4Addr("192.168.0.123"); private static final Inet4Address TEST_CLIENT_ADDRESS = inet4Addr("192.168.0.42"); private static final int TEST_ADDRESS_PARCELED = 0xc0a8007b; private static final int TEST_CLIENT_ADDRESS_PARCELED = 0xc0a8002a; private static final int TEST_PREFIX_LENGTH = 17; private static final int TEST_LEASE_TIME_SECS = 120; private static final int TEST_MTU = 1000; Loading Loading @@ -105,6 +107,12 @@ public class DhcpServingParamsParcelExtTest { assertFalse(mParcel.metered); } @Test public void testSetClientAddr() { mParcel.setSingleClientAddr(TEST_CLIENT_ADDRESS); assertEquals(TEST_CLIENT_ADDRESS_PARCELED, mParcel.clientAddr); } private static Inet4Address inet4Addr(String addr) { return (Inet4Address) parseNumericAddress(addr); } Loading packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +14 −6 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS; import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; Loading Loading @@ -1668,10 +1669,13 @@ public class TetheringTest { } @Test public void testRequestStaticServerIp() throws Exception { final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24"); final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24"); final String serverAddr = "192.168.20.1"; public void testRequestStaticIp() throws Exception { final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24"); final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24"); final String serverAddr = "192.168.0.123"; final int clientAddrParceled = 0xc0a8002a; final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor = ArgumentCaptor.forClass(DhcpServingParamsParcel.class); mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB, serverLinkAddr, clientLinkAddr), null); mLooper.dispatchAll(); Loading @@ -1680,8 +1684,12 @@ public class TetheringTest { sendUsbBroadcast(true, true, true, TETHERING_USB); mLooper.dispatchAll(); verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr))); // TODO: test static client address. verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(), any()); final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue(); assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress()); assertEquals(24, params.serverAddrPrefixLength); assertEquals(clientAddrParceled, params.clientAddr); } // TODO: Test that a request for hotspot mode doesn't interfere with an Loading Loading
packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java +16 −7 Original line number Diff line number Diff line Loading @@ -571,9 +571,8 @@ public class TetheringManager { /** * Configure tethering with static IPv4 assignment. * * The clientAddress must be in the localIPv4Address prefix. A DHCP server will be * started, but will only be able to offer the client address. The two addresses must * be in the same prefix. * A DHCP server will be started, but will only be able to offer the client address. * The two addresses must be in the same prefix. * * @param localIPv4Address The preferred local IPv4 link address to use. * @param clientAddress The static client address. Loading @@ -584,10 +583,7 @@ public class TetheringManager { @NonNull final LinkAddress clientAddress) { Objects.requireNonNull(localIPv4Address); Objects.requireNonNull(clientAddress); if (localIPv4Address.getPrefixLength() != clientAddress.getPrefixLength() || !localIPv4Address.isIpv4() || !clientAddress.isIpv4() || !new IpPrefix(localIPv4Address.toString()).equals( new IpPrefix(clientAddress.toString()))) { if (!checkStaticAddressConfiguration(localIPv4Address, clientAddress)) { throw new IllegalArgumentException("Invalid server or client addresses"); } Loading Loading @@ -656,6 +652,19 @@ public class TetheringManager { return mRequestParcel.showProvisioningUi; } /** * Check whether the two addresses are ipv4 and in the same prefix. * @hide */ public static boolean checkStaticAddressConfiguration( @NonNull final LinkAddress localIPv4Address, @NonNull final LinkAddress clientAddress) { return localIPv4Address.getPrefixLength() == clientAddress.getPrefixLength() && localIPv4Address.isIpv4() && clientAddress.isIpv4() && new IpPrefix(localIPv4Address.toString()).equals( new IpPrefix(clientAddress.toString())); } /** * Get a TetheringRequestParcel from the configuration * @hide Loading
packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java +14 −1 Original line number Diff line number Diff line Loading @@ -18,10 +18,12 @@ package android.net.dhcp; 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; Loading Loading @@ -160,6 +162,17 @@ public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel { 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; Loading
packages/Tethering/src/android/net/ip/IpServer.java +24 −8 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.net.ip; 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; Loading Loading @@ -511,17 +512,24 @@ public class IpServer extends StateMachine { } } 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++; Loading Loading @@ -556,9 +564,10 @@ public class IpServer extends StateMachine { } } 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; Loading Loading @@ -606,7 +615,7 @@ public class IpServer extends StateMachine { // 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) { Loading Loading @@ -643,7 +652,7 @@ public class IpServer extends StateMachine { mLinkProperties.removeRoute(route); } return configureDhcp(enabled, srvAddr, prefixLen); return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr); } private String getRandomWifiIPv4Address() { Loading Loading @@ -962,7 +971,14 @@ public class IpServer extends StateMachine { } 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; Loading
packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java +8 −0 Original line number Diff line number Diff line Loading @@ -42,7 +42,9 @@ import java.util.stream.IntStream; @SmallTest public class DhcpServingParamsParcelExtTest { private static final Inet4Address TEST_ADDRESS = inet4Addr("192.168.0.123"); private static final Inet4Address TEST_CLIENT_ADDRESS = inet4Addr("192.168.0.42"); private static final int TEST_ADDRESS_PARCELED = 0xc0a8007b; private static final int TEST_CLIENT_ADDRESS_PARCELED = 0xc0a8002a; private static final int TEST_PREFIX_LENGTH = 17; private static final int TEST_LEASE_TIME_SECS = 120; private static final int TEST_MTU = 1000; Loading Loading @@ -105,6 +107,12 @@ public class DhcpServingParamsParcelExtTest { assertFalse(mParcel.metered); } @Test public void testSetClientAddr() { mParcel.setSingleClientAddr(TEST_CLIENT_ADDRESS); assertEquals(TEST_CLIENT_ADDRESS_PARCELED, mParcel.clientAddr); } private static Inet4Address inet4Addr(String addr) { return (Inet4Address) parseNumericAddress(addr); } Loading
packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +14 −6 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS; import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; Loading Loading @@ -1668,10 +1669,13 @@ public class TetheringTest { } @Test public void testRequestStaticServerIp() throws Exception { final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24"); final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24"); final String serverAddr = "192.168.20.1"; public void testRequestStaticIp() throws Exception { final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24"); final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24"); final String serverAddr = "192.168.0.123"; final int clientAddrParceled = 0xc0a8002a; final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor = ArgumentCaptor.forClass(DhcpServingParamsParcel.class); mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB, serverLinkAddr, clientLinkAddr), null); mLooper.dispatchAll(); Loading @@ -1680,8 +1684,12 @@ public class TetheringTest { sendUsbBroadcast(true, true, true, TETHERING_USB); mLooper.dispatchAll(); verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr))); // TODO: test static client address. verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(), any()); final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue(); assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress()); assertEquals(24, params.serverAddrPrefixLength); assertEquals(clientAddrParceled, params.clientAddr); } // TODO: Test that a request for hotspot mode doesn't interfere with an Loading