Support encoding config payload wth ipv4 address
Bug: 140644755
Test: atest FrameworksIkeTests(new tests added)
Change-Id: Idb63dd01aff31b8d9239d10cfe062b6c7492f080
diff --git a/src/java/com/android/ike/ikev2/message/IkeConfigPayload.java b/src/java/com/android/ike/ikev2/message/IkeConfigPayload.java
index d79880a..766b5c1 100644
--- a/src/java/com/android/ike/ikev2/message/IkeConfigPayload.java
+++ b/src/java/com/android/ike/ikev2/message/IkeConfigPayload.java
@@ -42,6 +42,7 @@
*/
public final class IkeConfigPayload extends IkePayload {
private static final int CONFIG_HEADER_RESERVED_LEN = 3;
+ private static final int CONFIG_HEADER_LEN = 4;
// TODO: Move these constant definitions to API
@Retention(RetentionPolicy.SOURCE)
@@ -107,6 +108,10 @@
/** This class represents common information of all Configuration Attributes. */
public abstract static class ConfigAttribute {
+ private static final int ATTRIBUTE_TYPE_MASK = 0x7fff;
+
+ private static final int ATTRIBUTE_HEADER_LEN = 4;
+
protected static final int VALUE_LEN_NOT_INCLUDED = 0;
protected static final int IPV4_ADDRESS_LEN = 4;
protected static final int IPV6_ADDRESS_LEN = 16;
@@ -153,9 +158,23 @@
return configList;
}
- protected abstract boolean isLengthValid(int length);
+ /** Encode attribute to ByteBuffer. */
+ public void encodeAttributeToByteBuffer(ByteBuffer buffer) {
+ buffer.putShort((short) (attributeType & ATTRIBUTE_TYPE_MASK))
+ .putShort((short) getValueLength());
+ encodeValueToByteBuffer(buffer);
+ }
- // TODO: Add encoding method
+ /** Get attribute length. */
+ public int getAttributeLen() {
+ return ATTRIBUTE_HEADER_LEN + getValueLength();
+ }
+
+ protected abstract void encodeValueToByteBuffer(ByteBuffer buffer);
+
+ protected abstract int getValueLength();
+
+ protected abstract boolean isLengthValid(int length);
}
/**
@@ -192,6 +211,21 @@
}
@Override
+ protected void encodeValueToByteBuffer(ByteBuffer buffer) {
+ if (address == null) {
+ buffer.put(new byte[0]);
+ return;
+ }
+
+ buffer.put(address.getAddress());
+ }
+
+ @Override
+ protected int getValueLength() {
+ return address == null ? 0 : IPV4_ADDRESS_LEN;
+ }
+
+ @Override
protected boolean isLengthValid(int length) {
return length == IPV4_ADDRESS_LEN || length == VALUE_LEN_NOT_INCLUDED;
}
@@ -227,8 +261,12 @@
*/
@Override
protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
- // TODO: Implement it.
- throw new UnsupportedOperationException();
+ encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
+ byteBuffer.put((byte) configType).put(new byte[CONFIG_HEADER_RESERVED_LEN]);
+
+ for (ConfigAttribute attr : recognizedAttributeList) {
+ attr.encodeAttributeToByteBuffer(byteBuffer);
+ }
}
/**
@@ -238,8 +276,13 @@
*/
@Override
protected int getPayloadLength() {
- // TODO: Implement it.
- throw new UnsupportedOperationException();
+ int len = GENERIC_HEADER_LENGTH + CONFIG_HEADER_LEN;
+
+ for (ConfigAttribute attr : recognizedAttributeList) {
+ len += attr.getAttributeLen();
+ }
+
+ return len;
}
/**
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeConfigPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeConfigPayloadTest.java
index 291d413..4cdd132 100644
--- a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeConfigPayloadTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeConfigPayloadTest.java
@@ -20,13 +20,18 @@
import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_TYPE_REPLY;
import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_TYPE_REQUEST;
import static com.android.ike.ikev2.message.IkePayload.PAYLOAD_TYPE_CP;
+import static com.android.ike.ikev2.message.IkePayload.PAYLOAD_TYPE_NOTIFY;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import com.android.ike.TestUtils;
import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
@@ -39,6 +44,7 @@
import java.net.Inet4Address;
import java.nio.ByteBuffer;
+import java.util.LinkedList;
import java.util.List;
public final class IkeConfigPayloadTest {
@@ -54,6 +60,17 @@
private static final Inet4Address IPV4_ADDRESS =
(Inet4Address) (InetAddressUtils.parseNumericAddress("10.10.10.1"));
+ private static final byte[] IPV4_ADDRESS_ATTRIBUTE_WITH_VALUE =
+ TestUtils.hexStringToByteArray("000100040a0a0a01");
+ private static final byte[] IPV4_ADDRESS_ATTRIBUTE_WITHOUT_VALUE =
+ TestUtils.hexStringToByteArray("00010000");
+
+ private static final byte[] IPV6_ADDRESS_ATTRIBUTE_WITHOUT_VALUE =
+ TestUtils.hexStringToByteArray("00080000");
+ private static final byte[] IPV4_DNS_ATTRIBUTE_WITHOUT_VALUE =
+ TestUtils.hexStringToByteArray("00030000");
+ private static final byte[] IPV6_DNS_ATTRIBUTE_WITHOUT_VALUE =
+ TestUtils.hexStringToByteArray("000a0000");
private IkeConfigPayload verifyDecodeHeaderAndGetPayload(
IkePayload payload, int expectedConfigType) {
@@ -86,8 +103,6 @@
(ConfigAttributeIpv4Address) recognizedAttributeList.get(0);
assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, attributeIp4Address.attributeType);
assertNull(attributeIp4Address.address);
-
- // TODO: Verify decoded other types of attributes when they are supported.
}
@Test
@@ -109,19 +124,42 @@
(ConfigAttributeIpv4Address) recognizedAttributeList.get(0);
assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, attributeIp4Address.attributeType);
assertEquals(IPV4_ADDRESS, attributeIp4Address.address);
+ }
- // TODO: Verify decoded other types of attributes when they are supported.
+ private ConfigAttribute makeMockAttribute(byte[] encodedAttribute) {
+ ConfigAttribute mockAttribute = mock(ConfigAttribute.class);
+
+ when(mockAttribute.getAttributeLen()).thenReturn(encodedAttribute.length);
+
+ doAnswer(
+ (invocation) -> {
+ ByteBuffer buffer = (ByteBuffer) invocation.getArguments()[0];
+ buffer.put(encodedAttribute);
+ return null;
+ })
+ .when(mockAttribute)
+ .encodeAttributeToByteBuffer(any(ByteBuffer.class));
+
+ return mockAttribute;
}
@Test
- public void testBuildOutboundConfig() throws Exception {
- List<ConfigAttribute> mockAttributeList = mock(List.class);
+ public void testBuildAndEncodeOutboundConfig() throws Exception {
+ List<ConfigAttribute> mockAttributeList = new LinkedList<>();
+ mockAttributeList.add(makeMockAttribute(IPV4_ADDRESS_ATTRIBUTE_WITHOUT_VALUE));
+ mockAttributeList.add(makeMockAttribute(IPV6_ADDRESS_ATTRIBUTE_WITHOUT_VALUE));
+ mockAttributeList.add(makeMockAttribute(IPV4_DNS_ATTRIBUTE_WITHOUT_VALUE));
+ mockAttributeList.add(makeMockAttribute(IPV6_DNS_ATTRIBUTE_WITHOUT_VALUE));
IkeConfigPayload configPayload = new IkeConfigPayload(false /*isReply*/, mockAttributeList);
assertEquals(PAYLOAD_TYPE_CP, configPayload.payloadType);
assertFalse(configPayload.isCritical);
assertEquals(CONFIG_TYPE_REQUEST, configPayload.configType);
assertEquals(mockAttributeList, configPayload.recognizedAttributeList);
+
+ ByteBuffer buffer = ByteBuffer.allocate(configPayload.getPayloadLength());
+ configPayload.encodeToByteBuffer(PAYLOAD_TYPE_NOTIFY, buffer);
+ assertArrayEquals(CONFIG_REQ_PAYLOAD, buffer.array());
}
@Test
@@ -154,5 +192,28 @@
}
}
- // TODO: Testing encoding attributes
+ @Test
+ public void testEncodeIpv4AddressWithValue() throws Exception {
+ ConfigAttributeIpv4Address attributeIp4Address =
+ new ConfigAttributeIpv4Address(IPV4_ADDRESS);
+
+ assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, attributeIp4Address.attributeType);
+ assertEquals(IPV4_ADDRESS, attributeIp4Address.address);
+
+ ByteBuffer buffer = ByteBuffer.allocate(attributeIp4Address.getAttributeLen());
+ attributeIp4Address.encodeAttributeToByteBuffer(buffer);
+ assertArrayEquals(IPV4_ADDRESS_ATTRIBUTE_WITH_VALUE, buffer.array());
+ }
+
+ @Test
+ public void testEncodeIpv4AddressWithoutValue() throws Exception {
+ ConfigAttributeIpv4Address attributeIp4Address = new ConfigAttributeIpv4Address();
+
+ assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, attributeIp4Address.attributeType);
+ assertNull(attributeIp4Address.address);
+
+ ByteBuffer buffer = ByteBuffer.allocate(attributeIp4Address.getAttributeLen());
+ attributeIp4Address.encodeAttributeToByteBuffer(buffer);
+ assertArrayEquals(IPV4_ADDRESS_ATTRIBUTE_WITHOUT_VALUE, buffer.array());
+ }
}