diff options
Diffstat (limited to 'libtransport/includes/hicn/transport/core')
13 files changed, 925 insertions, 248 deletions
diff --git a/libtransport/includes/hicn/transport/core/CMakeLists.txt b/libtransport/includes/hicn/transport/core/CMakeLists.txt index cb10745ff..34048d93a 100644 --- a/libtransport/includes/hicn/transport/core/CMakeLists.txt +++ b/libtransport/includes/hicn/transport/core/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# 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: @@ -11,15 +11,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.5 FATAL_ERROR) - list(APPEND HEADER_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/asio_wrapper.h ${CMAKE_CURRENT_SOURCE_DIR}/content_object.h ${CMAKE_CURRENT_SOURCE_DIR}/interest.h ${CMAKE_CURRENT_SOURCE_DIR}/name.h ${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/asio_wrapper.h b/libtransport/includes/hicn/transport/core/asio_wrapper.h new file mode 100644 index 000000000..41b660587 --- /dev/null +++ b/libtransport/includes/hicn/transport/core/asio_wrapper.h @@ -0,0 +1,31 @@ +/* + * 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/portability/portability.h> + +TRANSPORT_PUSH_WARNING +TRANSPORT_CLANG_DISABLE_WARNING("-Wdeprecated-declarations") + +#ifndef ASIO_STANDALONE +#define ASIO_STANDALONE +#endif +#ifdef __APPLE__ +TRANSPORT_CLANG_DISABLE_WARNING("-Wshorten-64-to-32") +#endif +#include <asio.hpp> + +TRANSPORT_POP_WARNING diff --git a/libtransport/includes/hicn/transport/core/connector.h b/libtransport/includes/hicn/transport/core/connector.h new file mode 100644 index 000000000..7882b285d --- /dev/null +++ b/libtransport/includes/hicn/transport/core/connector.h @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2021-2022 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 <glog/logging.h> +#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> +#include <system_error> + +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 }; + + static constexpr std::size_t queue_size = 4096; + static constexpr std::uint32_t invalid_connector = ~0; + static constexpr std::uint32_t max_reconnection_reattempts = 5; + static constexpr std::uint16_t max_burst = 256; + + using Ptr = std::shared_ptr<Connector>; + using ReceptionBuffer = std::vector<utils::MemBuf::Ptr>; + using PacketQueue = std::deque<utils::MemBuf::Ptr>; + using PacketReceivedCallback = std::function<void( + Connector *, const ReceptionBuffer &, 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 *, const std::error_code &)>; + 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)) {} + + 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(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 utils::MemBuf::Ptr &buffer) = 0; + + virtual void receive(const std::vector<utils::MemBuf::Ptr> &buffers) { + receive_callback_(this, buffers, std::make_error_code(std::errc())); + } + + virtual void reconnect() { + on_reconnect_callback_(this, std::make_error_code(std::errc())); + } + + 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(const std::string &connector_name) { + connector_name_ = connector_name; + } + + std::string getConnectorName() const { return connector_name_; } + + template <typename EP> + void setLocalEndpoint(EP &&endpoint) { + local_endpoint_ = std::forward<EP>(endpoint); + } + + Endpoint getLocalEndpoint() const { return local_endpoint_; } + + Endpoint getRemoteEndpoint() const { return remote_endpoint_; } + + void setRole(Role r) { role_ = r; } + + Role getRole() const { return role_; } + + static utils::MemBuf::Ptr getPacketFromBuffer(uint8_t *buffer, + std::size_t size) { + utils::MemBuf::Ptr ret; + + hicn_packet_buffer_t pkbuf; + hicn_packet_set_buffer(&pkbuf, buffer, size, size); + hicn_packet_analyze(&pkbuf); + hicn_packet_type_t type = hicn_packet_get_type(&pkbuf); + + // XXX reuse pkbuf when creating the packet, to avoid reanalyzing it + + switch (type) { + case HICN_PACKET_TYPE_INTEREST: + ret = core::PacketManager<>::getInstance() + .getPacketFromExistingBuffer<Interest>(buffer, size); + break; + case HICN_PACKET_TYPE_DATA: + ret = core::PacketManager<>::getInstance() + .getPacketFromExistingBuffer<ContentObject>(buffer, size); + break; + default: + ret = core::PacketManager<>::getInstance().getMemBuf(buffer, size); + break; + } + + 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_ = State::CLOSED; + Id connector_id_ = invalid_connector; + + // Endpoints + Endpoint local_endpoint_; + Endpoint remote_endpoint_; + + // Connector name + std::string connector_name_; + + // Connector role + Role role_; + + // Stats + AtomicConnectorStats stats_; + + // Connection attempts + std::uint32_t connection_reattempts_ = 0; +}; + +} // 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..fff370d02 --- /dev/null +++ b/libtransport/includes/hicn/transport/core/connector_stats.h @@ -0,0 +1,51 @@ +/* + * 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 <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..3d6d98c48 100644 --- a/libtransport/includes/hicn/transport/core/content_object.h +++ b/libtransport/includes/hicn/transport/core/content_object.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 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: @@ -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,49 @@ namespace core { class ContentObject : public Packet { public: - using Ptr = utils::ObjectPool<ContentObject>::Ptr; - using HICNContentObject = hicn_header_t; + using Ptr = std::shared_ptr<ContentObject>; + using HICNContentObject = u8; - ContentObject(Packet::Format format = HF_INET6_TCP); + ContentObject(Packet::Format format, std::size_t additional_header_size = 0); - ContentObject(const Name &name, Packet::Format format = HF_INET6_TCP); + ContentObject(const Name &name, Packet::Format format, + std::size_t additional_header_size = 0); - ContentObject(const Name &name, hicn_format_t format, const uint8_t *payload, + ContentObject(const Name &name, hicn_packet_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(&pkbuf_, &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(&pkbuf_, &name_.getStructReference()) < 0) { + throw errors::MalformedPacketException(); + } + } + + template <typename... Args> + ContentObject(CreateOp op, Args &&...args) + : Packet(op, HICN_PACKET_TYPE_DATA, std::forward<Args>(args)...) { + if (hicn_data_get_name(&pkbuf_, &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; @@ -52,20 +78,24 @@ class ContentObject : public Packet { void setName(const Name &name) override; - void setName(Name &&name) override; - - uint32_t getPathLabel() const; + hicn_path_label_t getPathLabel() const; - ContentObject &setPathLabel(uint32_t path_label); + ContentObject &setPathLabel(hicn_path_label_t path_label); - void setLocator(const ip_address_t &ip_address) override; + void setLocator(const hicn_ip_address_t &ip_address) override; - ip_address_t getLocator() const override; + hicn_ip_address_t getLocator() const override; void setLifetime(uint32_t lifetime) override; uint32_t getLifetime() const override; + auto shared_from_this() { return utils::shared_from(this); } + + bool isLast() const; + + void setLast(); + 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..2278a1759 --- /dev/null +++ b/libtransport/includes/hicn/transport/core/endpoint.h @@ -0,0 +1,83 @@ +/* + * 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/asio_wrapper.h> + +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) { + if (this != &other) { + address_ = other.address_; + port_ = other.port_; + } + + return *this; + } + + Endpoint &operator=(Endpoint &&other) { + if (this != &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..f98df521f --- /dev/null +++ b/libtransport/includes/hicn/transport/core/global_object_pool.h @@ -0,0 +1,126 @@ +/* + * 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::ThreadLocalSingleton< + PacketManager<packet_pool_size, chunk_size>> { + friend class utils::ThreadLocalSingleton< + 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) { + static_assert(sizeof(PacketType) + sizeof(std::shared_ptr<PacketType>) + + sizeof(std::max_align_t) <= + sizeof(PacketStorage::packet_and_shared_ptr)); + 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..270ea7027 100644 --- a/libtransport/includes/hicn/transport/core/interest.h +++ b/libtransport/includes/hicn/transport/core/interest.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 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: @@ -17,32 +17,62 @@ #include <hicn/transport/core/name.h> #include <hicn/transport/core/packet.h> +#include <hicn/transport/utils/shared_ptr_utils.h> + +#include <set> + +extern "C" { +#include <hicn/interest_manifest.h> +} namespace transport { namespace core { +const uint32_t MAX_AGGREGATED_INTEREST = 128; + class Interest : public Packet /*, public std::enable_shared_from_this<Interest>*/ { public: - using Ptr = utils::ObjectPool<Interest>::Ptr; + using Ptr = std::shared_ptr<Interest>; + + Interest(Packet::Format format, std::size_t additional_header_size = 0); + + Interest(const Name &interest_name, Packet::Format format, + std::size_t additional_header_size = 0); - Interest(Packet::Format format = HF_INET6_TCP); + Interest(MemBuf &&buffer); - Interest(const Name &interest_name, Packet::Format format = HF_INET6_TCP); + template <typename... Args> + Interest(CopyBufferOp op, Args &&...args) + : Packet(op, std::forward<Args>(args)...) { + if (hicn_interest_get_name(&pkbuf_, &name_.getStructReference()) < 0) { + throw errors::MalformedPacketException(); + } + } - Interest(const uint8_t *buffer, std::size_t size); - Interest(MemBufPtr &&buffer); + template <typename... Args> + Interest(WrapBufferOp op, Args &&...args) + : Packet(op, std::forward<Args>(args)...) { + if (hicn_interest_get_name(&pkbuf_, &name_.getStructReference()) < 0) { + throw errors::MalformedPacketException(); + } + } - /* - * Enforce zero-copy. - */ - Interest(const Interest &other_interest) = delete; - Interest &operator=(const Interest &other_interest) = delete; + template <typename... Args> + Interest(CreateOp op, Args &&...args) + : Packet(op, HICN_PACKET_TYPE_INTEREST, std::forward<Args>(args)...) {} + /* Move constructor */ Interest(Interest &&other_interest); - ~Interest() override; + /* Copy constructor */ + Interest(const Interest &other_interest); + + /* Assginemnt operator */ + Interest &operator=(const Interest &other); + + ~Interest(); const Name &getName() const override; @@ -50,18 +80,41 @@ class Interest void setName(const Name &name) override; - void setName(Name &&name) override; - - void setLocator(const ip_address_t &ip_address) override; + void setLocator(const hicn_ip_address_t &ip_address) override; - ip_address_t getLocator() const override; + hicn_ip_address_t getLocator() const override; void setLifetime(uint32_t lifetime) override; uint32_t getLifetime() const override; + bool hasManifest() const; + + void appendSuffix(std::uint32_t suffix); + + void encodeSuffixes(); + + void serializeSuffixes(); + + void deserializeSuffixes(); + + uint32_t *firstSuffix(); + + uint32_t numberOfSuffixes(); + + hicn_uword *getRequestBitmap(); + + interest_manifest_header_t *getIntManifestHeader(); + + void setRequestBitmap(const uint32_t *request_bitmap); + + bool isValid(); + + 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..cfaa61975 --- /dev/null +++ b/libtransport/includes/hicn/transport/core/io_module.h @@ -0,0 +1,124 @@ +/* + * 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/asio_wrapper.h> +#include <hicn/transport/core/connector.h> +#include <hicn/transport/core/packet.h> +#include <hicn/transport/core/prefix.h> +#include <hicn/transport/portability/endianess.h> +#include <hicn/transport/portability/portability.h> +#include <hicn/transport/utils/chrono_typedefs.h> +#include <hicn/transport/utils/membuf.h> + +#include <deque> + +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 : utils::NonCopyable { + protected: + IoModule() + : inet_address_({}), + inet6_address_({}), + mtu_(1500), + output_interface_(""), + content_store_reserved_(5000) { + inet_address_.v4.as_u32 = portability::host_to_net(0x7f00001); + inet6_address_.v6.as_u8[15] = 0x01; + } + + public: + static IoModule *load(const char *); + + public: + virtual ~IoModule(); + + virtual void connect(bool is_consumer = true) = 0; + + virtual bool isConnected() = 0; + + virtual void init(Connector::PacketReceivedCallback &&receive_callback, + Connector::PacketSentCallback &&sent_callback, + Connector::OnCloseCallback &&close_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 void sendMapme() {} + + virtual void setForwardingStrategy(const Prefix &prefix, + std::string &strategy){}; + + virtual std::uint32_t getMtu() = 0; + + virtual bool isControlMessage(utils::MemBuf &packet_buffer) = 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 (HICN_PACKET_FORMAT_IS_IPV4(packet.getFormat())) { + packet.setLocator(inet_address_); + } else { + packet.setLocator(inet6_address_); + } + } + + virtual void send(const utils::MemBuf::Ptr &buffer) = 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_; } + + protected: + hicn_ip_address_t inet_address_; + hicn_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..14ea10898 100644 --- a/libtransport/includes/hicn/transport/core/name.h +++ b/libtransport/includes/hicn/transport/core/name.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * 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: @@ -46,12 +46,13 @@ class Name { friend class Packet; friend class ContentObject; friend class Interest; + friend class Prefix; static const uint32_t standard_name_string_length = 100; public: using NameStruct = hicn_name_t; - using Type = hicn_name_type_t; + enum class Type { UNDEFINED, V4, V6 }; Name(); @@ -69,6 +70,8 @@ class Name { Name(const Name &name); + ~Name(); + Name &operator=(const Name &name); bool operator==(const Name &name) const; @@ -77,6 +80,8 @@ class Name { operator bool() const; + bool isValid() const; + std::string toString() const; bool equals(const Name &name, bool consider_segment = true) const; @@ -89,23 +94,22 @@ class Name { uint32_t getSuffix() const; - std::shared_ptr<Sockaddr> getAddress() const; - Name &setSuffix(uint32_t seq_number); - ip_prefix_t toIpAddress() const; + hicn_ip_prefix_t toIpAddress() const; - void copyToDestination(uint8_t *destination, - bool include_suffix = false) const; + std::string getPrefix() const; + + void copyPrefixToDestination(uint8_t *destination) const; int getAddressFamily() const; private: - TRANSPORT_ALWAYS_INLINE const NameStruct *getConstStructReference() const { - return &name_; + TRANSPORT_ALWAYS_INLINE const NameStruct &getConstStructReference() const { + return name_; } - TRANSPORT_ALWAYS_INLINE NameStruct *getStructReference() { return &name_; } + TRANSPORT_ALWAYS_INLINE NameStruct &getStructReference() { return name_; } NameStruct name_; }; @@ -125,14 +129,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 2efd7439d..31d856cd5 100644 --- a/libtransport/includes/hicn/transport/core/packet.h +++ b/libtransport/includes/hicn/transport/core/packet.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 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: @@ -15,24 +15,31 @@ #pragma once +#include <hicn/transport/auth/crypto_hash.h> +#include <hicn/transport/auth/crypto_suite.h> +#include <hicn/transport/auth/key_id.h> #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> -#include <hicn/transport/security/key_id.h> #include <hicn/transport/utils/branch_prediction.h> #include <hicn/transport/utils/membuf.h> #include <hicn/transport/utils/object_pool.h> -namespace utils { -class Signer; -class Verifier; -} // namespace utils +extern "C" { +#ifndef _WIN32 +TRANSPORT_CLANG_DISABLE_WARNING("-Wextern-c-compat") +#endif +#include <hicn/packet.h> +} namespace transport { +namespace auth { +class Signer; +class Verifier; +} // namespace auth + namespace core { /* @@ -44,13 +51,17 @@ 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; + using Format = hicn_packet_format_t; + using Type = hicn_packet_type_t; + static constexpr size_t default_mtu = 1500; /** @@ -58,205 +69,122 @@ 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); - - /** - * 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; - - /* - * Move constructor. - */ + Packet(Type type, Format format, std::size_t additional_header_size = 0); + /* 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, Type type, uint8_t *buffer, std::size_t length, + std::size_t size, Format format, + std::size_t additional_header_size = 0); + + Packet(MemBuf &&buffer); Packet(Packet &&other); + Packet(const Packet &other); + + // Destructor + virtual ~Packet(); + // Operators + Packet &operator=(const Packet &other); friend bool operator==(const Packet &l_packet, const Packet &r_packet); - virtual ~Packet(); + // Cast to MemBuf + std::shared_ptr<utils::MemBuf> acquireMemBufReference(); - static std::size_t getHeaderSizeFromFormat(Format format, - 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); - - static std::size_t getPayloadSizeFromBuffer(Format format, - const uint8_t *buffer); - - static bool isInterest(const uint8_t *buffer); - - static Format getFormatFromBuffer(const uint8_t *buffer) { - Format format = HF_UNSPEC; - - 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(); - } + // Format + Format getFormat() const; + void setFormat(Packet::Format format); - std::size_t payloadSize() const; + void initialize(std::size_t additional_header_size = 0); + void analyze(); - std::size_t headerSize() const; + void initializeType(Packet::Type type); + hicn_packet_type_t getType() const; + void setType(Packet::Type type); - const std::shared_ptr<utils::MemBuf> acquireMemBufReference() const; + void setBuffer(); + // Name virtual const Name &getName() const = 0; - virtual Name &getWritableName() = 0; - virtual void setName(const Name &name) = 0; - virtual void setName(Name &&name) = 0; - + // Lifetime virtual void setLifetime(uint32_t lifetime) = 0; - virtual uint32_t getLifetime() const = 0; - Packet &appendPayload(const uint8_t *buffer, std::size_t length); - - Packet &appendPayload(std::unique_ptr<utils::MemBuf> &&payload); + // Locator + virtual void setLocator(const hicn_ip_address_t &locator) = 0; + virtual hicn_ip_address_t getLocator() const = 0; - Packet &appendHeader(std::unique_ptr<utils::MemBuf> &&header); - - Packet &appendHeader(const uint8_t *buffer, std::size_t length); + // Payload type + PayloadType getPayloadType() const; + Packet &setPayloadType(PayloadType payload_type); + // Payload std::unique_ptr<utils::MemBuf> getPayload() const; + Packet &appendPayload(std::unique_ptr<utils::MemBuf> &&payload); + Packet &appendPayload(const uint8_t *buffer, std::size_t length); - std::pair<const uint8_t *, std::size_t> getPayloadReference() const { - int signature_size = 0; + // Sizes + std::size_t headerSize() const; + std::size_t payloadSize() const; - if (_is_ah(format_)) { - signature_size = (uint32_t)getSignatureSize(); - } + // Digest + auth::CryptoHash computeDigest(auth::CryptoHashType algorithm) const; - auto header_size = getHeaderSizeFromFormat(format_, signature_size); - auto payload_length = payloadSize(); + bool isInterest(); - return std::make_pair(packet_->data() + header_size, payload_length); - } + // Reset packet + void reset(); + // Utils Packet &updateLength(std::size_t length = 0); - - PayloadType getPayloadType() const; - - Packet &setPayloadType(PayloadType payload_type); - - Format getFormat() const; - void dump() const; - virtual void setLocator(const ip_address_t &locator) = 0; - - virtual ip_address_t getLocator() const = 0; - - void setSignatureTimestamp(const uint64_t ×tamp); - - uint64_t getSignatureTimestamp() const; - - void setValidationAlgorithm(const utils::CryptoSuite &validation_algorithm); - - utils::CryptoSuite getValidationAlgorithm() const; - - void setKeyId(const utils::KeyId &key_id); - - utils::KeyId getKeyId() const; - - virtual utils::CryptoHash computeDigest( - utils::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); - } - if (hicn_packet_compute_header_checksum(format_, packet_start_, - partial_csum) < 0) { - throw errors::MalformedPacketException(); - } - } - + // TCP methods + void setChecksum(); bool checkIntegrity() const; - Packet &setSyn(); - Packet &resetSyn(); - bool testSyn() const; - Packet &setAck(); - Packet &resetAck(); - bool testAck() const; - Packet &setRst(); - Packet &resetRst(); - bool testRst() const; - Packet &setFin(); - Packet &resetFin(); - bool testFin() const; - Packet &resetFlags(); - std::string printFlags() const; - - Packet &setSrcPort(uint16_t srcPort); - Packet &setDstPort(uint16_t dstPort); - uint16_t getSrcPort() const; - uint16_t getDstPort() const; - - Packet &setTTL(uint8_t hops); - uint8_t getTTL() const; - - void separateHeaderPayload(); - void resetPayload(); + // Authentication Header methods + bool hasAH() const; + utils::MemBuf::Ptr getSignature() const; + std::size_t getSignatureFieldSize() const; + std::size_t getSignatureSize() const; + uint64_t getSignatureTimestamp() const; + auth::KeyId getKeyId() const; + auth::CryptoSuite getValidationAlgorithm() const; + void setSignature(const utils::MemBuf::Ptr &signature); + void setSignatureFieldSize(std::size_t size); + void setSignatureSize(std::size_t size); + void setSignatureTimestamp(const uint64_t ×tamp_ms); + void setKeyId(const auth::KeyId &key_id); + void setValidationAlgorithm(const auth::CryptoSuite &algo); + + void saveHeader(u8 *header, size_t *header_len); + void loadHeader(u8 *header, size_t header_len); + + // Static methods + static Format toAHFormat(const Format &format); + static Format getFormatFromBuffer(const uint8_t *buffer, std::size_t length); + static std::size_t getHeaderSizeFromFormat(Format format, + std::size_t signature_size = 0); + static std::size_t getHeaderSizeFromBuffer(const uint8_t *buffer, + size_t length); + static std::size_t getPayloadSizeFromBuffer(const uint8_t *buffer, + size_t length); + static void dump(uint8_t *buffer, std::size_t length); private: virtual void resetForHash() = 0; - void setSignatureSize(std::size_t size_bytes); - - 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 prependPayload(const uint8_t **buffer, std::size_t *size); protected: + hicn_packet_buffer_t pkbuf_; Name name_; - MemBufPtr packet_; - hicn_header_t *packet_start_; - utils::MemBuf *header_head_; - utils::MemBuf *payload_head_; - mutable Format format_; + 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..a528500ad 100644 --- a/libtransport/includes/hicn/transport/core/payload_type.h +++ b/libtransport/includes/hicn/transport/core/payload_type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 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: @@ -15,15 +15,25 @@ #pragma once +#include <hicn/transport/portability/portability.h> + +extern "C" { +#ifndef _WIN32 +TRANSPORT_CLANG_DISABLE_WARNING("-Wextern-c-compat") +#endif +#include <hicn/base.h> +}; + 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 -} // end namespace transport
\ No newline at end of file +} // end namespace transport diff --git a/libtransport/includes/hicn/transport/core/prefix.h b/libtransport/includes/hicn/transport/core/prefix.h index c3805f13f..791fbc770 100644 --- a/libtransport/includes/hicn/transport/core/prefix.h +++ b/libtransport/includes/hicn/transport/core/prefix.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * 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: @@ -25,54 +25,54 @@ class Prefix { public: Prefix(); - Prefix(const char *prefix); - Prefix(const std::string &prefix); - Prefix(std::string &&prefix); - - Prefix(std::string &prefix, uint16_t prefix_length); + Prefix(const std::string &prefix, uint16_t prefix_length); Prefix(const core::Name &content_name, uint16_t prefix_length); - std::unique_ptr<Sockaddr> toSockaddr(); + bool operator<(const Prefix &prefix) const; + + bool operator==(const Prefix &prefix) const; + + bool operator!=(const Prefix &prefix) const { return !operator==(prefix); } + + std::unique_ptr<Sockaddr> toSockaddr() const; - uint16_t getPrefixLength(); + uint16_t getPrefixLength() const; Prefix &setPrefixLength(uint16_t prefix_length); std::string getNetwork() const; - int contains(const ip_address_t &content_name) const; + Prefix &setNetwork(const std::string &network); - int contains(const core::Name &content_name) const; + int getAddressFamily() const; - Name getName() const; + bool contains(const hicn_ip_address_t &content_name) const; - Name getRandomName() const; + bool contains(const core::Name &content_name) const; Name getName(const core::Name &mask, const core::Name &components, const core::Name &content_name) const; Name mapName(const core::Name &content_name) const; - Prefix &setNetwork(std::string &network); - - int getAddressFamily(); - - Prefix &setAddressFamily(int address_family); - + Name makeName() const; Name makeRandomName() const; + Name makeNameWithIndex(std::uint64_t index) const; - ip_prefix_t &toIpPrefixStruct(); + const hicn_ip_prefix_t &toIpPrefixStruct() const; private: static bool checkPrefixLengthAndAddressFamily(uint16_t prefix_length, int family); - void buildPrefix(std::string &prefix, uint16_t prefix_length, int family); + void buildPrefix(const std::string &prefix, uint16_t prefix_length, + int family); - ip_prefix_t ip_prefix_; + private: + hicn_ip_prefix_t hicn_ip_prefix_; }; } // end namespace core |