Merge "Add version control for packet address translation design" into main
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user