Add/remove internal addresses from IpSecTunnelInterface

This change corrects a bug where IpSecTunnelInterface was not removing
old addresses, and resulted in EEXIST when trying to re-add an address
to a given interface.

Test: atest FrameworksVcnTests
Change-Id: I43434c801354483a7c7d0092891799bf86da23eb
This commit is contained in:
Benedict Wong
2021-04-01 18:23:45 -07:00
parent 7d6b4907cc
commit f78c3512df
3 changed files with 76 additions and 15 deletions

View File

@@ -1518,13 +1518,6 @@ public class VcnGatewayConnection extends StateMachine {
}
}
protected void setupInterface(
int token,
@NonNull IpSecTunnelInterface tunnelIface,
@NonNull VcnChildSessionConfiguration childConfig) {
setupInterface(token, tunnelIface, childConfig, null);
}
protected void setupInterface(
int token,
@NonNull IpSecTunnelInterface tunnelIface,
@@ -1609,9 +1602,11 @@ public class VcnGatewayConnection extends StateMachine {
transformCreatedInfo.direction);
break;
case EVENT_SETUP_COMPLETED:
final VcnChildSessionConfiguration oldChildConfig = mChildConfig;
mChildConfig = ((EventSetupCompletedInfo) msg.obj).childSessionConfig;
setupInterfaceAndNetworkAgent(mCurrentToken, mTunnelIface, mChildConfig);
setupInterfaceAndNetworkAgent(
mCurrentToken, mTunnelIface, mChildConfig, oldChildConfig);
break;
case EVENT_DISCONNECT_REQUESTED:
handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
@@ -1655,8 +1650,9 @@ public class VcnGatewayConnection extends StateMachine {
protected void setupInterfaceAndNetworkAgent(
int token,
@NonNull IpSecTunnelInterface tunnelIface,
@NonNull VcnChildSessionConfiguration childConfig) {
setupInterface(token, tunnelIface, childConfig);
@NonNull VcnChildSessionConfiguration childConfig,
@NonNull VcnChildSessionConfiguration oldChildConfig) {
setupInterface(token, tunnelIface, childConfig, oldChildConfig);
if (mNetworkAgent == null) {
mNetworkAgent = buildNetworkAgent(tunnelIface, childConfig);

View File

@@ -42,6 +42,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
@@ -60,8 +61,11 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
/** Tests for VcnGatewayConnection.ConnectedState */
@@ -169,12 +173,14 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
}
private void triggerChildOpened() {
triggerChildOpened(Collections.singletonList(TEST_INTERNAL_ADDR), TEST_DNS_ADDR);
}
private void triggerChildOpened(List<LinkAddress> internalAddresses, InetAddress dnsAddress) {
final VcnChildSessionConfiguration mMockChildSessionConfig =
mock(VcnChildSessionConfiguration.class);
doReturn(Collections.singletonList(TEST_INTERNAL_ADDR))
.when(mMockChildSessionConfig)
.getInternalAddresses();
doReturn(Collections.singletonList(TEST_DNS_ADDR))
doReturn(internalAddresses).when(mMockChildSessionConfig).getInternalAddresses();
doReturn(Collections.singletonList(dnsAddress))
.when(mMockChildSessionConfig)
.getInternalDnsServers();
@@ -248,6 +254,59 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
assertFalse(mGatewayConnection.isInSafeMode());
}
@Test
public void testInternalAndDnsAddressesChanged() throws Exception {
final List<LinkAddress> startingInternalAddrs =
Arrays.asList(new LinkAddress[] {TEST_INTERNAL_ADDR, TEST_INTERNAL_ADDR_2});
triggerChildOpened(startingInternalAddrs, TEST_DNS_ADDR);
mTestLooper.dispatchAll();
for (LinkAddress addr : startingInternalAddrs) {
verify(mIpSecSvc)
.addAddressToTunnelInterface(
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(addr), any());
}
verify(mDeps)
.newNetworkAgent(
any(),
any(),
any(),
argThat(
lp ->
startingInternalAddrs.equals(lp.getLinkAddresses())
&& Collections.singletonList(TEST_DNS_ADDR)
.equals(lp.getDnsServers())),
anyInt(),
any(),
any(),
any(),
any());
// Trigger another connection event, and verify that the addresses change
final List<LinkAddress> newInternalAddrs =
Arrays.asList(new LinkAddress[] {TEST_INTERNAL_ADDR_2, TEST_INTERNAL_ADDR_3});
triggerChildOpened(newInternalAddrs, TEST_DNS_ADDR_2);
mTestLooper.dispatchAll();
// Verify addresses on tunnel network added/removed
for (LinkAddress addr : newInternalAddrs) {
verify(mIpSecSvc)
.addAddressToTunnelInterface(
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(addr), any());
}
verify(mIpSecSvc)
.removeAddressFromTunnelInterface(
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(TEST_INTERNAL_ADDR), any());
// TODO(b/184579891): Also verify link properties updated and sent when sendLinkProperties
// is mockable
// Verify that IpSecTunnelInterface only created once
verify(mIpSecSvc).createTunnelInterface(any(), any(), any(), any(), any());
verifyNoMoreInteractions(mIpSecSvc);
}
@Test
public void testSuccessfulConnectionExitsSafeMode() throws Exception {
verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent(

View File

@@ -74,8 +74,14 @@ public class VcnGatewayConnectionTestBase {
protected static final ParcelUuid TEST_SUB_GRP = new ParcelUuid(UUID.randomUUID());
protected static final InetAddress TEST_DNS_ADDR =
InetAddresses.parseNumericAddress("2001:DB8:0:1::");
protected static final InetAddress TEST_DNS_ADDR_2 =
InetAddresses.parseNumericAddress("2001:DB8:0:2::");
protected static final LinkAddress TEST_INTERNAL_ADDR =
new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:0:2::"), 64);
new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:1::"), 64);
protected static final LinkAddress TEST_INTERNAL_ADDR_2 =
new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:2::"), 64);
protected static final LinkAddress TEST_INTERNAL_ADDR_3 =
new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:3::"), 64);
protected static final int TEST_IPSEC_SPI_VALUE = 0x1234;
protected static final int TEST_IPSEC_SPI_RESOURCE_ID = 1;