diff options
| -rw-r--r-- | api/system-current.txt | 2 | ||||
| -rw-r--r-- | core/java/android/net/IpSecManager.java | 6 | ||||
| -rw-r--r-- | services/core/java/com/android/server/IpSecService.java | 10 | ||||
| -rw-r--r-- | tests/net/java/com/android/server/IpSecServiceParameterizedTest.java | 42 |
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); |