summaryrefslogtreecommitdiffstats
path: root/libtransport/includes
diff options
context:
space:
mode:
authorMauro Sardara <msardara@cisco.com>2020-03-04 16:21:54 +0100
committerMauro Sardara <msardara@cisco.com>2020-03-09 13:02:50 +0000
commitafe807c61372fe2481e73af63c8382af1e1d3011 (patch)
tree181269bc2548bba9eb667df4301ded197183a4cf /libtransport/includes
parent248bfd5ad0ae3cc17bbd3ea3b9a47fa8d075ee58 (diff)
[HICN-540] Optimizations for libhicntransport
Change-Id: I8b46b4eb2ef5488c09041887cc8296a216440f33 Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'libtransport/includes')
-rw-r--r--libtransport/includes/hicn/transport/core/content_object.h2
-rw-r--r--libtransport/includes/hicn/transport/core/interest.h2
-rw-r--r--libtransport/includes/hicn/transport/core/packet.h72
-rw-r--r--libtransport/includes/hicn/transport/utils/CMakeLists.txt1
-rw-r--r--libtransport/includes/hicn/transport/utils/fixed_block_allocator.h136
5 files changed, 204 insertions, 9 deletions
diff --git a/libtransport/includes/hicn/transport/core/content_object.h b/libtransport/includes/hicn/transport/core/content_object.h
index 5af548fe4..822790e56 100644
--- a/libtransport/includes/hicn/transport/core/content_object.h
+++ b/libtransport/includes/hicn/transport/core/content_object.h
@@ -46,8 +46,6 @@ class ContentObject : public Packet {
~ContentObject() override;
- void replace(MemBufPtr &&buffer) override;
-
const Name &getName() const override;
Name &getWritableName() override;
diff --git a/libtransport/includes/hicn/transport/core/interest.h b/libtransport/includes/hicn/transport/core/interest.h
index f0c546a8e..c572afbff 100644
--- a/libtransport/includes/hicn/transport/core/interest.h
+++ b/libtransport/includes/hicn/transport/core/interest.h
@@ -44,8 +44,6 @@ class Interest
~Interest() override;
- void replace(MemBufPtr &&buffer) override;
-
const Name &getName() const override;
Name &getWritableName() override;
diff --git a/libtransport/includes/hicn/transport/core/packet.h b/libtransport/includes/hicn/transport/core/packet.h
index e758aa13e..3ddc4a595 100644
--- a/libtransport/includes/hicn/transport/core/packet.h
+++ b/libtransport/includes/hicn/transport/core/packet.h
@@ -17,6 +17,7 @@
#include <hicn/transport/core/name.h>
#include <hicn/transport/core/payload_type.h>
+#include <hicn/transport/errors/malformed_packet_exception.h>
#include <hicn/transport/portability/portability.h>
#include <hicn/transport/security/crypto_hasher.h>
#include <hicn/transport/security/crypto_suite.h>
@@ -81,7 +82,12 @@ class Packet : public std::enable_shared_from_this<Packet> {
virtual ~Packet();
static std::size_t getHeaderSizeFromFormat(Format format,
- std::size_t signature_size = 0);
+ std::size_t signature_size = 0) {
+ std::size_t header_length;
+ hicn_packet_get_header_length_from_format(format, &header_length);
+ int is_ah = _is_ah(format);
+ return is_ah * (header_length + signature_size) + (!is_ah) * header_length;
+ }
static std::size_t getHeaderSizeFromBuffer(Format format,
const uint8_t *buffer);
@@ -91,9 +97,26 @@ class Packet : public std::enable_shared_from_this<Packet> {
static bool isInterest(const uint8_t *buffer);
- static Format getFormatFromBuffer(const uint8_t *buffer);
+ static Format getFormatFromBuffer(const uint8_t *buffer) {
+ Format format = HF_UNSPEC;
- virtual void replace(MemBufPtr &&buffer);
+ if (TRANSPORT_EXPECT_FALSE(
+ hicn_packet_get_format((const hicn_header_t *)buffer, &format) <
+ 0)) {
+ throw errors::MalformedPacketException();
+ }
+
+ return format;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void replace(MemBufPtr &&buffer) {
+ packet_ = std::move(buffer);
+ packet_start_ = reinterpret_cast<hicn_header_t *>(packet_->writableData());
+ header_head_ = packet_.get();
+ payload_head_ = nullptr;
+ format_ = getFormatFromBuffer(reinterpret_cast<uint8_t *>(packet_start_));
+ name_.clear();
+ }
std::size_t payloadSize() const;
@@ -123,6 +146,19 @@ class Packet : public std::enable_shared_from_this<Packet> {
std::unique_ptr<utils::MemBuf> getPayload() const;
+ std::pair<const uint8_t *, std::size_t> getPayloadReference() const {
+ int signature_size = 0;
+ if (_is_ah(format_)) {
+ signature_size = (uint32_t)getSignatureSize();
+ }
+
+ auto header_size = getHeaderSizeFromFormat(format_, signature_size);
+ auto payload_length = packet_->length() - header_size;
+
+ return std::make_pair(packet_->data() + header_size,
+ payload_length);
+ }
+
Packet &updateLength(std::size_t length = 0);
PayloadType getPayloadType() const;
@@ -152,7 +188,21 @@ class Packet : public std::enable_shared_from_this<Packet> {
virtual utils::CryptoHash computeDigest(
utils::CryptoHashType algorithm) const;
- void setChecksum();
+ void setChecksum() {
+ uint16_t partial_csum = 0;
+
+ for (utils::MemBuf *current = header_head_->next();
+ current && current != header_head_; current = current->next()) {
+ if (partial_csum != 0) {
+ partial_csum = ~partial_csum;
+ }
+ partial_csum = csum(current->data(), current->length(), partial_csum);
+ }
+ if (hicn_packet_compute_header_checksum(format_, packet_start_,
+ partial_csum) < 0) {
+ throw errors::MalformedPacketException();
+ }
+ }
bool checkIntegrity() const;
@@ -184,7 +234,19 @@ class Packet : public std::enable_shared_from_this<Packet> {
private:
virtual void resetForHash() = 0;
void setSignatureSize(std::size_t size_bytes);
- std::size_t getSignatureSize() const;
+
+ std::size_t getSignatureSize() const {
+ size_t size_bytes;
+ int ret =
+ hicn_packet_get_signature_size(format_, packet_start_, &size_bytes);
+
+ if (ret < 0) {
+ throw errors::RuntimeException("Packet without Authentication Header.");
+ }
+
+ return size_bytes;
+ }
+
uint8_t *getSignature() const;
void separateHeaderPayload();
diff --git a/libtransport/includes/hicn/transport/utils/CMakeLists.txt b/libtransport/includes/hicn/transport/utils/CMakeLists.txt
index 396bd06d6..38ecc3d37 100644
--- a/libtransport/includes/hicn/transport/utils/CMakeLists.txt
+++ b/libtransport/includes/hicn/transport/utils/CMakeLists.txt
@@ -28,6 +28,7 @@ list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/object_pool.h
${CMAKE_CURRENT_SOURCE_DIR}/membuf.h
${CMAKE_CURRENT_SOURCE_DIR}/spinlock.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/fixed_block_allocator.h
)
if(NOT WIN32)
diff --git a/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h b/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h
new file mode 100644
index 000000000..1ade1516e
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2019 Cisco and/or its affiliates.
+ */
+
+#pragma once
+
+#include <hicn/transport/portability/c_portability.h>
+#include <hicn/transport/utils/spinlock.h>
+
+#include <stdint.h>
+#include <cstdlib>
+#include <memory>
+#include <cassert>
+
+namespace utils {
+template <std::size_t DEFAULT_SIZE = 512, std::size_t OBJECTS = 4096>
+class FixedBlockAllocator {
+ FixedBlockAllocator(std::size_t size = DEFAULT_SIZE,
+ std::size_t objects = OBJECTS)
+ : block_size_(size < sizeof(void*) ? sizeof(long*) : size),
+ object_size_(size),
+ max_objects_(objects),
+ p_head_(NULL),
+ pool_index_(0),
+ block_count_(0),
+ blocks_in_use_(0),
+ allocations_(0),
+ deallocations_(0) {
+ p_pool_ = (uint8_t*)new uint8_t[block_size_ * max_objects_];
+ }
+
+ public:
+ static FixedBlockAllocator* getInstance() {
+ if (!instance_) {
+ instance_ = std::unique_ptr<FixedBlockAllocator>(
+ new FixedBlockAllocator(DEFAULT_SIZE, OBJECTS));
+ }
+
+ return instance_.get();
+ }
+
+ ~FixedBlockAllocator() { delete[] p_pool_; }
+
+ TRANSPORT_ALWAYS_INLINE void* allocateBlock(size_t size = DEFAULT_SIZE) {
+ assert(size <= DEFAULT_SIZE);
+ uint32_t index;
+
+ void* p_block = pop();
+ if (!p_block) {
+ if (pool_index_ < max_objects_) {
+ {
+ SpinLock::Acquire locked(lock_);
+ index = pool_index_++;
+ }
+ p_block = (void*)(p_pool_ + (index * block_size_));
+ } else {
+ // TODO Consider increasing pool here instead of throwing an exception
+ throw std::runtime_error("No more memory available from packet pool!");
+ }
+ }
+
+ blocks_in_use_++;
+ allocations_++;
+
+ return p_block;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void deallocateBlock(void* pBlock) {
+ push(pBlock);
+ {
+ SpinLock::Acquire locked(lock_);
+ blocks_in_use_--;
+ deallocations_++;
+ }
+ }
+
+ TRANSPORT_ALWAYS_INLINE std::size_t blockSize() { return block_size_; }
+
+ TRANSPORT_ALWAYS_INLINE uint32_t blockCount() { return block_count_; }
+
+ TRANSPORT_ALWAYS_INLINE uint32_t blocksInUse() { return blocks_in_use_; }
+
+ TRANSPORT_ALWAYS_INLINE uint32_t allocations() { return allocations_; }
+
+ TRANSPORT_ALWAYS_INLINE uint32_t deallocations() { return deallocations_; }
+
+ private:
+ TRANSPORT_ALWAYS_INLINE void push(void* p_memory) {
+ Block* p_block = (Block*)p_memory;
+ {
+ SpinLock::Acquire locked(lock_);
+ p_block->p_next = p_head_;
+ p_head_ = p_block;
+ }
+ }
+
+ TRANSPORT_ALWAYS_INLINE void* pop() {
+ Block* p_block = nullptr;
+
+ {
+ SpinLock::Acquire locked(lock_);
+ if (p_head_) {
+ p_block = p_head_;
+ p_head_ = p_head_->p_next;
+ }
+ }
+
+ return (void*)p_block;
+ }
+
+ struct Block {
+ Block* p_next;
+ };
+
+ static std::unique_ptr<FixedBlockAllocator> instance_;
+
+ const std::size_t block_size_;
+ const std::size_t object_size_;
+ const std::size_t max_objects_;
+
+ Block* p_head_;
+ uint8_t* p_pool_;
+ uint32_t pool_index_;
+ uint32_t block_count_;
+ uint32_t blocks_in_use_;
+ uint32_t allocations_;
+ uint32_t deallocations_;
+
+ SpinLock lock_;
+};
+
+template <std::size_t A, std::size_t B>
+std::unique_ptr<FixedBlockAllocator<A, B>>
+ FixedBlockAllocator<A, B>::instance_ = nullptr;
+
+} // namespace utils \ No newline at end of file