aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Sardara <msardara@cisco.com>2022-07-08 16:10:13 +0000
committerMauro Sardara <msardara@cisco.com>2022-08-10 11:57:10 +0200
commit8f0a8bf572b9b8123121338a31462440bad65857 (patch)
treeecac67f0ad005b2eb0a1bd25c8f242497ffddea1
parent8d27045832427a0ea345f48bfb2c42f46a357af1 (diff)
feat: add interest manifest serialization/deserialization
Also: add helpers for interest manifest Ref: HICN-738 Signed-off-by: Mauro Sardara <msardara@cisco.com> Change-Id: Ia531605148e00ccbe446da0f4f2d8caae2b098be Signed-off-by: Mauro Sardara <msardara@cisco.com>
-rw-r--r--Dockerfile.dev13
-rw-r--r--ctrl/libhicnctrl/src/modules/CMakeLists.txt18
-rw-r--r--hicn-light/src/hicn/core/forwarder.c16
-rw-r--r--hicn-plugin/src/hicn.h7
-rw-r--r--hicn-plugin/src/interest_pcslookup_node.c6
-rw-r--r--hicn-plugin/src/parser.h4
-rw-r--r--lib/includes/hicn/common.h58
-rw-r--r--lib/includes/hicn/interest_manifest.h91
-rw-r--r--lib/includes/hicn/util/bitmap.h48
-rw-r--r--lib/includes/hicn/util/types.h8
-rw-r--r--lib/src/protocol/ah.c4
-rw-r--r--lib/src/test/test_interest_manifest.cc117
-rw-r--r--libtransport/includes/hicn/transport/core/interest.h2
-rw-r--r--libtransport/src/core/interest.cc31
-rw-r--r--libtransport/src/test/test_interest.cc7
15 files changed, 362 insertions, 68 deletions
diff --git a/Dockerfile.dev b/Dockerfile.dev
index 43a0c4555..326f4676c 100644
--- a/Dockerfile.dev
+++ b/Dockerfile.dev
@@ -5,6 +5,10 @@ WORKDIR /hicn-build
COPY Makefile versions.cmake ./
COPY scripts scripts/
+ARG USERNAME=ubuntu
+ARG USER_UID=1000
+ARG USER_GID=${USER_UID}
+
RUN apt update && apt-get install -y \
make \
sudo \
@@ -14,4 +18,13 @@ RUN apt update && apt-get install -y \
RUN make deps debug-tools
+# Add non-root user
+RUN groupadd --gid ${USER_GID} ${USERNAME} && \
+ useradd -s /bin/bash --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} && \
+ echo ${USERNAME} ALL=\(root\) NOPASSWD:ALL >/etc/sudoers.d/${USERNAME} && \
+ chmod 0440 /etc/sudoers.d/${USERNAME}
+
+USER ${USERNAME}
+WORKDIR /home/${USERNAME}
+
ENV DEBIAN_FRONTEND=
diff --git a/ctrl/libhicnctrl/src/modules/CMakeLists.txt b/ctrl/libhicnctrl/src/modules/CMakeLists.txt
index b85ef29dc..682192c6c 100644
--- a/ctrl/libhicnctrl/src/modules/CMakeLists.txt
+++ b/ctrl/libhicnctrl/src/modules/CMakeLists.txt
@@ -72,6 +72,22 @@ if(BUILD_HICNPLUGIN AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/route.h
)
+ ##############################################################
+ # Compiler Options
+ ##############################################################
+ set(COMPILER_OPTIONS
+ ${DEFAULT_COMPILER_OPTIONS}
+ ${MARCH_COMPILER_OPTIONS}
+ PRIVATE "-Wno-address-of-packed-member"
+ )
+
+ ##############################################################
+ # Compiler Definitions
+ ##############################################################
+ list(APPEND COMPILER_DEFINITIONS
+ PRIVATE "-DHICN_VPP_PLUGIN=1"
+ )
+
build_module(vppctrl_module
SOURCES ${HICN_PLUGIN_SOURCE_FILES} ${HICN_PLUGIN_HEADER_FILES}
DEPENDS ${DEPENDENCIES}
@@ -82,6 +98,6 @@ if(BUILD_HICNPLUGIN AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
COMPONENT ${LIBHICNCTRL_COMPONENT_MODULES}
INCLUDE_DIRS PRIVATE ${INCLUDE_DIRS}
DEFINITIONS PRIVATE ${COMPILER_DEFINITIONS}
- COMPILE_OPTIONS ${COMPILER_OPTIONS} ${MARCH_COMPILER_OPTIONS} "-DHICN_VPP_PLUGIN=1"
+ COMPILE_OPTIONS ${COMPILER_OPTIONS}
)
endif()
diff --git a/hicn-light/src/hicn/core/forwarder.c b/hicn-light/src/hicn/core/forwarder.c
index 482e3d6f1..14f1649fa 100644
--- a/hicn-light/src/hicn/core/forwarder.c
+++ b/hicn-light/src/hicn/core/forwarder.c
@@ -790,9 +790,18 @@ static interest_manifest_header_t *_forwarder_get_interest_manifest(
if (payload_type != HPT_MANIFEST) return NULL;
rc = hicn_packet_get_payload(pkbuf, &payload, &payload_size, false);
- _ASSERT(rc == HICN_LIB_ERROR_NONE);
+ assert(rc == HICN_LIB_ERROR_NONE);
+
+ interest_manifest_header_t *int_manifest_header =
+ (interest_manifest_header_t *)payload;
- return (interest_manifest_header_t *)payload;
+ // Deserialize intrest mmanifest
+ interest_manifest_deserialize(int_manifest_header);
+
+ if (!interest_manifest_is_valid(int_manifest_header, payload_size))
+ return NULL;
+
+ return int_manifest_header;
}
// Manifest is split using splitting strategy, then every
@@ -901,6 +910,9 @@ int _forwarder_forward_aggregated_interest(
{ pit_entry_egress_add(pit_entry, nexthop); });
}
+ // Serialize manifest before sending it
+ interest_manifest_serialize(int_manifest_header);
+
if (forwarder_forward_to_nexthops(forwarder, msgbuf_id, nexthops) <=
0) {
ERROR("Message %p returned an empty next hop set", msgbuf);
diff --git a/hicn-plugin/src/hicn.h b/hicn-plugin/src/hicn.h
index 9acd9662f..84d268357 100644
--- a/hicn-plugin/src/hicn.h
+++ b/hicn-plugin/src/hicn.h
@@ -83,6 +83,7 @@ typedef struct
hicn_name_t name;
*/
u16 port;
+ u16 payload_type;
hicn_lifetime_t lifetime;
} hicn_buffer_t;
@@ -139,6 +140,12 @@ hicn_buffer_get_lifetime (vlib_buffer_t *b)
return hicn_get_buffer (b)->lifetime;
}
+always_inline hicn_payload_type_t
+hicn_buffer_get_payload_type (vlib_buffer_t *b)
+{
+ return hicn_get_buffer (b)->payload_type;
+}
+
#endif /* __HICN_H__ */
/*
diff --git a/hicn-plugin/src/interest_pcslookup_node.c b/hicn-plugin/src/interest_pcslookup_node.c
index f0683727a..ab6a31e08 100644
--- a/hicn-plugin/src/interest_pcslookup_node.c
+++ b/hicn-plugin/src/interest_pcslookup_node.c
@@ -126,6 +126,12 @@ hicn_interest_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
stats.pkts_interest_count++;
+ // Interest manifest?
+ if (hicn_buffer_get_payload_type (b0) == HPT_MANIFEST)
+ {
+ ;
+ }
+
// Maybe trace
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
(b0->flags & VLIB_BUFFER_IS_TRACED)))
diff --git a/hicn-plugin/src/parser.h b/hicn-plugin/src/parser.h
index 1d297e510..f9b3e43ae 100644
--- a/hicn-plugin/src/parser.h
+++ b/hicn-plugin/src/parser.h
@@ -36,6 +36,7 @@
\
u16 *port; \
hicn_lifetime_t *lifetime; \
+ hicn_payload_type_t payload_type; \
\
hicn_packet_buffer_t *pkbuf = &hicn_get_buffer (pkt)->pkbuf; \
\
@@ -58,6 +59,9 @@
if (*lifetime > hicn_main.pit_lifetime_max_ms) \
*lifetime = hicn_main.pit_lifetime_max_ms; \
\
+ /* get payload type */ \
+ hicn_packet_get_payload_type (pkbuf, &payload_type); \
+ hicn_get_buffer (pkt)->payload_type = (u16) (payload_type); \
return ret; \
} \
while (0)
diff --git a/lib/includes/hicn/common.h b/lib/includes/hicn/common.h
index a84124617..64aca8f1f 100644
--- a/lib/includes/hicn/common.h
+++ b/lib/includes/hicn/common.h
@@ -235,34 +235,54 @@ typedef struct
} ip_version_t;
#define HICN_IP_VERSION(packet) ((ip_version_t *) packet)->version
-#ifndef ntohll
-static inline uint64_t
-ntohll (uint64_t input)
-{
- uint64_t return_val = input;
+/*
+ * Endianess utils
+ */
+
#if (__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)
- uint8_t *tmp = (uint8_t *) &return_val;
-
- tmp[0] = (uint8_t) (input >> 56);
- tmp[1] = (uint8_t) (input >> 48);
- tmp[2] = (uint8_t) (input >> 40);
- tmp[3] = (uint8_t) (input >> 32);
- tmp[4] = (uint8_t) (input >> 24);
- tmp[5] = (uint8_t) (input >> 16);
- tmp[6] = (uint8_t) (input >> 8);
- tmp[7] = (uint8_t) (input >> 0);
+#define HICN_LITTLE_ENDIAN_ARCH
+#else
+#define HICN_BIG_ENDIAN_ARCH
+#endif
+
+static inline u16
+hicn_conditional_swap_u16 (u16 value)
+{
+#ifdef HICN_LITTLE_ENDIAN_ARCH
+ value = __builtin_bswap16 (value);
#endif
- return return_val;
+ return value;
}
-static inline uint64_t
-htonll (uint64_t input)
+static inline u32
+hicn_conditional_swap_u32 (u32 value)
{
- return (ntohll (input));
+#ifdef HICN_LITTLE_ENDIAN_ARCH
+ value = __builtin_bswap32 (value);
+#endif
+
+ return value;
}
+
+static inline u64
+hicn_conditional_swap_u64 (u64 value)
+{
+#ifdef HICN_LITTLE_ENDIAN_ARCH
+ value = __builtin_bswap64 (value);
#endif
+ return value;
+}
+
+#define hicn_net_to_host_16(x) hicn_conditional_swap_u16 ((u16) (x))
+#define hicn_net_to_host_32(x) hicn_conditional_swap_u32 ((u32) (x))
+#define hicn_net_to_host_64(x) hicn_conditional_swap_u64 ((u64) (x))
+
+#define hicn_host_to_net_16(x) hicn_conditional_swap_u16 ((u16) (x))
+#define hicn_host_to_net_32(x) hicn_conditional_swap_u32 ((u32) (x))
+#define hicn_host_to_net_64(x) hicn_conditional_swap_u64 ((u64) (x))
+
#define hicn_round_pow2(x, pow2) (((x) + (pow2) -1) & ~((pow2) -1))
#define _SIZEOF_ALIGNED(x, size) hicn_round_pow2 (sizeof (x), size)
diff --git a/lib/includes/hicn/interest_manifest.h b/lib/includes/hicn/interest_manifest.h
index 03f54d6d5..2b4cd57a2 100644
--- a/lib/includes/hicn/interest_manifest.h
+++ b/lib/includes/hicn/interest_manifest.h
@@ -21,6 +21,8 @@
#include <hicn/util/bitmap.h>
#include <hicn/base.h>
+#include <hicn/name.h>
+#include <hicn/common.h>
typedef enum
{
@@ -52,7 +54,56 @@ typedef struct
} interest_manifest_header_t;
static_assert (sizeof (interest_manifest_header_t) == 32 + 4 + 4,
- "interest_manifest_header_t size must be 40 bytes");
+ "interest_manifest_header_t size must be exactly 40 bytes");
+
+#define _interest_manifest_serialize_deserialize(manifest, first, second, \
+ size, serialize) \
+ do \
+ { \
+ u32 n_suffixes = 0; \
+ if (serialize) \
+ n_suffixes = int_manifest_header->n_suffixes; \
+ \
+ int_manifest_header->n_suffixes = \
+ hicn_##first##_to_##second##_32 (int_manifest_header->n_suffixes); \
+ int_manifest_header->padding = \
+ hicn_##first##_to_##second##_32 (int_manifest_header->padding); \
+ \
+ for (unsigned i = 0; i < BITMAP_SIZE; i++) \
+ { \
+ int_manifest_header->request_bitmap[i] = \
+ hicn_##first##_to_##second##_##size ( \
+ int_manifest_header->request_bitmap[i]); \
+ } \
+ \
+ hicn_name_suffix_t *suffix = \
+ (hicn_name_suffix_t *) (int_manifest_header + 1); \
+ if (!serialize) \
+ n_suffixes = int_manifest_header->n_suffixes; \
+ for (unsigned i = 0; i < n_suffixes; i++) \
+ { \
+ *(suffix + i) = hicn_##first##_to_##second##_32 (*(suffix + i)); \
+ } \
+ } \
+ while (0)
+
+#define _interest_manifest_serialize(manifest, size) \
+ _interest_manifest_serialize_deserialize (manifest, host, net, size, 1)
+
+#define _interest_manifest_deserialize(manifest, size) \
+ _interest_manifest_serialize_deserialize (manifest, net, host, size, 0)
+
+static inline void
+interest_manifest_serialize (interest_manifest_header_t *int_manifest_header)
+{
+ _interest_manifest_serialize (int_manifest_header, hicn_uword_bits);
+}
+
+static inline void
+interest_manifest_deserialize (interest_manifest_header_t *int_manifest_header)
+{
+ _interest_manifest_deserialize (int_manifest_header, hicn_uword_bits);
+}
static inline bool
interest_manifest_is_valid (interest_manifest_header_t *int_manifest_header,
@@ -80,6 +131,33 @@ interest_manifest_is_valid (interest_manifest_header_t *int_manifest_header,
return true;
}
+static inline void
+interest_manifest_init (interest_manifest_header_t *int_manifest_header)
+{
+ int_manifest_header->n_suffixes = 0;
+ int_manifest_header->padding = 0;
+ memset (int_manifest_header->request_bitmap, 0,
+ sizeof (int_manifest_header->request_bitmap));
+}
+
+static inline void
+interest_manifest_add_suffix (interest_manifest_header_t *int_manifest_header,
+ hicn_name_suffix_t suffix)
+{
+ hicn_name_suffix_t *start = (hicn_name_suffix_t *) (int_manifest_header + 1);
+ *(start + int_manifest_header->n_suffixes) = suffix;
+ hicn_uword *request_bitmap = int_manifest_header->request_bitmap;
+ bitmap_set_no_check (request_bitmap, int_manifest_header->n_suffixes);
+ int_manifest_header->n_suffixes++;
+}
+
+static inline void
+interest_manifest_del_suffix (interest_manifest_header_t *int_manifest_header,
+ hicn_uword pos)
+{
+ bitmap_unset_no_check (int_manifest_header->request_bitmap, pos);
+}
+
static inline size_t
interest_manifest_update_bitmap (const hicn_uword *initial_bitmap,
hicn_uword *bitmap_to_update, size_t start,
@@ -102,4 +180,15 @@ interest_manifest_update_bitmap (const hicn_uword *initial_bitmap,
return i;
}
+#define _FIRST(h) (hicn_name_suffix_t *) (h + 1)
+
+#define interest_manifest_foreach_suffix(header, suffix) \
+ for (suffix = _FIRST (header) + bitmap_first_set_no_check ( \
+ header->request_bitmap, BITMAP_SIZE); \
+ suffix - _FIRST (header) < header->n_suffixes; \
+ suffix = _FIRST (header) + \
+ bitmap_next_set_no_check (header->request_bitmap, \
+ suffix - _FIRST (header) + 1, \
+ BITMAP_SIZE))
+
#endif /* HICNLIGHT_INTEREST_MANIFEST_H */
diff --git a/lib/includes/hicn/util/bitmap.h b/lib/includes/hicn/util/bitmap.h
index 15d47ac61..68541bc28 100644
--- a/lib/includes/hicn/util/bitmap.h
+++ b/lib/includes/hicn/util/bitmap.h
@@ -127,40 +127,46 @@ _bitmap_get_no_check (const bitmap_t *bitmap, off_t i)
#define bitmap_is_unset_no_check(bitmap, i) \
(_bitmap_get_no_check ((bitmap), (i)) == 0)
+static inline int
+_bitmap_set_no_check (bitmap_t *bitmap, off_t i)
+{
+ size_t offset = i / BITMAP_WIDTH (bitmap);
+ size_t pos = i % BITMAP_WIDTH (bitmap);
+ bitmap[offset] |= (bitmap_t) 1 << pos;
+ return 0;
+}
+
+static inline int
+_bitmap_set (bitmap_t **bitmap_ptr, off_t i)
+{
+ if (bitmap_ensure_pos (bitmap_ptr, i) < 0)
+ return -1;
+
+ bitmap_t *bitmap = *bitmap_ptr;
+ return _bitmap_set_no_check (bitmap, i);
+}
+
/*
- * @brief Returns whether the i-th bit is unset (equal to 0) in a bitmap.
+ * @brief Set i-th bit to 1 in a bitmap. Reallocate the vector if the bit
+ * position is greater than the vector length.
*
* @param[in] bitmap The bitmap to access.
* @param[in] i The bit position.
*
* @return bool
*/
-#define bitmap_set(bitmap, i) _bitmap_set ((bitmap_t **) &bitmap, i, 1)
-#define bitmap_set_no_check(bitmap, i) \
- _bitmap_set ((bitmap_t **) &bitmap, i, 0)
+#define bitmap_set(bitmap, i) _bitmap_set ((bitmap_t **) &bitmap, i)
/*
- * @brief Returns whether the i-th bit is unset (equal to 0) in a bitmap
- * (helper).
+ * @brief Set i-th bit to 1 in a bitmap. Unsafe version, does not check
+ * boundaries.
*
* @param[in] bitmap The bitmap to access.
* @param[in] i The bit position.
*
* @return bool
*/
-static inline int
-_bitmap_set (bitmap_t **bitmap_ptr, off_t i, int check)
-{
- if (check && bitmap_ensure_pos (bitmap_ptr, i) < 0)
- return -1;
-
- bitmap_t *bitmap = *bitmap_ptr;
- size_t offset = i / BITMAP_WIDTH (bitmap);
- size_t pos = i % BITMAP_WIDTH (bitmap);
-
- bitmap[offset] |= (bitmap_t) 1 << pos;
- return 0;
-}
+#define bitmap_set_no_check(bitmap, i) _bitmap_set_no_check (bitmap, i)
#define bitmap_unset(bitmap, i) _bitmap_unset (bitmap, i, 1)
#define bitmap_unset_no_check(bitmap, i) _bitmap_unset (bitmap, i, 0)
@@ -306,11 +312,11 @@ bitmap_next_unset (const bitmap_t *bitmap, hicn_uword i)
#define bitmap_first_set(bitmap) bitmap_next_set (bitmap, 0)
#define bitmap_first_set_no_check(bitmap, size) \
- bitmap_next_set_no_checks (bitmap, 0, size)
+ bitmap_next_set_no_check (bitmap, 0, size)
#define bitmap_first_unset(bitmap) bitmap_next_unset (bitmap, 0)
#define bitmap_first_unset_no_check(bitmap, size) \
- bitmap_next_unset_no_checks (bitmap, 0, size)
+ bitmap_next_unset_no_check (bitmap, 0, size)
static inline void
bitmap_print (const bitmap_t *bitmap, size_t n_words)
diff --git a/lib/includes/hicn/util/types.h b/lib/includes/hicn/util/types.h
index c9cc878cf..a883b8220 100644
--- a/lib/includes/hicn/util/types.h
+++ b/lib/includes/hicn/util/types.h
@@ -44,21 +44,21 @@ typedef float f32;
#error "Impossible to detect architecture"
#endif
-#define hicn_uword_bits (1 << hicn_log2_uword_bits)
+#define _hicn_uword_bits (1 << hicn_log2_uword_bits)
/* Word types. */
-#if hicn_uword_bits == 64
+#if _hicn_uword_bits == 64
/* 64 bit word machines. */
typedef u64 hicn_uword;
+#define hicn_uword_bits 64
#else
/* 32 bit word machines. */
typedef u32 hicn_uword;
+#define hicn_uword_bits 32
#endif
typedef hicn_uword hicn_ip_csum_t;
-#define hicn_uword_bits (1 << hicn_log2_uword_bits)
-
/* Helper for avoiding warnings about type-punning */
#define UNION_CAST(x, destType) \
(((union { \
diff --git a/lib/src/protocol/ah.c b/lib/src/protocol/ah.c
index 9cc747ac8..645b0482b 100644
--- a/lib/src/protocol/ah.c
+++ b/lib/src/protocol/ah.c
@@ -192,7 +192,7 @@ ah_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
{
_ah_header_t *ah = pkbuf_get_ah (pkbuf);
- uint64_t netwok_order_timestamp = htonll (signature_timestamp);
+ uint64_t netwok_order_timestamp = hicn_net_to_host_64 (signature_timestamp);
memcpy (ah->timestamp_as_u8, &netwok_order_timestamp, sizeof (uint64_t));
return HICN_LIB_ERROR_NONE;
}
@@ -204,7 +204,7 @@ ah_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
_ah_header_t *ah = pkbuf_get_ah (pkbuf);
memcpy (signature_timestamp, ah->timestamp_as_u8, sizeof (uint64_t));
- *signature_timestamp = ntohll (*signature_timestamp);
+ *signature_timestamp = hicn_host_to_net_64 (*signature_timestamp);
return HICN_LIB_ERROR_NONE;
}
diff --git a/lib/src/test/test_interest_manifest.cc b/lib/src/test/test_interest_manifest.cc
index c912b0bc6..5df06d6bd 100644
--- a/lib/src/test/test_interest_manifest.cc
+++ b/lib/src/test/test_interest_manifest.cc
@@ -14,6 +14,7 @@
*/
#include <gtest/gtest.h>
+#include <gmock/gmock.h>
extern "C"
{
@@ -25,8 +26,17 @@ static constexpr hicn_uword WORD_SIZE = WORD_WIDTH;
class InterestManifestTest : public ::testing::Test
{
protected:
+ static constexpr u32 n_suffixes = 0x00000014;
+ static constexpr u32 padding = 0x21232425;
+ static constexpr hicn_uword bitmap_word = ~0ULL;
+ static inline std::vector<uint32_t> values = { 10, 22, 23, 43, 54, 65, 66,
+ 4, 33, 2, 44, 99, 87, 67,
+ 78, 98, 76, 1, 7, 123 };
InterestManifestTest () {}
virtual ~InterestManifestTest () {}
+
+ uint8_t buffer[512];
+ hicn_uword bitmap_saved[BITMAP_SIZE];
};
TEST_F (InterestManifestTest, OneWordBitmapUpdate)
@@ -83,4 +93,111 @@ TEST_F (InterestManifestTest, TwoWordBitmapUpdate)
EXPECT_EQ (curr_bitmap[1], expected_bitmap[i][1]);
i++;
}
+}
+
+TEST_F (InterestManifestTest, SerializeDeserialize)
+{
+#if hicn_uword_bits == 64
+#define F(x) hicn_host_to_net_64 (x)
+#elif hicn_uword_bits == 32
+#define F(x) hicn_host_to_net_32 (x)
+#else
+#error "Unrecognized architecture"
+#endif
+
+ auto header = reinterpret_cast<interest_manifest_header_t *> (buffer);
+ interest_manifest_init (header);
+
+ for (const auto &v : values)
+ {
+ interest_manifest_add_suffix (header, v);
+ }
+
+ EXPECT_EQ (header->n_suffixes, n_suffixes);
+
+ // Save bitmap
+ memcpy (bitmap_saved, header->request_bitmap, sizeof (bitmap_saved));
+
+ // Serialize manifest
+ interest_manifest_serialize (header);
+
+ // If architecture is little endian, bytes should be now swapped
+ EXPECT_THAT (header->n_suffixes, ::testing::Eq (hicn_host_to_net_32 (
+ n_suffixes) /* 0x14000000 */));
+
+ for (unsigned i = 0; i < BITMAP_SIZE; i++)
+ {
+ EXPECT_THAT (header->request_bitmap[i],
+ ::testing::Eq (F (bitmap_saved[i])));
+ }
+
+ hicn_name_suffix_t *suffix = (hicn_name_suffix_t *) (header + 1);
+ for (unsigned i = 0; i < n_suffixes; i++)
+ {
+ EXPECT_THAT (*(suffix + i),
+ ::testing::Eq (hicn_host_to_net_32 (values[i])));
+ }
+
+ // Deserialize manifest
+ interest_manifest_deserialize (header);
+
+ // Bytes should now be as before
+ EXPECT_THAT (header->n_suffixes, ::testing::Eq (n_suffixes));
+
+ int i = 0;
+ interest_manifest_foreach_suffix (header, suffix)
+ {
+ EXPECT_THAT (*suffix, ::testing::Eq (values[i]));
+ i++;
+ }
+}
+
+TEST_F (InterestManifestTest, ForEach)
+{
+ auto header = reinterpret_cast<interest_manifest_header_t *> (buffer);
+ header->n_suffixes = n_suffixes;
+ header->padding = padding;
+ memset (header->request_bitmap, 0xff, BITMAP_SIZE * sizeof (hicn_uword));
+
+ hicn_name_suffix_t *suffix = (hicn_name_suffix_t *) (header + 1);
+ for (uint32_t i = 0; i < n_suffixes; i++)
+ {
+ *(suffix + i) = values[i];
+ }
+
+ // Iterate over interest manifest. As bitmap is all 1, we should be able to
+ // iterate over all suffixes.
+ unsigned i = 0;
+ interest_manifest_foreach_suffix (header, suffix)
+ {
+ EXPECT_EQ (*suffix, values[i]);
+ i++;
+ }
+
+ std::set<uint32_t> set_values (values.begin (), values.end ());
+
+ // Unset few bitmap positions
+ interest_manifest_del_suffix (header, 5);
+ set_values.erase (values[5]);
+
+ interest_manifest_del_suffix (header, 6);
+ set_values.erase (values[6]);
+
+ interest_manifest_del_suffix (header, 12);
+ set_values.erase (values[12]);
+
+ interest_manifest_del_suffix (header, 17);
+ set_values.erase (values[17]);
+
+ // Iterate over interest manifest and remove elements in manifest from set.
+ // The set should be empty at the end.
+ interest_manifest_foreach_suffix (header, suffix)
+ {
+ std::cout << suffix - _FIRST (header) << std::endl;
+ EXPECT_TRUE (set_values.find (*suffix) != set_values.end ())
+ << "The value was " << *suffix;
+ set_values.erase (*suffix);
+ }
+
+ EXPECT_TRUE (set_values.empty ());
} \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/core/interest.h b/libtransport/includes/hicn/transport/core/interest.h
index 23dc8f75e..716ac6b0a 100644
--- a/libtransport/includes/hicn/transport/core/interest.h
+++ b/libtransport/includes/hicn/transport/core/interest.h
@@ -92,6 +92,8 @@ class Interest
void appendSuffix(std::uint32_t suffix);
+ void decodeSuffixes();
+
void encodeSuffixes();
uint32_t *firstSuffix();
diff --git a/libtransport/src/core/interest.cc b/libtransport/src/core/interest.cc
index 0851bfef6..777374b09 100644
--- a/libtransport/src/core/interest.cc
+++ b/libtransport/src/core/interest.cc
@@ -171,7 +171,7 @@ void Interest::encodeSuffixes() {
(interest_manifest_header_t *)(writableData() + headerSize());
int_manifest_header->n_suffixes = (uint32_t)suffix_set_.size();
memset(int_manifest_header->request_bitmap, 0xFFFFFFFF,
- BITMAP_SIZE * sizeof(u32));
+ BITMAP_SIZE * sizeof(hicn_uword));
uint32_t *suffix = (uint32_t *)(int_manifest_header + 1);
for (auto it = suffix_set_.begin(); it != suffix_set_.end(); it++, suffix++) {
@@ -181,10 +181,21 @@ void Interest::encodeSuffixes() {
std::size_t additional_length =
sizeof(interest_manifest_header_t) +
int_manifest_header->n_suffixes * sizeof(uint32_t);
+
+ // Serialize interest manifest
+ interest_manifest_serialize(int_manifest_header);
+
append(additional_length);
updateLength();
}
+void Interest::decodeSuffixes() {
+ if (!hasManifest()) return;
+
+ auto header = (interest_manifest_header_t *)(writableData() + headerSize());
+ interest_manifest_deserialize(header);
+}
+
uint32_t *Interest::firstSuffix() {
if (!hasManifest()) {
return nullptr;
@@ -223,24 +234,8 @@ void Interest::setRequestBitmap(const uint32_t *request_bitmap) {
bool Interest::isValid() {
if (!hasManifest()) return true;
-
auto header = (interest_manifest_header_t *)(writableData() + headerSize());
-
- if (header->n_suffixes == 0 ||
- header->n_suffixes > MAX_SUFFIXES_IN_MANIFEST) {
- std::cerr << "Manifest with invalid number of suffixes "
- << header->n_suffixes;
- return false;
- }
-
- uint32_t empty_bitmap[BITMAP_SIZE];
- memset(empty_bitmap, 0, sizeof(empty_bitmap));
- if (memcmp(empty_bitmap, header->request_bitmap, sizeof(empty_bitmap)) == 0) {
- std::cerr << "Manifest with empty bitmap";
- return false;
- }
-
- return true;
+ return interest_manifest_is_valid(header, payloadSize());
}
} // end namespace core
diff --git a/libtransport/src/test/test_interest.cc b/libtransport/src/test/test_interest.cc
index 8d00a9c6d..ba63b6c93 100644
--- a/libtransport/src/test/test_interest.cc
+++ b/libtransport/src/test/test_interest.cc
@@ -255,7 +255,11 @@ TEST_F(InterestTest, AppendSuffixesEncodeAndIterate) {
// Encode them in wire format
interest.encodeSuffixes();
+ // Decode suffixes from wire format
+ interest.decodeSuffixes();
+
// Iterate over them. They should be in order and without repetitions
+
auto suffix = interest.firstSuffix();
auto n_suffixes = interest.numberOfSuffixes();
@@ -278,6 +282,9 @@ TEST_F(InterestTest, AppendSuffixesWithGaps) {
interest.encodeSuffixes();
EXPECT_TRUE(interest.hasManifest());
+ // Decode suffixes from wire format
+ interest.decodeSuffixes();
+
// Check first suffix correctness
auto suffix = interest.firstSuffix();
EXPECT_NE(suffix, nullptr);