summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/system-current.txt2
-rw-r--r--core/java/android/net/IpSecManager.java6
-rw-r--r--services/core/java/com/android/server/IpSecService.java10
-rw-r--r--tests/net/java/com/android/server/IpSecServiceParameterizedTest.java42
4 files changed, 53 insertions, 7 deletions
diff --git a/api/system-current.txt b/api/system-current.txt
index 1e2fe3df0d2c..6d43d27355d6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3067,8 +3067,10 @@ package android.net {
}
public static final class IpSecManager.IpSecTunnelInterface implements java.lang.AutoCloseable {
+ method public void addAddress(android.net.LinkAddress) throws java.io.IOException;
method public void close();
method public java.lang.String getInterfaceName();
+ method public void removeAddress(android.net.LinkAddress) throws java.io.IOException;
}
public final class IpSecTransform implements java.lang.AutoCloseable {
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 4e1f83430abf..cb4299ef6987 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -658,7 +658,8 @@ public final class IpSecManager {
* @param address the local address for traffic inside the tunnel
* @hide
*/
- public void addAddress(LinkAddress address) {
+ @SystemApi
+ public void addAddress(LinkAddress address) throws IOException {
try {
mService.addAddressToTunnelInterface(mResourceId, address);
} catch (RemoteException e) {
@@ -674,7 +675,8 @@ public final class IpSecManager {
* @param address to be removed
* @hide
*/
- public void removeAddress(LinkAddress address) {
+ @SystemApi
+ public void removeAddress(LinkAddress address) throws IOException {
try {
mService.removeAddressFromTunnelInterface(mResourceId, address);
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index f1f251f42524..d09a161d1ef4 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -676,10 +676,12 @@ public class IpSecService extends IIpSecService.Stub {
@Override
public void freeUnderlyingResources() {
try {
- mSrvConfig
- .getNetdInstance()
- .ipSecDeleteSecurityAssociation(
- mResourceId, mSourceAddress, mDestinationAddress, mSpi, 0, 0);
+ if (!mOwnedByTransform) {
+ mSrvConfig
+ .getNetdInstance()
+ .ipSecDeleteSecurityAssociation(
+ mResourceId, mSourceAddress, mDestinationAddress, mSpi, 0, 0);
+ }
} catch (ServiceSpecificException | RemoteException e) {
Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId, e);
}
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index a5c55e8d844e..410f754fb5ed 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -320,6 +321,30 @@ public class IpSecServiceParameterizedTest {
}
@Test
+ public void testReleaseOwnedSpi() throws Exception {
+ IpSecConfig ipSecConfig = new IpSecConfig();
+ addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+ addAuthAndCryptToIpSecConfig(ipSecConfig);
+
+ IpSecTransformResponse createTransformResp =
+ mIpSecService.createTransform(ipSecConfig, new Binder());
+ IpSecService.UserRecord userRecord =
+ mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+ assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
+ mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
+ verify(mMockNetd, times(0))
+ .ipSecDeleteSecurityAssociation(
+ eq(createTransformResp.resourceId),
+ anyString(),
+ anyString(),
+ eq(TEST_SPI),
+ anyInt(),
+ anyInt());
+ // quota is not released until the SPI is released by the Transform
+ assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
+ }
+
+ @Test
public void testDeleteTransform() throws Exception {
IpSecConfig ipSecConfig = new IpSecConfig();
addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
@@ -329,7 +354,7 @@ public class IpSecServiceParameterizedTest {
mIpSecService.createTransform(ipSecConfig, new Binder());
mIpSecService.deleteTransform(createTransformResp.resourceId);
- verify(mMockNetd)
+ verify(mMockNetd, times(1))
.ipSecDeleteSecurityAssociation(
eq(createTransformResp.resourceId),
anyString(),
@@ -342,6 +367,21 @@ public class IpSecServiceParameterizedTest {
IpSecService.UserRecord userRecord =
mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent);
+ assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
+
+ mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
+ // Verify that ipSecDeleteSa was not called when the SPI was released because the
+ // ownedByTransform property should prevent it; (note, the called count is cumulative).
+ verify(mMockNetd, times(1))
+ .ipSecDeleteSecurityAssociation(
+ anyInt(),
+ anyString(),
+ anyString(),
+ anyInt(),
+ anyInt(),
+ anyInt());
+ assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
+
try {
userRecord.mTransformRecords.getRefcountedResourceOrThrow(
createTransformResp.resourceId);