aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDheeraj Shetty <shettydheeraj@google.com>2020-04-20 13:27:29 -0700
committerDheeraj Shetty <shettydheeraj@google.com>2020-04-24 08:50:53 -0700
commitfe1329b1637308e570acc9656388425334722460 (patch)
tree9ce2f3b5d08bac17489ba92339576a0b44911bff
parent6d2920b94b1dabf1a988bb2b520db0aff2248a23 (diff)
downloadike-fe1329b1637308e570acc9656388425334722460.tar.gz
Use user configured retransmission timeouts
Test: atest FrameworksIkeTests(New tests added) Bug: 151947025 Change-Id: I19aabba8c250e68d4c504dd158f43259b0408579
-rw-r--r--src/java/android/net/ipsec/ike/IkeSessionParams.java24
-rw-r--r--src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java4
-rw-r--r--src/java/com/android/internal/net/ipsec/ike/utils/Retransmitter.java61
-rw-r--r--tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java20
-rw-r--r--tests/iketests/src/java/com/android/internal/net/ipsec/ike/utils/RetransmitterTest.java26
5 files changed, 37 insertions, 98 deletions
diff --git a/src/java/android/net/ipsec/ike/IkeSessionParams.java b/src/java/android/net/ipsec/ike/IkeSessionParams.java
index 80f6639f..9880ff42 100644
--- a/src/java/android/net/ipsec/ike/IkeSessionParams.java
+++ b/src/java/android/net/ipsec/ike/IkeSessionParams.java
@@ -93,7 +93,6 @@ public final class IkeSessionParams {
* request that the remote (also) use an EAP-only authentication flow.
*
* <p>@see {@link Builder#setAuthEap(X509Certificate, EapSessionConfig)}
- *
*/
public static final int IKE_OPTION_EAP_ONLY_AUTH = 1;
@@ -350,9 +349,7 @@ public final class IkeSessionParams {
Inet6Address getAddress();
}
- /**
- * This class contains common information of an IKEv2 authentication configuration.
- */
+ /** This class contains common information of an IKEv2 authentication configuration. */
public abstract static class IkeAuthConfig {
/** @hide */
@IkeAuthMethod public final int mAuthMethod;
@@ -864,10 +861,11 @@ public final class IkeSessionParams {
* Sets the retransmission timeout list in milliseconds.
*
* <p>Configures the retransmission by providing an array of relative retransmission
- * timeouts in milliseconds, where the array length represents the maximum retransmission
- * attempts before terminating the IKE Session. Each element in the array MUST be a value
- * from 500 ms to 1800000 ms (30 minutes). The length of the array MUST NOT exceed 10. This
- * retransmission timeout list defaults to {0.5s, 1s, 2s, 4s, 8s}
+ * timeouts in milliseconds, where each timeout is the waiting time before next retry,
+ * except the last timeout is the waiting time before terminating the IKE Session. Each
+ * element in the array MUST be a value from 500 ms to 1800000 ms (30 minutes). The length
+ * of the array MUST NOT exceed 10. This retransmission timeout list defaults to {0.5s, 1s,
+ * 2s, 4s, 8s}
*
* @param retransTimeoutMillisList the array of relative retransmission timeout in
* milliseconds.
@@ -877,6 +875,7 @@ public final class IkeSessionParams {
public Builder setRetransmissionTimeoutsMillis(@NonNull int[] retransTimeoutMillisList) {
boolean isValid = true;
if (retransTimeoutMillisList == null
+ || retransTimeoutMillisList.length == 0
|| retransTimeoutMillisList.length > IKE_RETRANS_MAX_ATTEMPTS_MAX) {
isValid = false;
}
@@ -943,14 +942,15 @@ public final class IkeSessionParams {
if ((mIkeOptions & getOptionBitValue(IKE_OPTION_EAP_ONLY_AUTH)) != 0) {
if (!(mLocalAuthConfig instanceof IkeAuthEapConfig)) {
- throw new IllegalArgumentException("If IKE_OPTION_EAP_ONLY_AUTH is set,"
- + " eap authentication needs to be configured.");
+ throw new IllegalArgumentException(
+ "If IKE_OPTION_EAP_ONLY_AUTH is set,"
+ + " eap authentication needs to be configured.");
}
IkeAuthEapConfig ikeAuthEapConfig = (IkeAuthEapConfig) mLocalAuthConfig;
if (!ikeAuthEapConfig.getEapConfig().areAllMethodsEapOnlySafe()) {
- throw new IllegalArgumentException("Only EAP-only safe method allowed"
- + " when using EAP-only option.");
+ throw new IllegalArgumentException(
+ "Only EAP-only safe method allowed" + " when using EAP-only option.");
}
}
diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
index 4a6ffb28..6dcc6d26 100644
--- a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
+++ b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
@@ -1827,7 +1827,7 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine {
}
private EncryptedRetransmitter(IkeSaRecord ikeSaRecord, IkeMessage msg) {
- super(getHandler(), msg);
+ super(getHandler(), msg, mIkeSessionParams.getRetransmissionTimeoutsMillis());
mIkeSaRecord = ikeSaRecord;
@@ -2959,7 +2959,7 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine {
private class UnencryptedRetransmitter extends Retransmitter {
private UnencryptedRetransmitter(IkeMessage msg) {
- super(getHandler(), msg);
+ super(getHandler(), msg, mIkeSessionParams.getRetransmissionTimeoutsMillis());
retransmit();
}
diff --git a/src/java/com/android/internal/net/ipsec/ike/utils/Retransmitter.java b/src/java/com/android/internal/net/ipsec/ike/utils/Retransmitter.java
index 778d6859..2b656d3b 100644
--- a/src/java/com/android/internal/net/ipsec/ike/utils/Retransmitter.java
+++ b/src/java/com/android/internal/net/ipsec/ike/utils/Retransmitter.java
@@ -19,7 +19,6 @@ import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_RETR
import android.os.Handler;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.ipsec.ike.message.IkeMessage;
/**
@@ -30,34 +29,15 @@ import com.android.internal.net.ipsec.ike.message.IkeMessage;
* instance of this class.
*/
public abstract class Retransmitter {
- private static IBackoffTimeoutCalculator sBackoffTimeoutCalculator =
- new BackoffTimeoutCalculator();
-
- /*
- * Retransmit parameters
- *
- * (Re)transmission count | Relative timeout | Absolute timeout
- * -------------------------+-------------------+------------------
- * 0 | 500ms | 500ms
- * 1 | 1s | 1.5s
- * 2 | 2s | 3.5s
- * 3 | 4s | 7.5s
- * 4 | 8s | 15.5s
- * 5 | 16s | 31.5s
- *
- * TODO: Add retransmitter configurability
- */
- static final double RETRANSMIT_BACKOFF_FACTOR = 2.0;
- static final long RETRANSMIT_TIMEOUT_MS = 500L;
- static final int RETRANSMIT_MAX_ATTEMPTS = 5;
-
private final Handler mHandler;
private final IkeMessage mRetransmitMsg;
private int mRetransmitCount = 0;
+ private int[] mRetransmissionTimeouts;
- public Retransmitter(Handler handler, IkeMessage msg) {
+ public Retransmitter(Handler handler, IkeMessage msg, int[] retransmissionTimeouts) {
mHandler = handler;
mRetransmitMsg = msg;
+ mRetransmissionTimeouts = retransmissionTimeouts;
}
/**
@@ -69,14 +49,14 @@ public abstract class Retransmitter {
}
// If the failed iteration is beyond the max attempts, clean up and shut down.
- if (mRetransmitCount > RETRANSMIT_MAX_ATTEMPTS) {
+ if (mRetransmitCount >= mRetransmissionTimeouts.length) {
handleRetransmissionFailure();
return;
}
send(mRetransmitMsg);
- long timeout = sBackoffTimeoutCalculator.getExponentialBackoffTimeout(mRetransmitCount++);
+ long timeout = mRetransmissionTimeouts[mRetransmitCount++];
mHandler.sendMessageDelayed(mHandler.obtainMessage(CMD_RETRANSMIT, this), timeout);
}
@@ -105,35 +85,4 @@ public abstract class Retransmitter {
* <p>For Retransmitter-internal use only.
*/
protected abstract void handleRetransmissionFailure();
-
- /**
- * IBackoffTimeoutCalculator provides interface for calculating retransmission backoff timeout.
- *
- * <p>IBackoffTimeoutCalculator exists so that the interface is injectable for testing.
- */
- @VisibleForTesting
- public interface IBackoffTimeoutCalculator {
- /** Calculate retransmission backoff timeout */
- long getExponentialBackoffTimeout(int retransmitCount);
- }
-
- private static final class BackoffTimeoutCalculator implements IBackoffTimeoutCalculator {
- @Override
- public long getExponentialBackoffTimeout(int retransmitCount) {
- double expBackoffFactor = Math.pow(RETRANSMIT_BACKOFF_FACTOR, retransmitCount);
- return (long) (RETRANSMIT_TIMEOUT_MS * expBackoffFactor);
- }
- }
-
- /** Sets IBackoffTimeoutCalculator */
- @VisibleForTesting
- public static void setBackoffTimeoutCalculator(IBackoffTimeoutCalculator calculator) {
- sBackoffTimeoutCalculator = calculator;
- }
-
- /** Resets BackoffTimeoutCalculator of retransmitter */
- @VisibleForTesting
- public static void resetBackoffTimeoutCalculator() {
- sBackoffTimeoutCalculator = new BackoffTimeoutCalculator();
- }
}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
index 7dff7515..bb4c6c26 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
@@ -150,8 +150,6 @@ import com.android.internal.net.ipsec.ike.message.IkeTestUtils;
import com.android.internal.net.ipsec.ike.message.IkeTsPayload;
import com.android.internal.net.ipsec.ike.testutils.CertUtils;
import com.android.internal.net.ipsec.ike.utils.IkeSecurityParameterIndex;
-import com.android.internal.net.ipsec.ike.utils.Retransmitter;
-import com.android.internal.net.ipsec.ike.utils.Retransmitter.IBackoffTimeoutCalculator;
import com.android.internal.net.ipsec.ike.utils.State;
import com.android.internal.net.utils.Log;
@@ -275,15 +273,10 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase {
private static final int CHILD_SPI_LOCAL = 0x2ad4c0a2;
private static final int CHILD_SPI_REMOTE = 0xcae7019f;
- private static final int DUMMY_UDP_ENCAP_RESOURCE_ID = 0x3234;
- private static final int UDP_ENCAP_PORT = 34567;
-
private static final int EAP_SIM_SUB_ID = 1;
private static final int PAYLOAD_TYPE_UNSUPPORTED = 127;
- private static final long RETRANSMIT_BACKOFF_TIMEOUT_MS = 5000L;
-
private IkeUdpEncapSocket mSpyIkeUdpEncapSocket;
private IkeUdp4Socket mSpyIkeUdp4Socket;
private IkeUdp6Socket mSpyIkeUdp6Socket;
@@ -307,7 +300,6 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase {
private IIkeMessageHelper mMockIkeMessageHelper;
private ISaRecordHelper mMockSaRecordHelper;
- private IBackoffTimeoutCalculator mMockBackoffTimeoutCalculator;
private ChildSessionStateMachine mMockChildSessionStateMachine;
private IChildSessionFactoryHelper mMockChildSessionFactoryHelper;
@@ -692,13 +684,6 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase {
mMockChildSessionFactoryHelper);
setupChildStateMachineFactory(mMockChildSessionStateMachine);
- // Inject longer retransmission timeout
- mMockBackoffTimeoutCalculator = mock(IBackoffTimeoutCalculator.class);
- doReturn(RETRANSMIT_BACKOFF_TIMEOUT_MS)
- .when(mMockBackoffTimeoutCalculator)
- .getExponentialBackoffTimeout(anyInt());
- Retransmitter.setBackoffTimeoutCalculator(mMockBackoffTimeoutCalculator);
-
// Setup state machine
mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsPsk(mPsk));
@@ -727,7 +712,6 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase {
mSpyRemoteInitIkeSaRecord.close();
IkeManager.resetIkeLog();
- Retransmitter.resetBackoffTimeoutCalculator();
IkeMessage.setIkeMessageHelper(new IkeMessageHelper());
SaRecord.setSaRecordHelper(new SaRecordHelper());
ChildSessionStateMachineFactory.setChildSessionFactoryHelper(
@@ -796,7 +780,9 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase {
.setRemoteIdentification(
new IkeIpv4AddrIdentification((Inet4Address) REMOTE_ADDRESS))
.addPcscfServerRequest(AF_INET)
- .addPcscfServerRequest(AF_INET6);
+ .addPcscfServerRequest(AF_INET6)
+ .setRetransmissionTimeoutsMillis(
+ new int[] {5000, 10000, 20000, 30000, 40000, 50000});
}
private IkeSessionParams buildIkeSessionParamsPsk(byte[] psk) throws Exception {
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/utils/RetransmitterTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/utils/RetransmitterTest.java
index 63552910..76999519 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/utils/RetransmitterTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/utils/RetransmitterTest.java
@@ -42,13 +42,15 @@ public final class RetransmitterTest {
private Handler mMockHandler;
private IkeMessage mMockIkeMessage;
private TestRetransmitter mRetransmitter;
+ private static final int[] IKE_RETRANS_TIMEOUT_MS_LIST =
+ new int[] {500, 1000, 2000, 4000, 8000};
private class TestRetransmitter extends Retransmitter {
int mSendCallCount; // Defaults to 0
boolean mFailed; // Defaults to false
- TestRetransmitter(Handler handler, IkeMessage message) {
- super(handler, message);
+ TestRetransmitter(Handler handler, IkeMessage message, int[] retransmissionTimeouts) {
+ super(handler, message, retransmissionTimeouts);
}
@Override
@@ -70,7 +72,8 @@ public final class RetransmitterTest {
doReturn(mockMessage).when(mMockHandler).obtainMessage(eq(CMD_RETRANSMIT), anyObject());
mMockIkeMessage = mock(IkeMessage.class);
- mRetransmitter = new TestRetransmitter(mMockHandler, mMockIkeMessage);
+ mRetransmitter =
+ new TestRetransmitter(mMockHandler, mMockIkeMessage, IKE_RETRANS_TIMEOUT_MS_LIST);
}
@Test
@@ -79,18 +82,16 @@ public final class RetransmitterTest {
assertEquals(1, mRetransmitter.mSendCallCount);
verify(mMockHandler).obtainMessage(eq(CMD_RETRANSMIT), eq(mRetransmitter));
verify(mMockHandler)
- .sendMessageDelayed(any(Message.class), eq(Retransmitter.RETRANSMIT_TIMEOUT_MS));
+ .sendMessageDelayed(
+ any(Message.class), eq((long) (IKE_RETRANS_TIMEOUT_MS_LIST[0])));
}
@Test
- public void testRetransmitQueuesExponentialRetransmit() throws Exception {
+ public void testRetransmitUserConfiguredRetransmit() throws Exception {
mRetransmitter.retransmit();
- for (int i = 0; i <= Retransmitter.RETRANSMIT_MAX_ATTEMPTS; i++) {
- long expectedTimeout =
- (long)
- (Retransmitter.RETRANSMIT_TIMEOUT_MS
- * Math.pow(Retransmitter.RETRANSMIT_BACKOFF_FACTOR, i));
+ for (int i = 0; i < IKE_RETRANS_TIMEOUT_MS_LIST.length; i++) {
+ long expectedTimeout = (long) IKE_RETRANS_TIMEOUT_MS_LIST[i];
assertEquals(i + 1, mRetransmitter.mSendCallCount);
assertFalse(mRetransmitter.mFailed);
@@ -114,10 +115,13 @@ public final class RetransmitterTest {
mRetransmitter.retransmit();
// Exhaust all retransmit attempts
- for (int i = 0; i <= Retransmitter.RETRANSMIT_MAX_ATTEMPTS; i++) {
+ for (int i = 0; i < IKE_RETRANS_TIMEOUT_MS_LIST.length - 1; i++) {
mRetransmitter.retransmit();
}
+ assertFalse(mRetransmitter.mFailed);
+ // Trigger the last retransmission
+ mRetransmitter.retransmit();
assertTrue(mRetransmitter.mFailed);
}