Loading services/core/java/com/android/server/vcn/VcnGatewayConnection.java +21 −1 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ import java.io.IOException; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.util.Arrays; import java.util.Collections; import java.util.List; Loading Loading @@ -2061,7 +2062,8 @@ public class VcnGatewayConnection extends StateMachine { return builder.build(); } private static LinkProperties buildConnectedLinkProperties( @VisibleForTesting(visibility = Visibility.PRIVATE) LinkProperties buildConnectedLinkProperties( @NonNull VcnGatewayConnectionConfig gatewayConnectionConfig, @NonNull IpSecTunnelInterface tunnelIface, @NonNull VcnChildSessionConfiguration childConfig, Loading Loading @@ -2089,6 +2091,13 @@ public class VcnGatewayConnection extends StateMachine { lp.setTcpBufferSizes(underlyingLp.getTcpBufferSizes()); underlyingMtu = underlyingLp.getMtu(); // WiFi LinkProperties uses DHCP as the sole source of MTU information, and as a result // often lists MTU as 0 (see b/184678973). Use the interface MTU as retrieved by // NetworkInterface APIs. if (underlyingMtu == 0 && underlyingLp.getInterfaceName() != null) { underlyingMtu = mDeps.getUnderlyingIfaceMtu(underlyingLp.getInterfaceName()); } } else { Slog.wtf( TAG, Loading Loading @@ -2436,6 +2445,17 @@ public class VcnGatewayConnection extends StateMachine { public long getElapsedRealTime() { return SystemClock.elapsedRealtime(); } /** Gets the MTU for the given underlying interface. */ public int getUnderlyingIfaceMtu(String ifaceName) { try { final NetworkInterface underlyingIface = NetworkInterface.getByName(ifaceName); return underlyingIface == null ? 0 : underlyingIface.getMTU(); } catch (IOException e) { Slog.d(TAG, "Could not get MTU of underlying network", e); return 0; } } } /** Loading tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java +70 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.vcn; import static android.net.IpSecManager.IpSecTunnelInterface; import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; Loading @@ -24,6 +25,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static com.android.server.vcn.VcnGatewayConnection.DUMMY_ADDR; import static com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration; import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; Loading @@ -36,8 +39,11 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.CALLS_REAL_METHODS; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.net.IpSecManager; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; Loading @@ -59,8 +65,11 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.net.InetAddress; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; Loading @@ -70,6 +79,8 @@ import java.util.UUID; public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase { private static final int TEST_UID = Process.myUid() + 1; private static final String LOOPBACK_IFACE = "lo"; private static final ParcelUuid TEST_PARCEL_UUID = new ParcelUuid(UUID.randomUUID()); private static final int TEST_SIM_SLOT_INDEX = 1; private static final int TEST_SUBSCRIPTION_ID_1 = 2; Loading @@ -77,6 +88,12 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase { private static final int TEST_SUBSCRIPTION_ID_2 = 3; private static final SubscriptionInfo TEST_SUBINFO_2 = mock(SubscriptionInfo.class); private static final Map<Integer, ParcelUuid> TEST_SUBID_TO_GROUP_MAP; private static final String TEST_TCP_BUFFER_SIZES = "1,2,3,4,5,6"; private static final int TEST_MTU = 1300; private static final int TEST_MTU_DELTA = 64; private static final List<LinkAddress> TEST_INTERNAL_ADDRESSES = Arrays.asList(new LinkAddress(DUMMY_ADDR, 16)); private static final List<InetAddress> TEST_DNS_ADDRESSES = Arrays.asList(DUMMY_ADDR); private static final int TEST_UPSTREAM_BANDWIDTH = 1234; private static final int TEST_DOWNSTREAM_BANDWIDTH = 2345; Loading Loading @@ -165,6 +182,59 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase { verifyBuildNetworkCapabilitiesCommon(TRANSPORT_CELLULAR, false /* isMobileDataEnabled */); } @Test public void testBuildLinkProperties() throws Exception { final IpSecTunnelInterface tunnelIface = mContext.getSystemService(IpSecManager.class) .createIpSecTunnelInterface( DUMMY_ADDR, DUMMY_ADDR, TEST_UNDERLYING_NETWORK_RECORD_1.network); final LinkProperties underlyingLp = new LinkProperties(); underlyingLp.setInterfaceName(LOOPBACK_IFACE); underlyingLp.setTcpBufferSizes(TEST_TCP_BUFFER_SIZES); doReturn(TEST_MTU).when(mDeps).getUnderlyingIfaceMtu(LOOPBACK_IFACE); final VcnChildSessionConfiguration childSessionConfig = mock(VcnChildSessionConfiguration.class); doReturn(TEST_INTERNAL_ADDRESSES).when(childSessionConfig).getInternalAddresses(); doReturn(TEST_DNS_ADDRESSES).when(childSessionConfig).getInternalDnsServers(); UnderlyingNetworkRecord record = new UnderlyingNetworkRecord( mock(Network.class, CALLS_REAL_METHODS), new NetworkCapabilities.Builder().build(), underlyingLp, false); final LinkProperties vcnLp1 = mGatewayConnection.buildConnectedLinkProperties( VcnGatewayConnectionConfigTest.buildTestConfig(), tunnelIface, childSessionConfig, record); verify(mDeps).getUnderlyingIfaceMtu(LOOPBACK_IFACE); // Instead of having to recalculate the final MTU (after accounting for IPsec overhead), // calculate another set of Link Properties with a lower MTU, and calculate the delta. doReturn(TEST_MTU - TEST_MTU_DELTA).when(mDeps).getUnderlyingIfaceMtu(LOOPBACK_IFACE); final LinkProperties vcnLp2 = mGatewayConnection.buildConnectedLinkProperties( VcnGatewayConnectionConfigTest.buildTestConfig(), tunnelIface, childSessionConfig, record); verify(mDeps, times(2)).getUnderlyingIfaceMtu(LOOPBACK_IFACE); assertEquals(tunnelIface.getInterfaceName(), vcnLp1.getInterfaceName()); assertEquals(TEST_INTERNAL_ADDRESSES, vcnLp1.getLinkAddresses()); assertEquals(TEST_DNS_ADDRESSES, vcnLp1.getDnsServers()); assertEquals(TEST_TCP_BUFFER_SIZES, vcnLp1.getTcpBufferSizes()); assertEquals(TEST_MTU_DELTA, vcnLp1.getMtu() - vcnLp2.getMtu()); } @Test public void testSubscriptionSnapshotUpdateNotifiesUnderlyingNetworkTracker() { verifyWakeLockSetUp(); Loading Loading
services/core/java/com/android/server/vcn/VcnGatewayConnection.java +21 −1 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ import java.io.IOException; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.util.Arrays; import java.util.Collections; import java.util.List; Loading Loading @@ -2061,7 +2062,8 @@ public class VcnGatewayConnection extends StateMachine { return builder.build(); } private static LinkProperties buildConnectedLinkProperties( @VisibleForTesting(visibility = Visibility.PRIVATE) LinkProperties buildConnectedLinkProperties( @NonNull VcnGatewayConnectionConfig gatewayConnectionConfig, @NonNull IpSecTunnelInterface tunnelIface, @NonNull VcnChildSessionConfiguration childConfig, Loading Loading @@ -2089,6 +2091,13 @@ public class VcnGatewayConnection extends StateMachine { lp.setTcpBufferSizes(underlyingLp.getTcpBufferSizes()); underlyingMtu = underlyingLp.getMtu(); // WiFi LinkProperties uses DHCP as the sole source of MTU information, and as a result // often lists MTU as 0 (see b/184678973). Use the interface MTU as retrieved by // NetworkInterface APIs. if (underlyingMtu == 0 && underlyingLp.getInterfaceName() != null) { underlyingMtu = mDeps.getUnderlyingIfaceMtu(underlyingLp.getInterfaceName()); } } else { Slog.wtf( TAG, Loading Loading @@ -2436,6 +2445,17 @@ public class VcnGatewayConnection extends StateMachine { public long getElapsedRealTime() { return SystemClock.elapsedRealtime(); } /** Gets the MTU for the given underlying interface. */ public int getUnderlyingIfaceMtu(String ifaceName) { try { final NetworkInterface underlyingIface = NetworkInterface.getByName(ifaceName); return underlyingIface == null ? 0 : underlyingIface.getMTU(); } catch (IOException e) { Slog.d(TAG, "Could not get MTU of underlying network", e); return 0; } } } /** Loading
tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java +70 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.vcn; import static android.net.IpSecManager.IpSecTunnelInterface; import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; Loading @@ -24,6 +25,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static com.android.server.vcn.VcnGatewayConnection.DUMMY_ADDR; import static com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration; import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; Loading @@ -36,8 +39,11 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.CALLS_REAL_METHODS; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.net.IpSecManager; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; Loading @@ -59,8 +65,11 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.net.InetAddress; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; Loading @@ -70,6 +79,8 @@ import java.util.UUID; public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase { private static final int TEST_UID = Process.myUid() + 1; private static final String LOOPBACK_IFACE = "lo"; private static final ParcelUuid TEST_PARCEL_UUID = new ParcelUuid(UUID.randomUUID()); private static final int TEST_SIM_SLOT_INDEX = 1; private static final int TEST_SUBSCRIPTION_ID_1 = 2; Loading @@ -77,6 +88,12 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase { private static final int TEST_SUBSCRIPTION_ID_2 = 3; private static final SubscriptionInfo TEST_SUBINFO_2 = mock(SubscriptionInfo.class); private static final Map<Integer, ParcelUuid> TEST_SUBID_TO_GROUP_MAP; private static final String TEST_TCP_BUFFER_SIZES = "1,2,3,4,5,6"; private static final int TEST_MTU = 1300; private static final int TEST_MTU_DELTA = 64; private static final List<LinkAddress> TEST_INTERNAL_ADDRESSES = Arrays.asList(new LinkAddress(DUMMY_ADDR, 16)); private static final List<InetAddress> TEST_DNS_ADDRESSES = Arrays.asList(DUMMY_ADDR); private static final int TEST_UPSTREAM_BANDWIDTH = 1234; private static final int TEST_DOWNSTREAM_BANDWIDTH = 2345; Loading Loading @@ -165,6 +182,59 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase { verifyBuildNetworkCapabilitiesCommon(TRANSPORT_CELLULAR, false /* isMobileDataEnabled */); } @Test public void testBuildLinkProperties() throws Exception { final IpSecTunnelInterface tunnelIface = mContext.getSystemService(IpSecManager.class) .createIpSecTunnelInterface( DUMMY_ADDR, DUMMY_ADDR, TEST_UNDERLYING_NETWORK_RECORD_1.network); final LinkProperties underlyingLp = new LinkProperties(); underlyingLp.setInterfaceName(LOOPBACK_IFACE); underlyingLp.setTcpBufferSizes(TEST_TCP_BUFFER_SIZES); doReturn(TEST_MTU).when(mDeps).getUnderlyingIfaceMtu(LOOPBACK_IFACE); final VcnChildSessionConfiguration childSessionConfig = mock(VcnChildSessionConfiguration.class); doReturn(TEST_INTERNAL_ADDRESSES).when(childSessionConfig).getInternalAddresses(); doReturn(TEST_DNS_ADDRESSES).when(childSessionConfig).getInternalDnsServers(); UnderlyingNetworkRecord record = new UnderlyingNetworkRecord( mock(Network.class, CALLS_REAL_METHODS), new NetworkCapabilities.Builder().build(), underlyingLp, false); final LinkProperties vcnLp1 = mGatewayConnection.buildConnectedLinkProperties( VcnGatewayConnectionConfigTest.buildTestConfig(), tunnelIface, childSessionConfig, record); verify(mDeps).getUnderlyingIfaceMtu(LOOPBACK_IFACE); // Instead of having to recalculate the final MTU (after accounting for IPsec overhead), // calculate another set of Link Properties with a lower MTU, and calculate the delta. doReturn(TEST_MTU - TEST_MTU_DELTA).when(mDeps).getUnderlyingIfaceMtu(LOOPBACK_IFACE); final LinkProperties vcnLp2 = mGatewayConnection.buildConnectedLinkProperties( VcnGatewayConnectionConfigTest.buildTestConfig(), tunnelIface, childSessionConfig, record); verify(mDeps, times(2)).getUnderlyingIfaceMtu(LOOPBACK_IFACE); assertEquals(tunnelIface.getInterfaceName(), vcnLp1.getInterfaceName()); assertEquals(TEST_INTERNAL_ADDRESSES, vcnLp1.getLinkAddresses()); assertEquals(TEST_DNS_ADDRESSES, vcnLp1.getDnsServers()); assertEquals(TEST_TCP_BUFFER_SIZES, vcnLp1.getTcpBufferSizes()); assertEquals(TEST_MTU_DELTA, vcnLp1.getMtu() - vcnLp2.getMtu()); } @Test public void testSubscriptionSnapshotUpdateNotifiesUnderlyingNetworkTracker() { verifyWakeLockSetUp(); Loading