Merge "Add version control for packet address translation design" into main

This commit is contained in:
Chiachang Wang
2023-08-03 06:58:28 +00:00
committed by Gerrit Code Review
3 changed files with 65 additions and 6 deletions

View File

@@ -34,6 +34,8 @@ import static android.net.SocketKeepalive.NO_KEEPALIVE;
import static android.net.SocketKeepalive.SUCCESS; import static android.net.SocketKeepalive.SUCCESS;
import static android.net.SocketKeepalive.SUCCESS_PAUSED; import static android.net.SocketKeepalive.SUCCESS_PAUSED;
import static com.android.net.module.util.FeatureVersions.FEATURE_CLAT_ADDRESS_TRANSLATE;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.Context; import android.content.Context;
@@ -59,6 +61,7 @@ import android.util.Pair;
import com.android.connectivity.resources.R; import com.android.connectivity.resources.R;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter;
import com.android.net.module.util.DeviceConfigUtils;
import com.android.net.module.util.HexDump; import com.android.net.module.util.HexDump;
import com.android.net.module.util.IpUtils; import com.android.net.module.util.IpUtils;
@@ -86,6 +89,9 @@ public class KeepaliveTracker {
public static final String PERMISSION = android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD; public static final String PERMISSION = android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD;
private static final String CONFIG_DISABLE_CLAT_ADDRESS_TRANSLATE =
"disable_clat_address_translate";
/** Keeps track of keepalive requests. */ /** Keeps track of keepalive requests. */
private final HashMap <NetworkAgentInfo, HashMap<Integer, KeepaliveInfo>> mKeepalives = private final HashMap <NetworkAgentInfo, HashMap<Integer, KeepaliveInfo>> mKeepalives =
new HashMap<> (); new HashMap<> ();
@@ -113,7 +119,7 @@ public class KeepaliveTracker {
} }
@VisibleForTesting @VisibleForTesting
KeepaliveTracker(Context context, Handler handler, TcpKeepaliveController tcpController, public KeepaliveTracker(Context context, Handler handler, TcpKeepaliveController tcpController,
Dependencies deps) { Dependencies deps) {
mTcpController = tcpController; mTcpController = tcpController;
mContext = context; mContext = context;
@@ -553,6 +559,8 @@ public class KeepaliveTracker {
private KeepaliveInfo handleUpdateKeepaliveForClat(KeepaliveInfo ki) private KeepaliveInfo handleUpdateKeepaliveForClat(KeepaliveInfo ki)
throws InvalidSocketException, InvalidPacketException { throws InvalidSocketException, InvalidPacketException {
if (!mDependencies.isAddressTranslationEnabled(mContext)) return ki;
// Translation applies to only NAT-T keepalive // Translation applies to only NAT-T keepalive
if (ki.mType != KeepaliveInfo.TYPE_NATT) return ki; if (ki.mType != KeepaliveInfo.TYPE_NATT) return ki;
// Only try to translate address if the packet source address is the clat's source address. // Only try to translate address if the packet source address is the clat's source address.
@@ -973,5 +981,20 @@ public class KeepaliveTracker {
public ConnectivityResources createConnectivityResources(@NonNull Context context) { public ConnectivityResources createConnectivityResources(@NonNull Context context) {
return new ConnectivityResources(context); return new ConnectivityResources(context);
} }
/**
* Return if keepalive address translation with clat feature is supported or not.
*
* This is controlled by both isFeatureSupported() and isFeatureEnabled(). The
* isFeatureSupported() checks whether device contains the minimal required module
* version for FEATURE_CLAT_ADDRESS_TRANSLATE. The isTetheringFeatureForceDisabled()
* checks the DeviceConfig flag that can be updated via DeviceConfig push to control
* the overall feature.
*/
public boolean isAddressTranslationEnabled(@NonNull Context context) {
return DeviceConfigUtils.isFeatureSupported(context, FEATURE_CLAT_ADDRESS_TRANSLATE)
&& !DeviceConfigUtils.isTetheringFeatureForceDisabled(
CONFIG_DISABLE_CLAT_ADDRESS_TRANSLATE);
}
} }
} }

View File

@@ -402,6 +402,7 @@ import com.android.server.connectivity.CarrierPrivilegeAuthenticator;
import com.android.server.connectivity.ClatCoordinator; import com.android.server.connectivity.ClatCoordinator;
import com.android.server.connectivity.ConnectivityFlags; import com.android.server.connectivity.ConnectivityFlags;
import com.android.server.connectivity.ConnectivityResources; import com.android.server.connectivity.ConnectivityResources;
import com.android.server.connectivity.KeepaliveTracker;
import com.android.server.connectivity.MultinetworkPolicyTracker; import com.android.server.connectivity.MultinetworkPolicyTracker;
import com.android.server.connectivity.MultinetworkPolicyTrackerTestDependencies; import com.android.server.connectivity.MultinetworkPolicyTrackerTestDependencies;
import com.android.server.connectivity.Nat464Xlat; import com.android.server.connectivity.Nat464Xlat;
@@ -410,6 +411,7 @@ import com.android.server.connectivity.NetworkNotificationManager;
import com.android.server.connectivity.NetworkNotificationManager.NotificationType; import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
import com.android.server.connectivity.ProxyTracker; import com.android.server.connectivity.ProxyTracker;
import com.android.server.connectivity.QosCallbackTracker; import com.android.server.connectivity.QosCallbackTracker;
import com.android.server.connectivity.TcpKeepaliveController;
import com.android.server.connectivity.UidRangeUtils; import com.android.server.connectivity.UidRangeUtils;
import com.android.server.connectivity.Vpn; import com.android.server.connectivity.Vpn;
import com.android.server.connectivity.VpnProfileStore; import com.android.server.connectivity.VpnProfileStore;
@@ -627,6 +629,7 @@ public class ConnectivityServiceTest {
@Mock ActivityManager mActivityManager; @Mock ActivityManager mActivityManager;
@Mock DestroySocketsWrapper mDestroySocketsWrapper; @Mock DestroySocketsWrapper mDestroySocketsWrapper;
@Mock SubscriptionManager mSubscriptionManager; @Mock SubscriptionManager mSubscriptionManager;
@Mock KeepaliveTracker.Dependencies mMockKeepaliveTrackerDependencies;
// BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the // BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the
// underlying binder calls. // underlying binder calls.
@@ -1898,6 +1901,12 @@ public class ConnectivityServiceTest {
doReturn(mResources).when(mockResContext).getResources(); doReturn(mResources).when(mockResContext).getResources();
ConnectivityResources.setResourcesContextForTest(mockResContext); ConnectivityResources.setResourcesContextForTest(mockResContext);
mDeps = new ConnectivityServiceDependencies(mockResContext); mDeps = new ConnectivityServiceDependencies(mockResContext);
doReturn(true).when(mMockKeepaliveTrackerDependencies)
.isAddressTranslationEnabled(mServiceContext);
doReturn(new ConnectivityResources(mockResContext)).when(mMockKeepaliveTrackerDependencies)
.createConnectivityResources(mServiceContext);
doReturn(new int[] {1, 3, 0, 0}).when(mMockKeepaliveTrackerDependencies)
.getSupportedKeepalives(mServiceContext);
mAutoOnOffKeepaliveDependencies = mAutoOnOffKeepaliveDependencies =
new AutomaticOnOffKeepaliveTrackerDependencies(mServiceContext); new AutomaticOnOffKeepaliveTrackerDependencies(mServiceContext);
mService = new ConnectivityService(mServiceContext, mService = new ConnectivityService(mServiceContext,
@@ -2297,6 +2306,12 @@ public class ConnectivityServiceTest {
// Assuming enabled here to focus on ConnectivityService tests. // Assuming enabled here to focus on ConnectivityService tests.
return true; return true;
} }
public KeepaliveTracker newKeepaliveTracker(@NonNull Context context,
@NonNull Handler connectivityserviceHander) {
return new KeepaliveTracker(context, connectivityserviceHander,
new TcpKeepaliveController(connectivityserviceHander),
mMockKeepaliveTrackerDependencies);
}
} }
private static void initAlarmManager(final AlarmManager am, final Handler alarmHandler) { private static void initAlarmManager(final AlarmManager am, final Handler alarmHandler) {

View File

@@ -78,7 +78,6 @@ import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.android.connectivity.resources.R;
import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker.AutomaticOnOffKeepalive; import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker.AutomaticOnOffKeepalive;
import com.android.server.connectivity.KeepaliveTracker.KeepaliveInfo; import com.android.server.connectivity.KeepaliveTracker.KeepaliveInfo;
import com.android.testutils.DevSdkIgnoreRule; import com.android.testutils.DevSdkIgnoreRule;
@@ -96,6 +95,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.net.Inet4Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@@ -128,7 +128,7 @@ public class AutomaticOnOffKeepaliveTrackerTest {
@Mock AlarmManager mAlarmManager; @Mock AlarmManager mAlarmManager;
@Mock NetworkAgentInfo mNai; @Mock NetworkAgentInfo mNai;
@Mock SubscriptionManager mSubscriptionManager; @Mock SubscriptionManager mSubscriptionManager;
@Mock KeepaliveTracker.Dependencies mKeepaliveTrackerDeps;
KeepaliveStatsTracker mKeepaliveStatsTracker; KeepaliveStatsTracker mKeepaliveStatsTracker;
TestKeepaliveTracker mKeepaliveTracker; TestKeepaliveTracker mKeepaliveTracker;
AOOTestHandler mTestHandler; AOOTestHandler mTestHandler;
@@ -267,7 +267,7 @@ public class AutomaticOnOffKeepaliveTrackerTest {
TestKeepaliveTracker(@NonNull final Context context, @NonNull final Handler handler, TestKeepaliveTracker(@NonNull final Context context, @NonNull final Handler handler,
@NonNull final TcpKeepaliveController tcpController) { @NonNull final TcpKeepaliveController tcpController) {
super(context, handler, tcpController, new Dependencies()); super(context, handler, tcpController, mKeepaliveTrackerDeps);
} }
public void setReturnedKeepaliveInfo(@NonNull final KeepaliveInfo ki) { public void setReturnedKeepaliveInfo(@NonNull final KeepaliveInfo ki) {
@@ -336,8 +336,6 @@ public class AutomaticOnOffKeepaliveTrackerTest {
anyInt() /* pid */, anyInt() /* uid */); anyInt() /* pid */, anyInt() /* uid */);
ConnectivityResources.setResourcesContextForTest(mCtx); ConnectivityResources.setResourcesContextForTest(mCtx);
final Resources mockResources = mock(Resources.class); final Resources mockResources = mock(Resources.class);
doReturn(new String[] { "0,3", "3,3" }).when(mockResources)
.getStringArray(R.array.config_networkSupportedKeepaliveCount);
doReturn(mockResources).when(mCtx).getResources(); doReturn(mockResources).when(mCtx).getResources();
doReturn(mNetd).when(mDependencies).getNetd(); doReturn(mNetd).when(mDependencies).getNetd();
doReturn(mAlarmManager).when(mDependencies).getAlarmManager(any()); doReturn(mAlarmManager).when(mDependencies).getAlarmManager(any());
@@ -345,6 +343,10 @@ public class AutomaticOnOffKeepaliveTrackerTest {
.getFwmarkForNetwork(TEST_NETID); .getFwmarkForNetwork(TEST_NETID);
doNothing().when(mDependencies).sendRequest(any(), any()); doNothing().when(mDependencies).sendRequest(any(), any());
doReturn(true).when(mKeepaliveTrackerDeps).isAddressTranslationEnabled(mCtx);
doReturn(new ConnectivityResources(mCtx)).when(mKeepaliveTrackerDeps)
.createConnectivityResources(mCtx);
doReturn(new int[] {3, 0, 0, 3}).when(mKeepaliveTrackerDeps).getSupportedKeepalives(mCtx);
mHandlerThread = new HandlerThread("KeepaliveTrackerTest"); mHandlerThread = new HandlerThread("KeepaliveTrackerTest");
mHandlerThread.start(); mHandlerThread.start();
@@ -658,6 +660,25 @@ public class AutomaticOnOffKeepaliveTrackerTest {
assertEquals(srcAddr, tpd.getSrcAddress()); assertEquals(srcAddr, tpd.getSrcAddress());
} }
@Test
public void testStartNattKeepalive_addressTranslationOnClatNotSupported() throws Exception {
// Disable address translation feature and verify the behavior
doReturn(false).when(mKeepaliveTrackerDeps).isAddressTranslationEnabled(mCtx);
setupTestNaiForClat(InetAddresses.parseNumericAddress("2001:db8::1"),
InetAddresses.parseNumericAddress("2001:db8::2"));
doStartNattKeepalive();
final ArgumentCaptor<NattKeepalivePacketData> kpdCaptor =
ArgumentCaptor.forClass(NattKeepalivePacketData.class);
verify(mNai).onStartNattSocketKeepalive(
eq(TEST_SLOT), eq(TEST_KEEPALIVE_INTERVAL_SEC), kpdCaptor.capture());
// Verify that address translation is not triggered so the addresses are still v4.
final NattKeepalivePacketData kpd = kpdCaptor.getValue();
assertTrue(kpd.getSrcAddress() instanceof Inet4Address);
assertTrue(kpd.getDstAddress() instanceof Inet4Address);
}
@Test @Test
public void testStartNattKeepalive_addressTranslationOnClat() throws Exception { public void testStartNattKeepalive_addressTranslationOnClat() throws Exception {
final InetAddress v6AddrSrc = InetAddresses.parseNumericAddress("2001:db8::1"); final InetAddress v6AddrSrc = InetAddresses.parseNumericAddress("2001:db8::1");