aboutsummaryrefslogtreecommitdiffstats
path: root/libtransport/includes/hicn/transport/core
diff options
context:
space:
mode:
Diffstat (limited to 'libtransport/includes/hicn/transport/core')
-rw-r--r--libtransport/includes/hicn/transport/core/CMakeLists.txt4
-rw-r--r--libtransport/includes/hicn/transport/core/connector.h212
-rw-r--r--libtransport/includes/hicn/transport/core/connector_stats.h40
-rw-r--r--libtransport/includes/hicn/transport/core/content_object.h50
-rw-r--r--libtransport/includes/hicn/transport/core/endpoint.h80
-rw-r--r--libtransport/includes/hicn/transport/core/global_object_pool.h122
-rw-r--r--libtransport/includes/hicn/transport/core/interest.h78
-rw-r--r--libtransport/includes/hicn/transport/core/io_module.h127
-rw-r--r--libtransport/includes/hicn/transport/core/name.h6
-rw-r--r--libtransport/includes/hicn/transport/core/packet.h143
-rw-r--r--libtransport/includes/hicn/transport/core/payload_type.h3
-rw-r--r--libtransport/includes/hicn/transport/core/prefix.h8
12 files changed, 763 insertions, 110 deletions
diff --git a/libtransport/includes/hicn/transport/core/CMakeLists.txt b/libtransport/includes/hicn/transport/core/CMakeLists.txt
index cb10745ff..2553b7dcd 100644
--- a/libtransport/includes/hicn/transport/core/CMakeLists.txt
+++ b/libtransport/includes/hicn/transport/core/CMakeLists.txt
@@ -20,6 +20,10 @@ list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/packet.h
${CMAKE_CURRENT_SOURCE_DIR}/payload_type.h
${CMAKE_CURRENT_SOURCE_DIR}/prefix.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/io_module.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/connector.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/endpoint.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/global_object_pool.h
)
set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/core/connector.h b/libtransport/includes/hicn/transport/core/connector.h
new file mode 100644
index 000000000..dcf38cdc8
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/connector.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/core/connector_stats.h>
+#include <hicn/transport/core/content_object.h>
+#include <hicn/transport/core/endpoint.h>
+#include <hicn/transport/core/global_object_pool.h>
+#include <hicn/transport/core/interest.h>
+#include <hicn/transport/core/packet.h>
+#include <hicn/transport/portability/platform.h>
+#include <hicn/transport/utils/membuf.h>
+#include <hicn/transport/utils/object_pool.h>
+#include <hicn/transport/utils/ring_buffer.h>
+#include <hicn/transport/utils/shared_ptr_utils.h>
+
+#include <deque>
+#include <functional>
+
+namespace transport {
+
+namespace core {
+
+class Connector : public std::enable_shared_from_this<Connector> {
+ public:
+ enum class Type : uint8_t {
+ SOCKET_CONNECTOR,
+ MEMIF_CONNECTOR,
+ LOOPBACK_CONNECTOR,
+ };
+
+ enum class State : std::uint8_t {
+ CLOSED,
+ CONNECTING,
+ CONNECTED,
+ };
+
+ enum class Role : std::uint8_t { CONSUMER, PRODUCER };
+
+ public:
+ static constexpr std::size_t queue_size = 4096;
+ static constexpr std::uint32_t invalid_connector = ~0;
+
+#ifdef LINUX
+ static constexpr std::uint16_t max_burst = 256;
+#endif
+
+ using Ptr = std::shared_ptr<Connector>;
+ using PacketQueue = std::deque<Packet::Ptr>;
+ using PacketReceivedCallback = std::function<void(
+ Connector *, utils::MemBuf &, const std::error_code &)>;
+ using PacketSentCallback =
+ std::function<void(Connector *, const std::error_code &)>;
+ using OnCloseCallback = std::function<void(Connector *)>;
+ using OnReconnectCallback = std::function<void(Connector *)>;
+ using Id = std::uint64_t;
+
+ template <typename ReceiveCallback, typename SentCallback, typename OnClose,
+ typename OnReconnect>
+ Connector(ReceiveCallback &&receive_callback, SentCallback &&packet_sent,
+ OnClose &&close_callback, OnReconnect &&on_reconnect)
+ : receive_callback_(std::forward<ReceiveCallback &&>(receive_callback)),
+ sent_callback_(std::forward<SentCallback &&>(packet_sent)),
+ on_close_callback_(std::forward<OnClose &&>(close_callback)),
+ on_reconnect_callback_(std::forward<OnReconnect &&>(on_reconnect)),
+ state_(State::CLOSED),
+ connector_id_(invalid_connector) {}
+
+ virtual ~Connector(){};
+
+ template <typename ReceiveCallback>
+ void setReceiveCallback(ReceiveCallback &&callback) {
+ receive_callback_ = std::forward<ReceiveCallback &&>(callback);
+ }
+
+ template <typename SentCallback>
+ void setSentCallback(SentCallback &&callback) {
+ sent_callback_ = std::forward<SentCallback &&>(callback);
+ }
+
+ template <typename OnClose>
+ void setOnCloseCallback(OnClose &&callback) {
+ on_close_callback_ = std::forward<OnClose &&>(callback);
+ }
+
+ template <typename OnReconnect>
+ void setReconnectCallback(const OnReconnect &&callback) {
+ on_reconnect_callback_ = std::forward<OnReconnect>(callback);
+ }
+
+ const PacketReceivedCallback &getReceiveCallback() const {
+ return receive_callback_;
+ }
+
+ const PacketSentCallback &getSentCallback() { return sent_callback_; }
+
+ const OnCloseCallback &getOnCloseCallback() { return on_close_callback_; }
+
+ const OnReconnectCallback &getOnReconnectCallback() {
+ return on_reconnect_callback_;
+ }
+
+ virtual void send(Packet &packet) = 0;
+
+ virtual void send(const uint8_t *packet, std::size_t len) = 0;
+
+ virtual void close() = 0;
+
+ virtual State state() { return state_; };
+
+ virtual bool isConnected() { return state_ == State::CONNECTED; }
+
+ void setConnectorId(Id connector_id) { connector_id_ = connector_id; }
+
+ Id getConnectorId() { return connector_id_; }
+
+ void setConnectorName(std::string connector_name) {
+ connector_name_ = connector_name;
+ }
+
+ std::string getConnectorName() { return connector_name_; }
+
+ Endpoint getLocalEndpoint() { return local_endpoint_; }
+
+ Endpoint getRemoteEndpoint() { return remote_endpoint_; }
+
+ void setRole(Role r) { role_ = r; }
+
+ Role getRole() { return role_; }
+
+ static utils::MemBuf::Ptr getPacketFromBuffer(uint8_t *buffer,
+ std::size_t size) {
+ utils::MemBuf::Ptr ret;
+
+ auto format = Packet::getFormatFromBuffer(buffer, size);
+
+ if (TRANSPORT_EXPECT_TRUE(format != HF_UNSPEC && !_is_icmp(format))) {
+ if (Packet::isInterest(buffer)) {
+ ret = core::PacketManager<>::getInstance()
+ .getPacketFromExistingBuffer<Interest>(buffer, size);
+ } else {
+ ret = core::PacketManager<>::getInstance()
+ .getPacketFromExistingBuffer<ContentObject>(buffer, size);
+ }
+ } else {
+ ret = core::PacketManager<>::getInstance().getMemBuf(buffer, size);
+ }
+
+ return ret;
+ }
+
+ static std::pair<uint8_t *, std::size_t> getRawBuffer() {
+ return core::PacketManager<>::getInstance().getRawBuffer();
+ }
+
+ protected:
+ inline void sendSuccess(const utils::MemBuf &packet) {
+ stats_.tx_packets_.fetch_add(1, std::memory_order_relaxed);
+ stats_.tx_bytes_.fetch_add(packet.length(), std::memory_order_relaxed);
+ }
+
+ inline void receiveSuccess(const utils::MemBuf &packet) {
+ stats_.rx_packets_.fetch_add(1, std::memory_order_relaxed);
+ stats_.rx_bytes_.fetch_add(packet.length(), std::memory_order_relaxed);
+ }
+
+ inline void sendFailed() {
+ stats_.drops_.fetch_add(1, std::memory_order_relaxed);
+ }
+
+ protected:
+ PacketQueue output_buffer_;
+
+ // Connector events
+ PacketReceivedCallback receive_callback_;
+ PacketSentCallback sent_callback_;
+ OnCloseCallback on_close_callback_;
+ OnReconnectCallback on_reconnect_callback_;
+
+ // Connector state
+ std::atomic<State> state_;
+ Id connector_id_;
+
+ // Endpoints
+ Endpoint local_endpoint_;
+ Endpoint remote_endpoint_;
+
+ // Connector name
+ std::string connector_name_;
+
+ // Connector role
+ Role role_;
+
+ // Stats
+ AtomicConnectorStats stats_;
+};
+
+} // namespace core
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/core/connector_stats.h b/libtransport/includes/hicn/transport/core/connector_stats.h
new file mode 100644
index 000000000..1985331e9
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/connector_stats.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019 Cisco and/or its affiliates.
+ */
+
+#pragma once
+
+#include <atomic>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace transport {
+namespace core {
+
+struct AtomicConnectorStats {
+ AtomicConnectorStats()
+ : tx_packets_(0), tx_bytes_(0), rx_packets_(0), rx_bytes_(0), drops_(0) {}
+ std::atomic<uint64_t> tx_packets_;
+ std::atomic<uint64_t> tx_bytes_;
+ std::atomic<uint64_t> rx_packets_;
+ std::atomic<uint64_t> rx_bytes_;
+ std::atomic<uint64_t> drops_;
+};
+
+struct ConnectorStats {
+ ConnectorStats()
+ : tx_packets_(0), tx_bytes_(0), rx_packets_(0), rx_bytes_(0), drops_(0) {}
+ std::uint64_t tx_packets_;
+ std::uint64_t tx_bytes_;
+ std::uint64_t rx_packets_;
+ std::uint64_t rx_bytes_;
+ std::uint64_t drops_;
+};
+
+using TableEntry = std::tuple<std::string, std::uint64_t, std::uint64_t,
+ std::uint64_t, std::uint64_t, std::uint64_t>;
+using StatisticTable = std::vector<TableEntry>;
+
+} // namespace core
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/core/content_object.h b/libtransport/includes/hicn/transport/core/content_object.h
index 822790e56..805bc814c 100644
--- a/libtransport/includes/hicn/transport/core/content_object.h
+++ b/libtransport/includes/hicn/transport/core/content_object.h
@@ -17,6 +17,7 @@
#include <hicn/transport/core/name.h>
#include <hicn/transport/core/packet.h>
+#include <hicn/transport/utils/shared_ptr_utils.h>
namespace transport {
@@ -27,24 +28,53 @@ namespace core {
class ContentObject : public Packet {
public:
- using Ptr = utils::ObjectPool<ContentObject>::Ptr;
+ using Ptr = std::shared_ptr<ContentObject>;
using HICNContentObject = hicn_header_t;
- ContentObject(Packet::Format format = HF_INET6_TCP);
+ ContentObject(Packet::Format format = HF_INET6_TCP,
+ std::size_t additional_header_size = 0);
- ContentObject(const Name &name, Packet::Format format = HF_INET6_TCP);
+ ContentObject(const Name &name, Packet::Format format = HF_INET6_TCP,
+ std::size_t additional_header_size = 0);
- ContentObject(const Name &name, hicn_format_t format, const uint8_t *payload,
+ ContentObject(const Name &name, hicn_format_t format,
+ std::size_t additional_header_size, const uint8_t *payload,
std::size_t payload_size);
- ContentObject(const uint8_t *buffer, std::size_t size);
- ContentObject(MemBufPtr &&buffer);
-
- ContentObject(const ContentObject &content_object) = delete;
+ template <typename... Args>
+ ContentObject(CopyBufferOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {
+ if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) <
+ 0) {
+ throw errors::MalformedPacketException();
+ }
+ }
+
+ template <typename... Args>
+ ContentObject(WrapBufferOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {
+ if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) <
+ 0) {
+ throw errors::MalformedPacketException();
+ }
+ }
+
+ template <typename... Args>
+ ContentObject(CreateOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {
+ if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) <
+ 0) {
+ throw errors::MalformedPacketException();
+ }
+ }
+
+ ContentObject(const ContentObject &content_object);
+
+ ContentObject &operator=(const ContentObject &other);
ContentObject(ContentObject &&content_object);
- ~ContentObject() override;
+ ~ContentObject();
const Name &getName() const override;
@@ -66,6 +96,8 @@ class ContentObject : public Packet {
uint32_t getLifetime() const override;
+ auto shared_from_this() { return utils::shared_from(this); }
+
private:
void resetForHash() override;
};
diff --git a/libtransport/includes/hicn/transport/core/endpoint.h b/libtransport/includes/hicn/transport/core/endpoint.h
new file mode 100644
index 000000000..4a19744a7
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/endpoint.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#ifndef ASIO_STANDALONE
+#define ASIO_STANDALONE
+#endif
+#include <asio.hpp>
+
+namespace transport {
+
+namespace core {
+
+const uint16_t INVALID_PORT = 0xffff;
+
+class Endpoint {
+ public:
+ Endpoint() : address_(), port_(INVALID_PORT) {}
+
+ Endpoint(const Endpoint &other)
+ : address_(other.address_), port_(other.port_) {}
+
+ Endpoint(Endpoint &&other)
+ : address_(std::move(other.address_)), port_(other.port_) {}
+
+ Endpoint(std::string ip_address, uint32_t port)
+ : address_(asio::ip::address::from_string(ip_address)), port_(port) {}
+
+ Endpoint(asio::ip::udp::endpoint endpoint)
+ : address_(endpoint.address()), port_(endpoint.port()) {}
+
+ ~Endpoint() = default;
+
+ Endpoint &operator=(const Endpoint &other) {
+ address_ = other.address_;
+ port_ = other.port_;
+ return *this;
+ }
+
+ Endpoint &operator=(Endpoint &&other) {
+ address_ = std::move(other.address_);
+ port_ = std::move(other.port_);
+ return *this;
+ }
+
+#if 0
+ template <typename Ip, typename Port>
+ Endpoint(Ip &&ip_address, Port &&port)
+ : address_(std::forward<Ip &&>(ip_address)),
+ port_(std::forward<Port &&>(port)) {}
+#endif
+
+ asio::ip::address getAddress() { return address_; }
+ uint16_t getPort() { return port_; }
+
+ void setAddress(uint32_t address) {
+ address_ = asio::ip::address(asio::ip::address_v4(address));
+ }
+
+ void setPort(uint16_t port) { port_ = port; }
+
+ private:
+ asio::ip::address address_;
+ uint16_t port_;
+};
+} // namespace core
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/core/global_object_pool.h b/libtransport/includes/hicn/transport/core/global_object_pool.h
new file mode 100644
index 000000000..e0b6e373f
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/global_object_pool.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/core/packet.h>
+#include <hicn/transport/utils/fixed_block_allocator.h>
+#include <hicn/transport/utils/singleton.h>
+
+#include <array>
+#include <mutex>
+
+namespace transport {
+
+namespace core {
+
+template <std::size_t packet_pool_size = 1024, std::size_t chunk_size = 2048>
+class PacketManager
+ : public utils::Singleton<PacketManager<packet_pool_size, chunk_size>> {
+ friend class utils::Singleton<PacketManager<packet_pool_size, chunk_size>>;
+
+ public:
+ using MemoryPool = utils::FixedBlockAllocator<chunk_size, packet_pool_size>;
+ using RawBuffer = std::pair<uint8_t *, std::size_t>;
+
+ struct PacketStorage {
+ std::array<uint8_t, 256> packet_and_shared_ptr;
+ std::max_align_t align;
+ };
+
+ utils::MemBuf::Ptr getMemBuf() {
+ utils::MemBuf *memory = nullptr;
+
+ memory = reinterpret_cast<utils::MemBuf *>(memory_pool_.allocateBlock());
+
+ utils::STLAllocator<utils::MemBuf, MemoryPool> allocator(memory,
+ &memory_pool_);
+ auto offset = offsetof(PacketStorage, align);
+ auto ret = std::allocate_shared<utils::MemBuf>(
+ allocator, utils::MemBuf::WRAP_BUFFER, (uint8_t *)memory + offset, 0,
+ chunk_size - offset);
+ ret->clear();
+
+ return ret;
+ }
+
+ utils::MemBuf::Ptr getMemBuf(uint8_t *buffer, std::size_t length) {
+ auto offset = offsetof(PacketStorage, align);
+ auto memory = buffer - offset;
+ utils::STLAllocator<utils::MemBuf, MemoryPool> allocator(
+ (utils::MemBuf *)memory, &memory_pool_);
+ auto ret = std::allocate_shared<utils::MemBuf>(
+ allocator, utils::MemBuf::WRAP_BUFFER, (uint8_t *)buffer, length,
+ chunk_size - offset);
+
+ return ret;
+ }
+
+ template <
+ typename PacketType, typename... Args,
+ typename = std::enable_if_t<std::is_base_of<Packet, PacketType>::value>>
+ typename PacketType::Ptr getPacket(Args &&...args) {
+ PacketType *memory = nullptr;
+
+ memory = reinterpret_cast<PacketType *>(memory_pool_.allocateBlock());
+ utils::STLAllocator<PacketType, MemoryPool> allocator(memory,
+ &memory_pool_);
+ auto offset = offsetof(PacketStorage, align);
+ auto ret = std::allocate_shared<PacketType>(
+ allocator, PacketType::CREATE, (uint8_t *)memory + offset, 0,
+ chunk_size - offset, std::forward<Args>(args)...);
+
+ return ret;
+ }
+
+ std::pair<uint8_t *, std::size_t> getRawBuffer() {
+ uint8_t *memory = nullptr;
+ memory = reinterpret_cast<uint8_t *>(memory_pool_.allocateBlock());
+
+ auto offset = offsetof(PacketStorage, align);
+ memory += offset;
+
+ return std::make_pair(memory, chunk_size - offset);
+ }
+
+ template <typename PacketType, typename... Args>
+ typename PacketType::Ptr getPacketFromExistingBuffer(uint8_t *buffer,
+ std::size_t length,
+ Args &&...args) {
+ auto offset = offsetof(PacketStorage, align);
+ auto memory = reinterpret_cast<PacketType *>(buffer - offset);
+ utils::STLAllocator<PacketType, MemoryPool> allocator(memory,
+ &memory_pool_);
+ auto ret = std::allocate_shared<PacketType>(
+ allocator, PacketType::WRAP_BUFFER, (uint8_t *)buffer, length,
+ chunk_size - offset, std::forward<Args>(args)...);
+
+ return ret;
+ }
+
+ private:
+ PacketManager(std::size_t size = packet_pool_size)
+ : memory_pool_(MemoryPool::getInstance()), size_(0) {}
+ MemoryPool &memory_pool_;
+ std::atomic<size_t> size_;
+};
+
+} // end namespace core
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/core/interest.h b/libtransport/includes/hicn/transport/core/interest.h
index c572afbff..b41b0c94a 100644
--- a/libtransport/includes/hicn/transport/core/interest.h
+++ b/libtransport/includes/hicn/transport/core/interest.h
@@ -17,6 +17,9 @@
#include <hicn/transport/core/name.h>
#include <hicn/transport/core/packet.h>
+#include <hicn/transport/utils/shared_ptr_utils.h>
+
+#include <set>
namespace transport {
@@ -24,25 +27,57 @@ namespace core {
class Interest
: public Packet /*, public std::enable_shared_from_this<Interest>*/ {
- public:
- using Ptr = utils::ObjectPool<Interest>::Ptr;
-
- Interest(Packet::Format format = HF_INET6_TCP);
-
- Interest(const Name &interest_name, Packet::Format format = HF_INET6_TCP);
+ private:
+ struct InterestManifestHeader {
+ /* This can be 16 bits, but we use 32 bits for alignment */
+ uint32_t n_suffixes;
+ /* Followed by the list of prefixes to ask */
+ /* ... */
+ };
- Interest(const uint8_t *buffer, std::size_t size);
- Interest(MemBufPtr &&buffer);
+ public:
+ using Ptr = std::shared_ptr<Interest>;
+
+ Interest(Packet::Format format = HF_INET6_TCP,
+ std::size_t additional_header_size = 0);
+
+ Interest(const Name &interest_name, Packet::Format format = HF_INET6_TCP,
+ std::size_t additional_header_size = 0);
+
+ Interest(MemBuf &&buffer);
+
+ template <typename... Args>
+ Interest(CopyBufferOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {
+ if (hicn_interest_get_name(format_, packet_start_,
+ name_.getStructReference()) < 0) {
+ throw errors::MalformedPacketException();
+ }
+ }
+
+ template <typename... Args>
+ Interest(WrapBufferOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {
+ if (hicn_interest_get_name(format_, packet_start_,
+ name_.getStructReference()) < 0) {
+ throw errors::MalformedPacketException();
+ }
+ }
+
+ template <typename... Args>
+ Interest(CreateOp op, Args &&...args)
+ : Packet(op, std::forward<Args>(args)...) {}
+
+ /* Move constructor */
+ Interest(Interest &&other_interest);
- /*
- * Enforce zero-copy.
- */
- Interest(const Interest &other_interest) = delete;
- Interest &operator=(const Interest &other_interest) = delete;
+ /* Copy constructor */
+ Interest(const Interest &other_interest);
- Interest(Interest &&other_interest);
+ /* Assginemnt operator */
+ Interest &operator=(const Interest &other);
- ~Interest() override;
+ ~Interest();
const Name &getName() const override;
@@ -60,8 +95,21 @@ class Interest
uint32_t getLifetime() const override;
+ bool hasManifest();
+
+ void appendSuffix(std::uint32_t suffix);
+
+ void encodeSuffixes();
+
+ uint32_t *firstSuffix();
+
+ uint32_t numberOfSuffixes();
+
+ auto shared_from_this() { return utils::shared_from(this); }
+
private:
void resetForHash() override;
+ std::set<uint32_t> suffix_set_;
};
} // end namespace core
diff --git a/libtransport/includes/hicn/transport/core/io_module.h b/libtransport/includes/hicn/transport/core/io_module.h
new file mode 100644
index 000000000..d4c3bb03a
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/io_module.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/core/connector.h>
+#include <hicn/transport/core/packet.h>
+#include <hicn/transport/core/prefix.h>
+#include <hicn/transport/portability/portability.h>
+#include <hicn/transport/utils/chrono_typedefs.h>
+#include <hicn/transport/utils/membuf.h>
+
+#include <deque>
+
+#ifndef ASIO_STANDALONE
+#define ASIO_STANDALONE
+#endif
+#include <asio/io_service.hpp>
+
+namespace transport {
+
+namespace core {
+
+typedef struct {
+ uint64_t rx_packets;
+ uint64_t tx_packets;
+ uint64_t rx_bytes;
+ uint64_t tx_bytes;
+ uint64_t rx_errors;
+ uint64_t tx_errors;
+} Counters;
+
+class Connector;
+
+class IoModule {
+ protected:
+ IoModule()
+ : inet_address_({}),
+ inet6_address_({}),
+ mtu_(1500),
+ output_interface_(""),
+ content_store_reserved_(5000) {
+ inet_address_.v4.as_u32 = htonl(0x7f00001);
+ inet6_address_.v6.as_u8[15] = 0x01;
+ }
+
+ public:
+ static IoModule *load(const char *);
+ static bool unload(IoModule *);
+
+ public:
+ virtual ~IoModule();
+
+ virtual void connect(bool is_consumer = true) = 0;
+
+ virtual bool isConnected() = 0;
+
+ virtual void init(Connector::PacketReceivedCallback &&receive_callback,
+ Connector::OnReconnectCallback &&reconnect_callback,
+ asio::io_service &io_service,
+ const std::string &app_name = "Libtransport") = 0;
+
+ virtual void registerRoute(const Prefix &prefix) = 0;
+
+ virtual std::uint32_t getMtu() = 0;
+
+ virtual bool isControlMessage(const uint8_t *message) = 0;
+
+ virtual void processControlMessageReply(utils::MemBuf &packet_buffer) = 0;
+
+ virtual void closeConnection() = 0;
+
+ virtual void send(Packet &packet) {
+ counters_.tx_packets++;
+ counters_.tx_bytes += packet.payloadSize() + packet.headerSize();
+
+ if (_is_ipv4(packet.getFormat())) {
+ packet.setLocator(inet_address_);
+ } else {
+ packet.setLocator(inet6_address_);
+ }
+ }
+
+ virtual void send(const uint8_t *packet, std::size_t len) = 0;
+
+ void setContentStoreSize(uint32_t cs_size) {
+ content_store_reserved_ = cs_size;
+ }
+
+ uint32_t getContentStoreSize() const { return content_store_reserved_; }
+
+ void setOutputInterface(const std::string &interface) {
+ output_interface_ = interface;
+ }
+
+ const std::string &getOutputInterface() { return output_interface_; }
+
+#ifndef ANDROID
+ private:
+ void *handle_;
+#endif
+
+ protected:
+ ip_address_t inet_address_;
+ ip_address_t inet6_address_;
+ uint16_t mtu_;
+ std::string output_interface_;
+ uint32_t content_store_reserved_;
+ Counters counters_;
+};
+
+extern "C" IoModule *createModule();
+
+} // namespace core
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/core/name.h b/libtransport/includes/hicn/transport/core/name.h
index ea72797ad..033582289 100644
--- a/libtransport/includes/hicn/transport/core/name.h
+++ b/libtransport/includes/hicn/transport/core/name.h
@@ -77,6 +77,8 @@ class Name {
operator bool() const;
+ bool isValid() const;
+
std::string toString() const;
bool equals(const Name &name, bool consider_segment = true) const;
@@ -125,14 +127,14 @@ struct compare2 {};
template <>
struct compare2<transport::core::Name> {
- size_t operator()(const transport::core::Name &name1, const transport::core::Name &name2) const;
+ size_t operator()(const transport::core::Name &name1,
+ const transport::core::Name &name2) const;
};
} // end namespace core
} // end namespace transport
-
namespace std {
template <>
struct hash<transport::core::Name> {
diff --git a/libtransport/includes/hicn/transport/core/packet.h b/libtransport/includes/hicn/transport/core/packet.h
index 91f957964..68daea841 100644
--- a/libtransport/includes/hicn/transport/core/packet.h
+++ b/libtransport/includes/hicn/transport/core/packet.h
@@ -19,21 +19,15 @@
#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>
-#include <hicn/transport/security/key_id.h>
+#include <hicn/transport/auth/crypto_hasher.h>
+#include <hicn/transport/auth/crypto_suite.h>
+#include <hicn/transport/auth/key_id.h>
#include <hicn/transport/utils/branch_prediction.h>
#include <hicn/transport/utils/log.h>
#include <hicn/transport/utils/membuf.h>
#include <hicn/transport/utils/object_pool.h>
-namespace utils {
-class Signer;
-class Verifier;
-} // namespace utils
-
namespace transport {
-
namespace core {
/*
@@ -45,11 +39,13 @@ namespace core {
* \_______________________________________|
*/
-class Packet : public std::enable_shared_from_this<Packet> {
- friend class utils::Signer;
- friend class utils::Verifier;
+class Packet : public utils::MemBuf,
+ public std::enable_shared_from_this<Packet> {
+ friend class auth::Signer;
+ friend class auth::Verifier;
public:
+ using Ptr = std::shared_ptr<Packet>;
using MemBufPtr = std::shared_ptr<utils::MemBuf>;
using Format = hicn_format_t;
static constexpr size_t default_mtu = 1500;
@@ -59,24 +55,29 @@ class Packet : public std::enable_shared_from_this<Packet> {
* the eventual payload will be added by prepending the payload buffer
* to the buffer chain whose the fist buffer is the header itself.
*/
- Packet(Format format = HF_UNSPEC);
+ Packet(Format format = HF_INET6_TCP, std::size_t additional_header_size = 0);
/**
* Create new IP packet using raw buffer.
*/
- Packet(const uint8_t *buffer, std::size_t size);
- Packet(MemBufPtr &&buffer);
- /*
- * Enforce zero-copy lifestyle.
- */
- Packet(const Packet &other) = delete;
- Packet &operator=(const Packet &other) = delete;
+ /* Copy buffer */
+ Packet(CopyBufferOp, const uint8_t *buffer, std::size_t size);
+ /* Wrap buffer */
+ Packet(WrapBufferOp, uint8_t *buffer, std::size_t length, std::size_t size);
+ /* Create new using pre-allocated buffer */
+ Packet(CreateOp, uint8_t *buffer, std::size_t length, std::size_t size,
+ Format format = HF_INET6_TCP, std::size_t additional_header_size = 0);
+ /* Move MemBuf */
+ Packet(MemBuf &&buffer);
+
+ Packet(Packet &&other);
/*
- * Move constructor.
+ * Copy constructor and assignemnt operators.
*/
- Packet(Packet &&other);
+ Packet(const Packet &other);
+ Packet &operator=(const Packet &other);
friend bool operator==(const Packet &l_packet, const Packet &r_packet);
@@ -98,36 +99,35 @@ class Packet : public std::enable_shared_from_this<Packet> {
static bool isInterest(const uint8_t *buffer);
+ bool isInterest();
+
static Format getFormatFromBuffer(const uint8_t *buffer, std::size_t length) {
Format format = HF_UNSPEC;
-
- if (TRANSPORT_EXPECT_FALSE(
- hicn_packet_get_format((const hicn_header_t *)buffer, &format) <
- 0)) {
- TRANSPORT_LOGE(
- "Error while getting format from packet buffer. Packet will be "
- "discarded.");
- hicn_packet_dump(buffer, length);
- }
-
+ hicn_packet_get_format((const hicn_header_t *)buffer, &format);
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_),
- packet_->length());
+ void reset() {
+ clear();
+ packet_start_ = reinterpret_cast<hicn_header_t *>(writableData());
+ header_offset_ = 0;
+ format_ = HF_UNSPEC;
+ payload_type_ = PayloadType::UNSPECIFIED;
name_.clear();
+
+ if (isChained()) {
+ separateChain(next(), prev());
+ }
}
+ void setFormat(Packet::Format format = HF_INET6_TCP,
+ std::size_t additional_header_size = 0);
+
std::size_t payloadSize() const;
std::size_t headerSize() const;
- const std::shared_ptr<utils::MemBuf> acquireMemBufReference() const;
+ std::shared_ptr<utils::MemBuf> acquireMemBufReference();
virtual const Name &getName() const = 0;
@@ -145,25 +145,8 @@ class Packet : public std::enable_shared_from_this<Packet> {
Packet &appendPayload(std::unique_ptr<utils::MemBuf> &&payload);
- Packet &appendHeader(std::unique_ptr<utils::MemBuf> &&header);
-
- Packet &appendHeader(const uint8_t *buffer, std::size_t length);
-
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 = payloadSize();
-
- return std::make_pair(packet_->data() + header_size, payload_length);
- }
-
Packet &updateLength(std::size_t length = 0);
PayloadType getPayloadType() const;
@@ -174,35 +157,38 @@ class Packet : public std::enable_shared_from_this<Packet> {
void dump() const;
+ static void dump(uint8_t *buffer, std::size_t length);
+
virtual void setLocator(const ip_address_t &locator) = 0;
virtual ip_address_t getLocator() const = 0;
- void setSignatureTimestamp(const uint64_t &timestamp);
+ /**
+ * @brief Set signature timestamp, in milliseconds.
+ */
+ void setSignatureTimestamp(const uint64_t &timestamp_milliseconds);
uint64_t getSignatureTimestamp() const;
- void setValidationAlgorithm(const utils::CryptoSuite &validation_algorithm);
+ void setValidationAlgorithm(const auth::CryptoSuite &validation_algorithm);
- utils::CryptoSuite getValidationAlgorithm() const;
+ auth::CryptoSuite getValidationAlgorithm() const;
- void setKeyId(const utils::KeyId &key_id);
+ void setKeyId(const auth::KeyId &key_id);
- utils::KeyId getKeyId() const;
+ auth::KeyId getKeyId() const;
- virtual utils::CryptoHash computeDigest(
- utils::CryptoHashType algorithm) const;
+ virtual auth::CryptoHash computeDigest(auth::CryptoHashType algorithm) const;
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);
+ uint16_t partial_csum =
+ csum(data() + HICN_V6_TCP_HDRLEN, length() - HICN_V6_TCP_HDRLEN, 0);
+
+ for (utils::MemBuf *current = next(); current != this;
+ current = current->next()) {
+ partial_csum = csum(current->data(), current->length(), ~partial_csum);
}
+
if (hicn_packet_compute_header_checksum(format_, packet_start_,
partial_csum) < 0) {
throw errors::MalformedPacketException();
@@ -234,12 +220,12 @@ class Packet : public std::enable_shared_from_this<Packet> {
Packet &setTTL(uint8_t hops);
uint8_t getTTL() const;
- void separateHeaderPayload();
- void resetPayload();
-
private:
virtual void resetForHash() = 0;
void setSignatureSize(std::size_t size_bytes);
+ void prependPayload(const uint8_t **buffer, std::size_t *size);
+
+ bool authenticationHeader() const { return _is_ah(format_); }
std::size_t getSignatureSize() const {
size_t size_bytes;
@@ -256,12 +242,11 @@ class Packet : public std::enable_shared_from_this<Packet> {
uint8_t *getSignature() const;
protected:
- Name name_;
- MemBufPtr packet_;
hicn_header_t *packet_start_;
- utils::MemBuf *header_head_;
- utils::MemBuf *payload_head_;
+ std::size_t header_offset_;
mutable Format format_;
+ Name name_;
+ mutable PayloadType payload_type_;
static const core::Name base_name;
};
diff --git a/libtransport/includes/hicn/transport/core/payload_type.h b/libtransport/includes/hicn/transport/core/payload_type.h
index fa79db35a..8c918f792 100644
--- a/libtransport/includes/hicn/transport/core/payload_type.h
+++ b/libtransport/includes/hicn/transport/core/payload_type.h
@@ -20,8 +20,9 @@ namespace transport {
namespace core {
enum class PayloadType : uint16_t {
- CONTENT_OBJECT = HPT_DATA,
+ DATA = HPT_DATA,
MANIFEST = HPT_MANIFEST,
+ UNSPECIFIED = HPT_UNSPEC
};
} // end namespace core
diff --git a/libtransport/includes/hicn/transport/core/prefix.h b/libtransport/includes/hicn/transport/core/prefix.h
index c3805f13f..7ef667bc8 100644
--- a/libtransport/includes/hicn/transport/core/prefix.h
+++ b/libtransport/includes/hicn/transport/core/prefix.h
@@ -35,9 +35,9 @@ class Prefix {
Prefix(const core::Name &content_name, uint16_t prefix_length);
- std::unique_ptr<Sockaddr> toSockaddr();
+ std::unique_ptr<Sockaddr> toSockaddr() const;
- uint16_t getPrefixLength();
+ uint16_t getPrefixLength() const;
Prefix &setPrefixLength(uint16_t prefix_length);
@@ -58,13 +58,13 @@ class Prefix {
Prefix &setNetwork(std::string &network);
- int getAddressFamily();
+ int getAddressFamily() const;
Prefix &setAddressFamily(int address_family);
Name makeRandomName() const;
- ip_prefix_t &toIpPrefixStruct();
+ const ip_prefix_t &toIpPrefixStruct() const;
private:
static bool checkPrefixLengthAndAddressFamily(uint16_t prefix_length,