diff options
author | Mauro Sardara <msardara@cisco.com> | 2022-07-08 16:10:13 +0000 |
---|---|---|
committer | Mauro Sardara <msardara@cisco.com> | 2022-08-10 11:57:10 +0200 |
commit | 8f0a8bf572b9b8123121338a31462440bad65857 (patch) | |
tree | ecac67f0ad005b2eb0a1bd25c8f242497ffddea1 | |
parent | 8d27045832427a0ea345f48bfb2c42f46a357af1 (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.dev | 13 | ||||
-rw-r--r-- | ctrl/libhicnctrl/src/modules/CMakeLists.txt | 18 | ||||
-rw-r--r-- | hicn-light/src/hicn/core/forwarder.c | 16 | ||||
-rw-r--r-- | hicn-plugin/src/hicn.h | 7 | ||||
-rw-r--r-- | hicn-plugin/src/interest_pcslookup_node.c | 6 | ||||
-rw-r--r-- | hicn-plugin/src/parser.h | 4 | ||||
-rw-r--r-- | lib/includes/hicn/common.h | 58 | ||||
-rw-r--r-- | lib/includes/hicn/interest_manifest.h | 91 | ||||
-rw-r--r-- | lib/includes/hicn/util/bitmap.h | 48 | ||||
-rw-r--r-- | lib/includes/hicn/util/types.h | 8 | ||||
-rw-r--r-- | lib/src/protocol/ah.c | 4 | ||||
-rw-r--r-- | lib/src/test/test_interest_manifest.cc | 117 | ||||
-rw-r--r-- | libtransport/includes/hicn/transport/core/interest.h | 2 | ||||
-rw-r--r-- | libtransport/src/core/interest.cc | 31 | ||||
-rw-r--r-- | libtransport/src/test/test_interest.cc | 7 |
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); |