diff options
Diffstat (limited to 'libtransport/includes/hicn/transport/core')
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 ×tamp); + /** + * @brief Set signature timestamp, in milliseconds. + */ + void setSignatureTimestamp(const uint64_t ×tamp_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, |