aboutsummaryrefslogtreecommitdiffstats
path: root/libtransport/includes/hicn/transport
diff options
context:
space:
mode:
authorLuca Muscariello <muscariello@ieee.org>2021-04-15 09:05:46 +0200
committerMauro Sardara <msardara@cisco.com>2021-04-15 16:36:16 +0200
commite92e9e839ca2cf42b56322b2489ccc0d8bf767af (patch)
tree9f1647c83a87fbf982ae329e800af25dbfb226b5 /libtransport/includes/hicn/transport
parent3e541d7c947cc2f9db145f26c9274efd29a6fb56 (diff)
[HICN-690] Transport Library Major Refactory
The current patch provides a major refactory of the transportlibrary. A summary of the different components that underwent major modifications is reported below. - Transport protocol updates The hierarchy of classes has been optimized to have common transport services across different transport protocols. This can allow to customize a transport protocol with new features. - A new real-time communication protocol The RTC protocol has been optimized in terms of algorithms to reduce consumer-producer synchronization latency. - A novel socket API The API has been reworked to be easier to consumer but also to have a more efficient integration in L4 proxies. - Several performance improvements A large number of performance improvements have been included in particular to make the entire stack zero-copy and optimize cache miss. - New memory buffer framework Memory management has been reworked entirely to provide a more efficient infra with a richer API. Buffers are now allocated in blocks and a single buffer holds the memory for (1) the shared_ptr control block, (2) the metadata of the packet (e.g. name, pointer to other buffers if buffer is chained and relevant offsets), and (3) the packet itself, as it is sent/received over the network. - A new slab allocator Dynamic memory allocation is now managed by a novel slab allocator that is optimised for packet processing and connection management. Memory is organized in pools of blocks all of the same size which are used during the processing of outgoing/incoming packets. When a memory block Is allocated is always taken from a global pool and when it is deallocated is returned to the pool, thus avoiding the cost of any heap allocation in the data path. - New transport connectors Consumer and producer end-points can communication either using an hicn packet forwarder or with direct connector based on shared memories or sockets. The usage of transport connectors typically for unit and funcitonal testing but may have additional usage. - Support for FEC/ECC for transport services FEC/ECC via reed solomon is supported by default and made available to transport services as a modular component. Reed solomon block codes is a default FEC model that can be replaced in a modular way by many other codes including RLNC not avaiable in this distribution. The current FEC framework support variable size padding and efficiently makes use of the infra memory buffers to avoid additiona copies. - Secure transport framework for signature computation and verification Crypto support is nativelty used in hICN for integrity and authenticity. Novel support that includes RTC has been implemented and made modular and reusable acrosso different transport protocols. - TLS - Transport layer security over hicn Point to point confidentiality is provided by integrating TLS on top of hICN reliable and non-reliable transport. The integration is common and makes a different use of the TLS record. - MLS - Messaging layer security over hicn MLS integration on top of hICN is made by using the MLSPP implemetation open sourced by Cisco. We have included instrumentation tools to deploy performance and functional tests of groups of end-points. - Android support The overall code has been heavily tested in Android environments and has received heavy lifting to better run natively in recent Android OS. Co-authored-by: Mauro Sardara <msardara@cisco.com> Co-authored-by: Michele Papalini <micpapal@cisco.com> Co-authored-by: Olivier Roques <oroques+fdio@cisco.com> Co-authored-by: Giulio Grassi <gigrassi@cisco.com> Change-Id: If477ba2fa686e6f47bdf96307ac60938766aef69 Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Diffstat (limited to 'libtransport/includes/hicn/transport')
-rw-r--r--libtransport/includes/hicn/transport/CMakeLists.txt4
-rw-r--r--libtransport/includes/hicn/transport/auth/CMakeLists.txt29
-rw-r--r--libtransport/includes/hicn/transport/auth/common.h29
-rw-r--r--libtransport/includes/hicn/transport/auth/crypto_hash.h121
-rw-r--r--libtransport/includes/hicn/transport/auth/crypto_hash_type.h35
-rw-r--r--libtransport/includes/hicn/transport/auth/crypto_hasher.h70
-rw-r--r--libtransport/includes/hicn/transport/auth/crypto_suite.h39
-rw-r--r--libtransport/includes/hicn/transport/auth/identity.h66
-rw-r--r--libtransport/includes/hicn/transport/auth/key_id.h27
-rw-r--r--libtransport/includes/hicn/transport/auth/policies.h33
-rw-r--r--libtransport/includes/hicn/transport/auth/signer.h92
-rw-r--r--libtransport/includes/hicn/transport/auth/verifier.h169
-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
-rw-r--r--libtransport/includes/hicn/transport/errors/errors.h5
-rw-r--r--libtransport/includes/hicn/transport/http/client_connection.h4
-rw-r--r--libtransport/includes/hicn/transport/interfaces/CMakeLists.txt3
-rw-r--r--libtransport/includes/hicn/transport/interfaces/callbacks.h21
-rw-r--r--libtransport/includes/hicn/transport/interfaces/global_conf_interface.h60
-rw-r--r--libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h5
-rw-r--r--libtransport/includes/hicn/transport/interfaces/portal.h8
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_consumer.h30
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h1
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_options_keys.h11
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_producer.h49
-rw-r--r--libtransport/includes/hicn/transport/interfaces/statistics.h79
-rw-r--r--libtransport/includes/hicn/transport/portability/c_portability.h2
-rw-r--r--libtransport/includes/hicn/transport/portability/platform.h108
-rw-r--r--libtransport/includes/hicn/transport/portability/portability.h2
-rw-r--r--libtransport/includes/hicn/transport/portability/win_portability.h1
-rw-r--r--libtransport/includes/hicn/transport/utils/CMakeLists.txt5
-rw-r--r--libtransport/includes/hicn/transport/utils/conversions.h2
-rw-r--r--libtransport/includes/hicn/transport/utils/enum_iterator.h43
-rw-r--r--libtransport/includes/hicn/transport/utils/event_thread.h63
-rw-r--r--libtransport/includes/hicn/transport/utils/file.h28
-rw-r--r--libtransport/includes/hicn/transport/utils/fixed_block_allocator.h209
-rw-r--r--libtransport/includes/hicn/transport/utils/linux.h4
-rw-r--r--libtransport/includes/hicn/transport/utils/membuf.h32
-rw-r--r--libtransport/includes/hicn/transport/utils/move_wrapper.h39
-rw-r--r--libtransport/includes/hicn/transport/utils/noncopyable.h29
-rw-r--r--libtransport/includes/hicn/transport/utils/object_pool.h25
-rw-r--r--libtransport/includes/hicn/transport/utils/shared_ptr_utils.h28
-rw-r--r--libtransport/includes/hicn/transport/utils/singleton.h39
-rw-r--r--libtransport/includes/hicn/transport/utils/string_utils.h2
54 files changed, 2218 insertions, 306 deletions
diff --git a/libtransport/includes/hicn/transport/CMakeLists.txt b/libtransport/includes/hicn/transport/CMakeLists.txt
index 1099e701d..ca53bdffd 100644
--- a/libtransport/includes/hicn/transport/CMakeLists.txt
+++ b/libtransport/includes/hicn/transport/CMakeLists.txt
@@ -22,7 +22,7 @@ add_subdirectory(errors)
add_subdirectory(http)
add_subdirectory(interfaces)
add_subdirectory(portability)
-add_subdirectory(security)
+add_subdirectory(auth)
add_subdirectory(utils)
set(LIBTRANSPORT_INCLUDE_DIRS
@@ -35,4 +35,4 @@ set(LIBHICNTRANSPORT_TO_INSTALL_HEADER_FILES
${HEADER_FILES} ""
CACHE INTERNAL
"" FORCE
-) \ No newline at end of file
+)
diff --git a/libtransport/includes/hicn/transport/auth/CMakeLists.txt b/libtransport/includes/hicn/transport/auth/CMakeLists.txt
new file mode 100644
index 000000000..d855125b0
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Copyright (c) 2017-2019 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.
+
+cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/common.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_hash.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_hash_type.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_hasher.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_suite.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/identity.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/key_id.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/policies.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/signer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/verifier.h
+)
+
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE)
diff --git a/libtransport/includes/hicn/transport/auth/common.h b/libtransport/includes/hicn/transport/auth/common.h
new file mode 100644
index 000000000..911bcbc6a
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/common.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017-2019 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>
+
+namespace transport {
+namespace auth {
+
+using Hash = std::vector<uint8_t>;
+using HashEntry = std::pair<CryptoHashType, Hash>;
+using PacketPtr = core::Packet *;
+using Suffix = uint32_t;
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/crypto_hash.h b/libtransport/includes/hicn/transport/auth/crypto_hash.h
new file mode 100644
index 000000000..26c251b38
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/crypto_hash.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2017-2019 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/errors/runtime_exception.h>
+#include <hicn/transport/portability/portability.h>
+#include <hicn/transport/auth/crypto_hash_type.h>
+#include <hicn/transport/utils/array.h>
+
+extern "C" {
+#include <parc/security/parc_CryptoHash.h>
+};
+
+#include <cstring>
+#include <unordered_map>
+
+namespace transport {
+namespace auth {
+
+class CryptoHasher;
+
+struct EnumClassHash {
+ template <typename T>
+ std::size_t operator()(T t) const {
+ return static_cast<std::size_t>(t);
+ }
+};
+
+static std::unordered_map<CryptoHashType, std::size_t, EnumClassHash>
+ hash_size_map = {{CryptoHashType::SHA_256, 32},
+ {CryptoHashType::CRC32C, 4},
+ {CryptoHashType::SHA_512, 64}};
+
+class Signer;
+class Verifier;
+
+class CryptoHash {
+ friend class CryptoHasher;
+ friend class Signer;
+ friend class Verifier;
+
+ public:
+ CryptoHash() : hash_(nullptr) {}
+
+ CryptoHash(const CryptoHash& other) {
+ if (other.hash_) {
+ hash_ = parcCryptoHash_Acquire(other.hash_);
+ }
+ }
+
+ CryptoHash(CryptoHash&& other) {
+ if (other.hash_) {
+ hash_ = parcCryptoHash_Acquire(other.hash_);
+ }
+ }
+
+ template <typename T>
+ CryptoHash(const T* buffer, std::size_t length, CryptoHashType hash_type) {
+ hash_ = parcCryptoHash_CreateFromArray(
+ static_cast<PARCCryptoHashType>(hash_type), buffer, length);
+ }
+
+ ~CryptoHash() {
+ if (hash_) {
+ parcCryptoHash_Release(&hash_);
+ }
+ }
+
+ CryptoHash& operator=(const CryptoHash& other) {
+ if (other.hash_) {
+ hash_ = parcCryptoHash_Acquire(other.hash_);
+ }
+
+ return *this;
+ }
+
+ template <typename T>
+ utils::Array<T> getDigest() const {
+ return utils::Array<T>(
+ static_cast<T*>(parcBuffer_Overlay(parcCryptoHash_GetDigest(hash_), 0)),
+ parcBuffer_Remaining(parcCryptoHash_GetDigest(hash_)));
+ }
+
+ CryptoHashType getType() {
+ return static_cast<CryptoHashType>(parcCryptoHash_GetDigestType(hash_));
+ }
+
+ template <typename T>
+ static bool compareBinaryDigest(const T* digest1, const T* digest2,
+ CryptoHashType hash_type) {
+ if (hash_size_map.find(hash_type) == hash_size_map.end()) {
+ return false;
+ }
+
+ return !static_cast<bool>(
+ std::memcmp(digest1, digest2, hash_size_map[hash_type]));
+ }
+
+ TRANSPORT_ALWAYS_INLINE void display() {
+ parcBuffer_Display(parcCryptoHash_GetDigest(hash_), 2);
+ }
+
+ private:
+ PARCCryptoHash* hash_;
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/crypto_hash_type.h b/libtransport/includes/hicn/transport/auth/crypto_hash_type.h
new file mode 100644
index 000000000..9d792624e
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/crypto_hash_type.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017-2019 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
+
+extern "C" {
+#include <parc/security/parc_CryptoHashType.h>
+};
+
+#include <cstdint>
+
+namespace transport {
+namespace auth {
+
+enum class CryptoHashType : uint8_t {
+ SHA_256 = PARCCryptoHashType_SHA256,
+ SHA_512 = PARCCryptoHashType_SHA512,
+ CRC32C = PARCCryptoHashType_CRC32C,
+ NULL_HASH = PARCCryptoHashType_NULL
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/crypto_hasher.h b/libtransport/includes/hicn/transport/auth/crypto_hasher.h
new file mode 100644
index 000000000..ada1a6ee8
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/crypto_hasher.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017-2019 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/auth/crypto_hash.h>
+
+extern "C" {
+#include <parc/security/parc_CryptoHasher.h>
+};
+
+namespace transport {
+namespace auth {
+
+class CryptoHasher {
+ public:
+ CryptoHasher(CryptoHashType hash_type)
+ : hasher_(parcCryptoHasher_Create(
+ static_cast<PARCCryptoHashType>(hash_type))),
+ managed_(true) {}
+
+ CryptoHasher(PARCCryptoHasher* hasher) : hasher_(hasher), managed_(false) {}
+
+ ~CryptoHasher() {
+ if (managed_) {
+ parcCryptoHasher_Release(&hasher_);
+ }
+ }
+
+ CryptoHasher& init() {
+ if (parcCryptoHasher_Init(hasher_) == -1) {
+ throw errors::RuntimeException("Cryptohash init failed.");
+ }
+
+ return *this;
+ }
+
+ template <typename T>
+ CryptoHasher& updateBytes(const T* buffer, std::size_t length) {
+ if (parcCryptoHasher_UpdateBytes(hasher_, buffer, length) == -1) {
+ throw errors::RuntimeException("Cryptohash updateBytes failed.");
+ }
+ return *this;
+ }
+
+ CryptoHash finalize() {
+ CryptoHash hash;
+ hash.hash_ = parcCryptoHasher_Finalize(hasher_);
+ return hash;
+ }
+
+ private:
+ PARCCryptoHasher* hasher_;
+ bool managed_;
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/crypto_suite.h b/libtransport/includes/hicn/transport/auth/crypto_suite.h
new file mode 100644
index 000000000..11df6ac06
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/crypto_suite.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017-2019 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
+
+extern "C" {
+#include <parc/security/parc_CryptoSuite.h>
+};
+
+#include <cstdint>
+
+namespace transport {
+namespace auth {
+
+enum class CryptoSuite : uint8_t {
+ RSA_SHA256 = PARCCryptoSuite_RSA_SHA256,
+ DSA_SHA256 = PARCCryptoSuite_DSA_SHA256,
+ RSA_SHA512 = PARCCryptoSuite_RSA_SHA512,
+ HMAC_SHA256 = PARCCryptoSuite_HMAC_SHA256,
+ HMAC_SHA512 = PARCCryptoSuite_HMAC_SHA512,
+ NULL_CRC32C = PARCCryptoSuite_NULL_CRC32C,
+ ECDSA_256K1 = PARCCryptoSuite_ECDSA_SHA256,
+ UNKNOWN = PARCCryptoSuite_UNKNOWN
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/identity.h b/libtransport/includes/hicn/transport/auth/identity.h
new file mode 100644
index 000000000..19157952e
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/identity.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017-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/auth/signer.h>
+
+extern "C" {
+#include <parc/security/parc_Identity.h>
+#include <parc/security/parc_IdentityFile.h>
+#include <parc/security/parc_Pkcs12KeyStore.h>
+#include <parc/security/parc_Security.h>
+};
+
+namespace transport {
+namespace auth {
+
+class Identity {
+ // This class holds several information about a client, including its public
+ // key.
+ public:
+ // Generate a new identity from the given parameters. The identity will be
+ // saved in 'keystore_path' and encrypted using 'keystore_pwd'.
+ Identity(const std::string &keystore_path, const std::string &keystore_pwd,
+ CryptoSuite suite, unsigned int signature_len,
+ unsigned int validity_days, const std::string &subject_name);
+
+ // Create an identity from an already existing keystore path.
+ Identity(std::string &keystore_path, std::string &keystore_pwd,
+ CryptoHashType hash_type);
+
+ Identity(const Identity &other);
+ Identity(Identity &&other);
+ ~Identity();
+
+ // Return the asymmetric signer object created from the public key.
+ std::shared_ptr<AsymmetricSigner> getSigner() const;
+
+ // Return the key store filename.
+ std::string getFilename() const;
+
+ // Return the key store password.
+ std::string getPassword() const;
+
+ // Generate a new random identity.
+ static Identity generateIdentity(const std::string &subject_name = "");
+
+ private:
+ PARCIdentity *identity_;
+ std::shared_ptr<AsymmetricSigner> signer_;
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/key_id.h b/libtransport/includes/hicn/transport/auth/key_id.h
new file mode 100644
index 000000000..3aa09336f
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/key_id.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017-2019 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 <cstdint>
+#include <utility>
+
+namespace transport {
+namespace auth {
+
+using KeyId = std::pair<uint8_t *, uint8_t>;
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/policies.h b/libtransport/includes/hicn/transport/auth/policies.h
new file mode 100644
index 000000000..00464d54b
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/policies.h
@@ -0,0 +1,33 @@
+/*
+ * 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
+
+namespace transport {
+namespace auth {
+
+/**
+ * These policies allows the verifier to tell the transport what action to
+ * perform after verification.
+ */
+enum class VerificationPolicy {
+ ABORT,
+ ACCEPT,
+ DROP,
+ UNKNOWN,
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/signer.h b/libtransport/includes/hicn/transport/auth/signer.h
new file mode 100644
index 000000000..fd5c4e6c6
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/signer.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017-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/auth/common.h>
+#include <hicn/transport/errors/errors.h>
+
+extern "C" {
+#include <parc/security/parc_PublicKeySigner.h>
+#include <parc/security/parc_Security.h>
+#include <parc/security/parc_Signer.h>
+#include <parc/security/parc_SymmetricKeySigner.h>
+}
+
+namespace transport {
+namespace auth {
+
+class Signer {
+ // The base class from which all signer classes derive.
+ public:
+ Signer();
+
+ Signer(PARCSigner *signer);
+
+ virtual ~Signer();
+
+ // Sign a packet.
+ virtual void signPacket(PacketPtr packet);
+
+ // Set the signer object used to sign packets.
+ void setSigner(PARCSigner *signer);
+
+ // Return the signature size.
+ size_t getSignatureSize() const;
+
+ // Return the crypto suite associated to the signer.
+ CryptoSuite getCryptoSuite() const;
+
+ // Return the hash algorithm associated to the signer.
+ CryptoHashType getCryptoHashType() const;
+
+ // Return the PARC signer.
+ PARCSigner *getParcSigner() const;
+
+ // Return the PARC key store containing the signer key.
+ PARCKeyStore *getParcKeyStore() const;
+
+ protected:
+ PARCSigner *signer_;
+ PARCKeyId *key_id_;
+};
+
+class AsymmetricSigner : public Signer {
+ // This class uses asymmetric verification to sign packets. The public key
+ // must be given from a PARCKeyStore.
+ public:
+ AsymmetricSigner() = default;
+ AsymmetricSigner(PARCSigner *signer) : Signer(signer){};
+
+ // Construct an AsymmetricSigner from a key store and a given crypto suite.
+ AsymmetricSigner(CryptoSuite suite, PARCKeyStore *key_store);
+};
+
+class SymmetricSigner : public Signer {
+ // This class uses symmetric verification to sign packets. The symmetric
+ // key is derived from a passphrase.
+ public:
+ SymmetricSigner() = default;
+ SymmetricSigner(PARCSigner *signer) : Signer(signer){};
+
+ // Construct an SymmetricSigner from a key store and a given crypto suite.
+ SymmetricSigner(CryptoSuite suite, PARCKeyStore *key_store);
+
+ // Construct an AsymmetricSigner from a passphrase and a given crypto suite.
+ SymmetricSigner(CryptoSuite suite, const std::string &passphrase);
+};
+
+} // namespace auth
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/auth/verifier.h b/libtransport/includes/hicn/transport/auth/verifier.h
new file mode 100644
index 000000000..e6e561918
--- /dev/null
+++ b/libtransport/includes/hicn/transport/auth/verifier.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2017-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/auth/common.h>
+#include <hicn/transport/auth/policies.h>
+#include <hicn/transport/core/content_object.h>
+#include <hicn/transport/errors/errors.h>
+#include <hicn/transport/interfaces/callbacks.h>
+
+#include <algorithm>
+
+extern "C" {
+#include <parc/security/parc_CertificateFactory.h>
+#include <parc/security/parc_InMemoryVerifier.h>
+#include <parc/security/parc_Security.h>
+#include <parc/security/parc_SymmetricKeySigner.h>
+#include <parc/security/parc_Verifier.h>
+}
+
+namespace transport {
+namespace auth {
+
+class Verifier {
+ // The base class from which all verifier classes derive.
+ public:
+ // The VerificationFailedCallback will be called by the transport if a data
+ // packet (either a manifest or a content object) cannot be verified. The
+ // application decides what to do then by returning a VerificationPolicy
+ // object.
+ using VerificationFailedCallback = std::function<auth::VerificationPolicy(
+ const core::ContentObject &content_object, std::error_code ec)>;
+
+ // The list of VerificationPolicy that will trigger the
+ // VerificationFailedCallback.
+ static const std::vector<VerificationPolicy> DEFAULT_FAILED_POLICIES;
+
+ Verifier();
+
+ virtual ~Verifier();
+
+ // Verify a single packet and return whether or not the packet signature is
+ // valid.
+ virtual bool verifyPacket(PacketPtr packet);
+
+ // Verify a batch of packets. Return a vector with the same size as the packet
+ // list, element i of that vector will contain the VerificationPolicy for
+ // packet i.
+ virtual std::vector<VerificationPolicy> verifyPackets(
+ const std::vector<PacketPtr> &packets);
+ VerificationPolicy verifyPackets(PacketPtr packet) {
+ return verifyPackets(std::vector<PacketPtr>{packet}).front();
+ }
+
+ // Verify that a batch of packets are valid using a map from packet suffixes
+ // to hashes. A packet is considered valid if its hash correspond to the hash
+ // present in the map. Return a vector with the same size as the packet list,
+ // element i of that vector will contain the VerificationPolicy for packet i.
+ virtual std::vector<VerificationPolicy> verifyPackets(
+ const std::vector<PacketPtr> &packets,
+ const std::unordered_map<Suffix, HashEntry> &suffix_map);
+ VerificationPolicy verifyPackets(
+ PacketPtr packet,
+ const std::unordered_map<Suffix, HashEntry> &suffix_map) {
+ return verifyPackets(std::vector<PacketPtr>{packet}, suffix_map).front();
+ }
+
+ // Add a general PARC key which can be used to verify packet signatures.
+ void addKey(PARCKey *key);
+
+ // Set the hasher object used to compute packet hashes.
+ void setHasher(PARCCryptoHasher *hasher);
+
+ // Set the callback for the case packet verification fails.
+ void setVerificationFailedCallback(
+ VerificationFailedCallback verification_failed_cb,
+ const std::vector<VerificationPolicy> &failed_policies =
+ DEFAULT_FAILED_POLICIES);
+
+ // Retrieve the VerificationFailedCallback function.
+ void getVerificationFailedCallback(
+ VerificationFailedCallback **verification_failed_cb);
+
+ static size_t getSignatureSize(const PacketPtr);
+
+ protected:
+ PARCCryptoHasher *hasher_;
+ PARCVerifier *verifier_;
+ VerificationFailedCallback verification_failed_cb_;
+ std::vector<VerificationPolicy> failed_policies_;
+
+ // Internally compute a packet hash using the hasher object.
+ virtual CryptoHash computeHash(PacketPtr packet);
+
+ // Call VerificationFailedCallback if it is set and update the packet policy.
+ void callVerificationFailedCallback(PacketPtr packet,
+ VerificationPolicy &policy);
+};
+
+class VoidVerifier : public Verifier {
+ // This class is the default socket verifier. It ignores completely the packet
+ // signature and always returns true.
+ public:
+ bool verifyPacket(PacketPtr packet) override;
+
+ std::vector<VerificationPolicy> verifyPackets(
+ const std::vector<PacketPtr> &packets) override;
+
+ std::vector<VerificationPolicy> verifyPackets(
+ const std::vector<PacketPtr> &packets,
+ const std::unordered_map<Suffix, HashEntry> &suffix_map) override;
+};
+
+class AsymmetricVerifier : public Verifier {
+ // This class uses asymmetric verification to validate packets. The public key
+ // can be set directly or extracted from a certificate.
+ public:
+ AsymmetricVerifier() = default;
+
+ // Add a public key to the verifier.
+ AsymmetricVerifier(PARCKey *pub_key);
+
+ // Construct an AsymmetricVerifier from a certificate file.
+ AsymmetricVerifier(const std::string &cert_path);
+
+ // Extract the public key of a certificate file.
+ void setCertificate(const std::string &cert_path);
+};
+
+class SymmetricVerifier : public Verifier {
+ // This class uses symmetric verification to validate packets. The symmetric
+ // key is derived from a passphrase.
+ public:
+ SymmetricVerifier() = default;
+
+ // Construct a SymmetricVerifier from a passphrase.
+ SymmetricVerifier(const std::string &passphrase);
+
+ ~SymmetricVerifier();
+
+ // Create and set a symmetric key from a passphrase.
+ void setPassphrase(const std::string &passphrase);
+
+ // Construct a signer object. Passphrase must be set beforehand.
+ void setSigner(const PARCCryptoSuite &suite);
+
+ virtual std::vector<VerificationPolicy> verifyPackets(
+ const std::vector<PacketPtr> &packets) override;
+
+ protected:
+ PARCBuffer *passphrase_;
+ PARCSigner *signer_;
+};
+
+} // namespace auth
+} // namespace transport
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,
diff --git a/libtransport/includes/hicn/transport/errors/errors.h b/libtransport/includes/hicn/transport/errors/errors.h
index 512e35736..b659820fa 100644
--- a/libtransport/includes/hicn/transport/errors/errors.h
+++ b/libtransport/includes/hicn/transport/errors/errors.h
@@ -15,10 +15,13 @@
#pragma once
+#include <hicn/transport/errors/indexing_exception.h>
#include <hicn/transport/errors/invalid_ip_address_exception.h>
+#include <hicn/transport/errors/malformed_ahpacket_exception.h>
#include <hicn/transport/errors/malformed_name_exception.h>
#include <hicn/transport/errors/malformed_packet_exception.h>
#include <hicn/transport/errors/not_implemented_exception.h>
#include <hicn/transport/errors/null_pointer_exception.h>
#include <hicn/transport/errors/runtime_exception.h>
-#include <hicn/transport/errors/tokenizer_exception.h> \ No newline at end of file
+#include <hicn/transport/errors/tokenizer_exception.h>
+#include <hicn/transport/errors/unexpected_manifest_exception.h>
diff --git a/libtransport/includes/hicn/transport/http/client_connection.h b/libtransport/includes/hicn/transport/http/client_connection.h
index 262756a09..7e78e9c59 100644
--- a/libtransport/includes/hicn/transport/http/client_connection.h
+++ b/libtransport/includes/hicn/transport/http/client_connection.h
@@ -68,7 +68,7 @@ class HTTPClientConnection {
HTTPClientConnection &setTimeout(const std::chrono::seconds &timeout);
- HTTPClientConnection &setCertificate(const std::string &cert_path);
+ HTTPClientConnection &setVerifier(std::shared_ptr<auth::Verifier> verifier);
private:
class Implementation;
@@ -77,4 +77,4 @@ class HTTPClientConnection {
} // end namespace http
-} // end namespace transport \ No newline at end of file
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt b/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt
index 7370ad1b0..08f880930 100644
--- a/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt
+++ b/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt
@@ -16,12 +16,11 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/socket_consumer.h
${CMAKE_CURRENT_SOURCE_DIR}/socket_producer.h
- ${CMAKE_CURRENT_SOURCE_DIR}/rtc_socket_producer.h
${CMAKE_CURRENT_SOURCE_DIR}/publication_options.h
${CMAKE_CURRENT_SOURCE_DIR}/socket_options_default_values.h
${CMAKE_CURRENT_SOURCE_DIR}/socket_options_keys.h
${CMAKE_CURRENT_SOURCE_DIR}/callbacks.h
- ${CMAKE_CURRENT_SOURCE_DIR}/verification_policy.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/global_conf_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/statistics.h
${CMAKE_CURRENT_SOURCE_DIR}/portal.h
)
diff --git a/libtransport/includes/hicn/transport/interfaces/callbacks.h b/libtransport/includes/hicn/transport/interfaces/callbacks.h
index 6ae07797e..95b4d1977 100644
--- a/libtransport/includes/hicn/transport/interfaces/callbacks.h
+++ b/libtransport/includes/hicn/transport/interfaces/callbacks.h
@@ -16,7 +16,7 @@
#pragma once
#include <hicn/transport/interfaces/statistics.h>
-#include <hicn/transport/interfaces/verification_policy.h>
+#include <hicn/transport/auth/policies.h>
#include <functional>
#include <system_error>
@@ -75,25 +75,6 @@ using ConsumerContentObjectCallback =
std::function<void(ConsumerSocket &, const core::ContentObject &)>;
/**
- * The ConsumerContentObjectVerificationCallback will be called by the transport
- * if an application is willing to verify each content object. Note that a
- * better alternative is to instrument the transport to perform the verification
- * autonomously, without requiring the intervention of the application.
- */
-using ConsumerContentObjectVerificationCallback =
- std::function<bool(ConsumerSocket &, const core::ContentObject &)>;
-
-/**
- * The ConsumerContentObjectVerificationFailedCallback will be caled by the
- * transport if a data packet (either manifest or content object) cannot be
- * verified. The application here decides what to do by returning a
- * VerificationFailedPolicy object.
- */
-using ConsumerContentObjectVerificationFailedCallback =
- std::function<VerificationPolicy(
- ConsumerSocket &, const core::ContentObject &, std::error_code ec)>;
-
-/**
* The ProducerContentObjectCallback will be called in different parts of the
* consumer socket processing pipeline, with a ProducerSocket and an
* ContentObject as parameters.
diff --git a/libtransport/includes/hicn/transport/interfaces/global_conf_interface.h b/libtransport/includes/hicn/transport/interfaces/global_conf_interface.h
new file mode 100644
index 000000000..a9fe6fac6
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/global_conf_interface.h
@@ -0,0 +1,60 @@
+/*
+ * 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 <string>
+#include <vector>
+
+/**
+ * Global configuration interface.
+ */
+
+namespace transport {
+namespace interface {
+namespace global_config {
+
+static const constexpr char io_module_section[] = "io_module";
+void parseConfigurationFile(const std::string& path = "");
+
+class ConfigurationObject {
+ public:
+ /**
+ * Set configuration.
+ */
+ void set();
+
+ /**
+ * Get configuration.
+ */
+ void get();
+
+ /**
+ * Get configuration key
+ */
+ virtual std::string getKey() const = 0;
+};
+
+class IoModuleConfiguration : public ConfigurationObject {
+ public:
+ std::string getKey() const override { return io_module_section; }
+
+ std::string name;
+ std::vector<std::string> search_path;
+};
+
+} // namespace global_config
+} // namespace interface
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h b/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h
index 6f0d48bb9..7b284c520 100644
--- a/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h
+++ b/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h
@@ -16,8 +16,7 @@
#pragma once
#include <hicn/transport/interfaces/socket_producer.h>
-
-#include <hicn/transport/security/identity.h>
+#include <hicn/transport/auth/identity.h>
namespace transport {
@@ -27,7 +26,7 @@ class P2PSecureProducerSocket : public ProducerSocket {
public:
P2PSecureProducerSocket();
P2PSecureProducerSocket(bool rtc,
- const std::shared_ptr<utils::Identity> &identity);
+ const std::shared_ptr<auth::Identity> &identity);
~P2PSecureProducerSocket() = default;
};
diff --git a/libtransport/includes/hicn/transport/interfaces/portal.h b/libtransport/includes/hicn/transport/interfaces/portal.h
index 724cd7592..22c8591f4 100644
--- a/libtransport/includes/hicn/transport/interfaces/portal.h
+++ b/libtransport/includes/hicn/transport/interfaces/portal.h
@@ -23,7 +23,6 @@
#define ASIO_STANDALONE
#endif
#include <asio/io_service.hpp>
-
#include <functional>
#define UNSET_CALLBACK 0
@@ -71,8 +70,7 @@ class Portal {
*/
class ConsumerCallback {
public:
- virtual void onContentObject(core::Interest::Ptr &&i,
- core::ContentObject::Ptr &&c) = 0;
+ virtual void onContentObject(core::Interest &i, core::ContentObject &c) = 0;
virtual void onTimeout(core::Interest::Ptr &&i) = 0;
virtual void onError(std::error_code ec) = 0;
};
@@ -83,12 +81,12 @@ class Portal {
*/
class ProducerCallback {
public:
- virtual void onInterest(core::Interest::Ptr &&i) = 0;
+ virtual void onInterest(core::Interest &i) = 0;
virtual void onError(std::error_code ec) = 0;
};
using OnContentObjectCallback =
- std::function<void(core::Interest::Ptr &&, core::ContentObject::Ptr &&)>;
+ std::function<void(core::Interest &, core::ContentObject &)>;
using OnInterestTimeoutCallback = std::function<void(core::Interest::Ptr &&)>;
Portal();
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_consumer.h b/libtransport/includes/hicn/transport/interfaces/socket_consumer.h
index 2447f9b5b..621e7ce6f 100644
--- a/libtransport/includes/hicn/transport/interfaces/socket_consumer.h
+++ b/libtransport/includes/hicn/transport/interfaces/socket_consumer.h
@@ -21,7 +21,7 @@
#include <hicn/transport/interfaces/callbacks.h>
#include <hicn/transport/interfaces/socket_options_default_values.h>
#include <hicn/transport/interfaces/socket_options_keys.h>
-#include <hicn/transport/security/verifier.h>
+#include <hicn/transport/auth/verifier.h>
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
@@ -208,14 +208,6 @@ class ConsumerSocket {
int asyncConsume(const Name &name);
/**
- * Verify the packets containing a key after the origin of the key has been
- * validated by the client.
- *
- * @return true if all packets are valid, false otherwise
- */
- bool verifyKeyPackets();
-
- /**
* Stops the consumer socket. If several downloads are queued (using
* asyncConsume), this call stops just the current one.
*/
@@ -251,14 +243,6 @@ class ConsumerSocket {
int setSocketOption(int socket_option_key,
ConsumerContentObjectCallback socket_option_value);
- int setSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationFailedCallback socket_option_value);
-
- int setSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationCallback socket_option_value);
-
int setSocketOption(int socket_option_key,
ConsumerInterestCallback socket_option_value);
@@ -267,7 +251,7 @@ class ConsumerSocket {
int setSocketOption(
int socket_option_key,
- const std::shared_ptr<utils::Verifier> &socket_option_value);
+ const std::shared_ptr<auth::Verifier> &socket_option_value);
int setSocketOption(int socket_option_key,
const std::string &socket_option_value);
@@ -286,21 +270,13 @@ class ConsumerSocket {
int getSocketOption(int socket_option_key,
ConsumerContentObjectCallback **socket_option_value);
- int getSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationFailedCallback **socket_option_value);
-
- int getSocketOption(
- int socket_option_key,
- ConsumerContentObjectVerificationCallback **socket_option_value);
-
int getSocketOption(int socket_option_key,
ConsumerInterestCallback **socket_option_value);
int getSocketOption(int socket_option_key, IcnObserver **socket_option_value);
int getSocketOption(int socket_option_key,
- std::shared_ptr<utils::Verifier> &socket_option_value);
+ std::shared_ptr<auth::Verifier> &socket_option_value);
int getSocketOption(int socket_option_key, std::string &socket_option_value);
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h b/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h
index bcf103b8c..f4945ac8a 100644
--- a/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h
+++ b/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h
@@ -16,6 +16,7 @@
#pragma once
#include <hicn/base.h>
+
#include <chrono>
#include <cstdint>
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h b/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h
index f50e919b4..00cd44075 100644
--- a/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h
+++ b/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h
@@ -32,6 +32,11 @@ typedef enum {
} TransportProtocolAlgorithms;
typedef enum {
+ BYTE_STREAM = 10,
+ RTC_PROD = 11,
+} ProductionProtocolAlgorithms;
+
+typedef enum {
INPUT_BUFFER_SIZE = 101,
OUTPUT_BUFFER_SIZE = 102,
NETWORK_NAME = 103,
@@ -40,7 +45,6 @@ typedef enum {
DATA_PACKET_SIZE = 106,
INTEREST_LIFETIME = 107,
CONTENT_OBJECT_EXPIRY_TIME = 108,
- KEY_CONTENT = 110,
MIN_WINDOW_SIZE = 111,
MAX_WINDOW_SIZE = 112,
CURRENT_WINDOW_SIZE = 113,
@@ -50,12 +54,10 @@ typedef enum {
RUNNING = 117,
APPLICATION_BUFFER = 118,
HASH_ALGORITHM = 119,
- CRYPTO_SUITE = 120,
SIGNER = 121,
VERIFIER = 122,
- CERTIFICATE = 123,
- VERIFY_SIGNATURE = 124,
STATS_INTERVAL = 125,
+ SUFFIX_STRATEGY = 126
} GeneralTransportOptions;
typedef enum {
@@ -98,6 +100,7 @@ typedef enum {
CONTENT_OBJECT_READY = 510,
CONTENT_OBJECT_OUTPUT = 511,
CONTENT_PRODUCED = 512,
+ CONTENT_OBJECT_TO_SIGN = 513
} ProducerCallbacksOptions;
typedef enum { OUTPUT_INTERFACE = 601 } DataLinkOptions;
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_producer.h b/libtransport/includes/hicn/transport/interfaces/socket_producer.h
index e269fb83d..302b03f3f 100644
--- a/libtransport/includes/hicn/transport/interfaces/socket_producer.h
+++ b/libtransport/includes/hicn/transport/interfaces/socket_producer.h
@@ -21,7 +21,7 @@
#include <hicn/transport/interfaces/callbacks.h>
#include <hicn/transport/interfaces/socket_options_default_values.h>
#include <hicn/transport/interfaces/socket_options_keys.h>
-#include <hicn/transport/security/signer.h>
+#include <hicn/transport/auth/signer.h>
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
@@ -40,7 +40,10 @@ using namespace core;
class ProducerSocket {
public:
- explicit ProducerSocket(int protocol = 0);
+ explicit ProducerSocket(
+ int protocol = ProductionProtocolAlgorithms::BYTE_STREAM);
+
+ explicit ProducerSocket(int protocol, asio::io_service &io_service);
virtual ~ProducerSocket();
@@ -48,22 +51,21 @@ class ProducerSocket {
bool isRunning();
- uint32_t produce(Name content_name, const uint8_t *buffer, size_t buffer_size,
- bool is_last = true, uint32_t start_offset = 0) {
- return produce(content_name, utils::MemBuf::copyBuffer(buffer, buffer_size),
- is_last, start_offset);
- }
+ void registerPrefix(const Prefix &producer_namespace);
- uint32_t produce(Name content_name, std::unique_ptr<utils::MemBuf> &&buffer,
- bool is_last = true, uint32_t start_offset = 0);
+ uint32_t produceStream(const Name &content_name, const uint8_t *buffer,
+ size_t buffer_size, bool is_last = true,
+ uint32_t start_offset = 0);
- void produce(ContentObject &content_object);
+ uint32_t produceStream(const Name &content_name,
+ std::unique_ptr<utils::MemBuf> &&buffer,
+ bool is_last = true, uint32_t start_offset = 0);
- void produce(const uint8_t *buffer, size_t buffer_size) {
- produce(utils::MemBuf::copyBuffer(buffer, buffer_size));
- }
+ uint32_t produceDatagram(const Name &content_name, const uint8_t *buffer,
+ size_t buffer_size);
- void produce(std::unique_ptr<utils::MemBuf> &&buffer);
+ uint32_t produceDatagram(const Name &content_name,
+ std::unique_ptr<utils::MemBuf> &&buffer);
void asyncProduce(const Name &suffix, const uint8_t *buf, size_t buffer_size,
bool is_last = true, uint32_t *start_offset = nullptr);
@@ -72,9 +74,7 @@ class ProducerSocket {
bool is_last, uint32_t offset,
uint32_t **last_segment = nullptr);
- void asyncProduce(ContentObject &content_object);
-
- void registerPrefix(const Prefix &producer_namespace);
+ void produce(ContentObject &content_object);
void serveForever();
@@ -104,14 +104,13 @@ class ProducerSocket {
ProducerContentCallback socket_option_value);
int setSocketOption(int socket_option_key,
- utils::CryptoHashType socket_option_value);
+ auth::CryptoHashType socket_option_value);
int setSocketOption(int socket_option_key,
- utils::CryptoSuite socket_option_value);
+ auth::CryptoSuite socket_option_value);
- int setSocketOption(
- int socket_option_key,
- const std::shared_ptr<utils::Signer> &socket_option_value);
+ int setSocketOption(int socket_option_key,
+ const std::shared_ptr<auth::Signer> &socket_option_value);
int setSocketOption(int socket_option_key,
const std::string &socket_option_value);
@@ -133,13 +132,13 @@ class ProducerSocket {
ProducerInterestCallback **socket_option_value);
int getSocketOption(int socket_option_key,
- utils::CryptoHashType &socket_option_value);
+ auth::CryptoHashType &socket_option_value);
int getSocketOption(int socket_option_key,
- utils::CryptoSuite &socket_option_value);
+ auth::CryptoSuite &socket_option_value);
int getSocketOption(int socket_option_key,
- std::shared_ptr<utils::Signer> &socket_option_value);
+ std::shared_ptr<auth::Signer> &socket_option_value);
int getSocketOption(int socket_option_key, std::string &socket_option_value);
diff --git a/libtransport/includes/hicn/transport/interfaces/statistics.h b/libtransport/includes/hicn/transport/interfaces/statistics.h
index 26831fbf1..92c58da23 100644
--- a/libtransport/includes/hicn/transport/interfaces/statistics.h
+++ b/libtransport/includes/hicn/transport/interfaces/statistics.h
@@ -31,6 +31,8 @@ class IcnObserver {
virtual void notifyDownloadTime(double downloadTime) = 0;
};
+class ProductionStatistics {};
+
class TransportStatistics {
static constexpr double default_alpha = 0.7;
@@ -43,7 +45,15 @@ class TransportStatistics {
interest_tx_(0),
alpha_(alpha),
loss_ratio_(0.0),
- queuing_delay_(0.0) {}
+ queuing_delay_(0.0),
+ interest_FEC_tx_(0),
+ bytes_FEC_received_(0),
+ lost_data_(0),
+ recovered_data_(0),
+ status_(-1),
+ // avg_data_rtt_(0),
+ avg_pending_pkt_(0.0),
+ received_nacks_(0) {}
TRANSPORT_ALWAYS_INLINE void updateRetxCount(uint64_t retx) {
retx_count_ += retx;
@@ -74,6 +84,32 @@ class TransportStatistics {
queuing_delay_ = queuing_delay;
}
+ TRANSPORT_ALWAYS_INLINE void updateInterestFecTx(uint64_t int_tx) {
+ interest_FEC_tx_ += int_tx;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateBytesFecRecv(uint64_t bytes) {
+ bytes_FEC_received_ += bytes;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateLostData(uint64_t pkt) {
+ lost_data_ += pkt;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateRecoveredData(uint64_t bytes) {
+ recovered_data_ += bytes;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateCCState(int status) { status_ = status; }
+
+ TRANSPORT_ALWAYS_INLINE void updateAveragePendingPktCount(double pkt) {
+ avg_pending_pkt_ = (alpha_ * avg_pending_pkt_) + ((1. - alpha_) * pkt);
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateReceivedNacks(uint32_t nacks) {
+ received_nacks_ += nacks;
+ }
+
TRANSPORT_ALWAYS_INLINE uint64_t getRetxCount() const { return retx_count_; }
TRANSPORT_ALWAYS_INLINE uint64_t getBytesRecv() const {
@@ -96,6 +132,32 @@ class TransportStatistics {
return queuing_delay_;
}
+ TRANSPORT_ALWAYS_INLINE uint64_t getInterestFecTxCount() const {
+ return interest_FEC_tx_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE uint64_t getBytesFecRecv() const {
+ return bytes_FEC_received_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE uint64_t getLostData() const { return lost_data_; }
+
+ TRANSPORT_ALWAYS_INLINE uint64_t getBytesRecoveredData() const {
+ return recovered_data_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE int getCCStatus() const { return status_; }
+
+ TRANSPORT_ALWAYS_INLINE double getAveragePendingPktCount() const {
+ return avg_pending_pkt_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE uint32_t getReceivedNacks() const {
+ return received_nacks_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void setAlpha(double val) { alpha_ = val; }
+
TRANSPORT_ALWAYS_INLINE void reset() {
retx_count_ = 0;
bytes_received_ = 0;
@@ -103,6 +165,14 @@ class TransportStatistics {
avg_window_size_ = 0;
interest_tx_ = 0;
loss_ratio_ = 0;
+ interest_FEC_tx_ = 0;
+ bytes_FEC_received_ = 0;
+ lost_data_ = 0;
+ recovered_data_ = 0;
+ status_ = 0;
+ // avg_data_rtt_ = 0;
+ avg_pending_pkt_ = 0;
+ received_nacks_ = 0;
}
private:
@@ -114,6 +184,13 @@ class TransportStatistics {
double alpha_;
double loss_ratio_;
double queuing_delay_;
+ uint64_t interest_FEC_tx_;
+ uint64_t bytes_FEC_received_;
+ uint64_t lost_data_;
+ uint64_t recovered_data_;
+ int status_; // transport status (e.g. sync status, congestion etc.)
+ double avg_pending_pkt_;
+ uint32_t received_nacks_;
};
} // namespace interface
diff --git a/libtransport/includes/hicn/transport/portability/c_portability.h b/libtransport/includes/hicn/transport/portability/c_portability.h
index 71e976a81..9fe9ef90a 100644
--- a/libtransport/includes/hicn/transport/portability/c_portability.h
+++ b/libtransport/includes/hicn/transport/portability/c_portability.h
@@ -33,4 +33,4 @@
#define TRANSPORT_ALWAYS_INLINE inline __attribute__((__always_inline__))
#else
#define TRANSPORT_ALWAYS_INLINE inline
-#endif \ No newline at end of file
+#endif
diff --git a/libtransport/includes/hicn/transport/portability/platform.h b/libtransport/includes/hicn/transport/portability/platform.h
new file mode 100644
index 000000000..282d27740
--- /dev/null
+++ b/libtransport/includes/hicn/transport/portability/platform.h
@@ -0,0 +1,108 @@
+/*
+ * 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
+
+/*
+ * Extract the "MACINTOSH" flag from the compiler.
+ */
+#if defined(__APPLE__)
+#define UNIX
+#define MACINTOSH
+#endif
+
+/*
+ * Extract the "SUNOS" flag from the compiler.
+ */
+#if defined(sun)
+#define UNIX
+#define SUNOS
+#endif
+
+/*
+ * Extract the "LINUX" flag from compiler.
+ */
+#ifdef __linux__
+#define UNIX
+#define LINUX
+#endif
+
+/*
+ * Extract the "ANDROID" flag from compiler.
+ */
+#ifdef __ANDROID__
+#define UNIX
+#define LINUX
+#ifndef ANDROID
+#define ANDROID
+#endif
+#endif
+
+/*
+ * Extract the "BSD" flag from compiler.
+ */
+#if defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || \
+ defined(__OpenBSD__)
+#define OS_BSD
+#define UNIX
+#endif
+
+/*
+ * Extract the "MSDOS" flag from the compiler.
+ */
+#ifdef __MSDOS__
+#define MSDOS
+#undef UNIX
+#endif
+
+/*
+ * Extract the "WINDOWS" flag from the compiler.
+ */
+#if defined(_Windows) || defined(__WINDOWS__) || defined(__WIN32__) || \
+ defined(WIN32) || defined(__WINNT__) || defined(__NT__) || \
+ defined(_WIN32) || defined(_WIN64)
+#define WINDOWS
+#ifdef _MSC_VER
+#define MSV
+#if defined(DEBUG) || defined(DEBUGTRACE)
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#else
+#ifndef NDEBUG
+#define NDEBUG
+#endif
+#endif
+#else
+#undef MSV
+#endif
+#undef UNIX
+#undef MSDOS
+#endif
+
+/*
+ * Remove the WINDOWS flag when using MACINTOSH.
+ */
+#ifdef MACINTOSH
+#undef WINDOWS
+#endif
+
+/*
+ * Assume UNIX if not Windows, Macintosh or MSDOS.
+ */
+#if !defined(WINDOWS) && !defined(MACINTOSH) && !defined(MSDOS)
+#define UNIX
+#endif
diff --git a/libtransport/includes/hicn/transport/portability/portability.h b/libtransport/includes/hicn/transport/portability/portability.h
index 1d97a346e..539ce2d5a 100644
--- a/libtransport/includes/hicn/transport/portability/portability.h
+++ b/libtransport/includes/hicn/transport/portability/portability.h
@@ -22,8 +22,8 @@
#endif
#include <hicn/transport/portability/c_portability.h>
-
#include <string.h>
+
#include <cstddef>
namespace portability {
diff --git a/libtransport/includes/hicn/transport/portability/win_portability.h b/libtransport/includes/hicn/transport/portability/win_portability.h
index 65d949291..bfbe431d1 100644
--- a/libtransport/includes/hicn/transport/portability/win_portability.h
+++ b/libtransport/includes/hicn/transport/portability/win_portability.h
@@ -31,6 +31,7 @@
#include <winsock2.h>
#include <ws2ipdef.h>
#include <ws2tcpip.h>
+
#include <algorithm>
#define __ORDER_LITTLE_ENDIAN__ 0x41424344UL
diff --git a/libtransport/includes/hicn/transport/utils/CMakeLists.txt b/libtransport/includes/hicn/transport/utils/CMakeLists.txt
index 11a9b0f25..7094601f4 100644
--- a/libtransport/includes/hicn/transport/utils/CMakeLists.txt
+++ b/libtransport/includes/hicn/transport/utils/CMakeLists.txt
@@ -31,6 +31,11 @@ list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/fixed_block_allocator.h
${CMAKE_CURRENT_SOURCE_DIR}/event_thread.h
${CMAKE_CURRENT_SOURCE_DIR}/string_utils.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/file.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/shared_ptr_utils.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/move_wrapper.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/noncopyable.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/singleton.h
)
if(NOT WIN32)
diff --git a/libtransport/includes/hicn/transport/utils/conversions.h b/libtransport/includes/hicn/transport/utils/conversions.h
index 24b529206..52d3e3168 100644
--- a/libtransport/includes/hicn/transport/utils/conversions.h
+++ b/libtransport/includes/hicn/transport/utils/conversions.h
@@ -16,8 +16,8 @@
#pragma once
#include <hicn/transport/portability/portability.h>
-
#include <stdio.h>
+
#include <cstdint>
#include <string>
diff --git a/libtransport/includes/hicn/transport/utils/enum_iterator.h b/libtransport/includes/hicn/transport/utils/enum_iterator.h
new file mode 100644
index 000000000..5e108b088
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/enum_iterator.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#include <type_traits>
+
+template <typename C, C begin_val, C end_val>
+class Iterator {
+ typedef typename std::underlying_type<C>::type val_t;
+ int val;
+
+ public:
+ Iterator(const C& f) : val(static_cast<val_t>(f)) {}
+
+ Iterator() : val(static_cast<val_t>(begin_val)) {}
+
+ Iterator operator++() {
+ ++val;
+ return *this;
+ }
+
+ C operator*() { return static_cast<C>(val); }
+
+ Iterator begin() { return *this; } // default ctor is good
+
+ Iterator end() {
+ static const Iterator endIter = ++Iterator(end_val); // cache it
+ return endIter;
+ }
+
+ bool operator!=(const Iterator& i) { return val != i.val; }
+}; \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/event_thread.h b/libtransport/includes/hicn/transport/utils/event_thread.h
index 702c98f8d..bb6ab90ef 100644
--- a/libtransport/includes/hicn/transport/utils/event_thread.h
+++ b/libtransport/includes/hicn/transport/utils/event_thread.h
@@ -17,7 +17,11 @@
#include <hicn/transport/config.h>
#include <hicn/transport/errors/runtime_exception.h>
+#include <hicn/transport/utils/log.h>
+#ifndef ASIO_STANDALONE
+#define ASIO_STANDALONE
+#endif
#include <asio.hpp>
#include <memory>
#include <thread>
@@ -25,36 +29,58 @@
namespace utils {
class EventThread {
- private:
- // No copies
- EventThread(const EventThread&) = delete; // non construction-copyable
- EventThread& operator=(const EventThread&) = delete; // non copyable
-
public:
- explicit EventThread(asio::io_service& io_service)
+ EventThread(asio::io_service& io_service, bool detached = false)
: internal_io_service_(nullptr),
- io_service_(io_service),
+ io_service_(std::ref(io_service)),
work_(std::make_unique<asio::io_service::work>(io_service_)),
- thread_(nullptr) {
+ thread_(nullptr),
+ detached_(detached) {
run();
}
- explicit EventThread()
+ EventThread(bool detached = false)
: internal_io_service_(std::make_unique<asio::io_service>()),
- io_service_(*internal_io_service_),
+ io_service_(std::ref(*internal_io_service_)),
work_(std::make_unique<asio::io_service::work>(io_service_)),
- thread_(nullptr) {
+ thread_(nullptr),
+ detached_(detached) {
run();
}
+ EventThread(const EventThread&) = delete;
+ EventThread& operator=(const EventThread&) = delete;
+
+ EventThread(EventThread&& other)
+ : internal_io_service_(std::move(other.internal_io_service_)),
+ io_service_(std::move(other.io_service_)),
+ work_(std::move(other.work_)),
+ thread_(std::move(other.thread_)),
+ detached_(std::move(other.detached_)) {}
+
+ EventThread& operator=(EventThread&& other) {
+ internal_io_service_ = std::move(other.internal_io_service_);
+ io_service_ = std::move(other.io_service_);
+ work_ = std::move(other.work_);
+ thread_ = std::move(other.thread_);
+ detached_ = other.detached_;
+
+ return *this;
+ }
+
~EventThread() { stop(); }
void run() {
if (stopped()) {
- io_service_.reset();
+ io_service_.get().stopped();
}
- thread_ = std::make_unique<std::thread>([this]() { io_service_.run(); });
+ thread_ =
+ std::make_unique<std::thread>([this]() { io_service_.get().run(); });
+
+ if (detached_) {
+ thread_->detach();
+ }
}
std::thread::id getThreadId() const {
@@ -67,14 +93,12 @@ class EventThread {
template <typename Func>
void add(Func&& f) {
- // If the function f
- // TODO USe post in mac os, asio->post in xenial
- io_service_.post(std::forward<Func&&>(f));
+ io_service_.get().post(std::forward<Func&&>(f));
}
template <typename Func>
void tryRunHandlerNow(Func&& f) {
- io_service_.dispatch(std::forward<Func&&>(f));
+ io_service_.get().dispatch(std::forward<Func&&>(f));
}
void stop() {
@@ -87,15 +111,16 @@ class EventThread {
thread_.reset();
}
- bool stopped() { return io_service_.stopped(); }
+ bool stopped() { return io_service_.get().stopped(); }
asio::io_service& getIoService() { return io_service_; }
private:
std::unique_ptr<asio::io_service> internal_io_service_;
- asio::io_service& io_service_;
+ std::reference_wrapper<asio::io_service> io_service_;
std::unique_ptr<asio::io_service::work> work_;
std::unique_ptr<std::thread> thread_;
+ bool detached_;
};
} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/file.h b/libtransport/includes/hicn/transport/utils/file.h
new file mode 100644
index 000000000..4c73f33e8
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/file.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+#include <sys/stat.h>
+
+namespace utils {
+
+class File {
+ public:
+ static inline bool exists(const std::string& name) {
+ struct stat buffer;
+ return (stat(name.c_str(), &buffer) == 0);
+ }
+};
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h b/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h
index 1ade1516e..b1df36493 100644
--- a/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h
+++ b/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h
@@ -5,104 +5,99 @@
#pragma once
#include <hicn/transport/portability/c_portability.h>
+#include <hicn/transport/utils/singleton.h>
#include <hicn/transport/utils/spinlock.h>
-
#include <stdint.h>
+
+#include <cassert>
#include <cstdlib>
#include <memory>
-#include <cassert>
namespace utils {
-template <std::size_t DEFAULT_SIZE = 512, std::size_t OBJECTS = 4096>
-class FixedBlockAllocator {
- FixedBlockAllocator(std::size_t size = DEFAULT_SIZE,
- std::size_t objects = OBJECTS)
- : block_size_(size < sizeof(void*) ? sizeof(long*) : size),
- object_size_(size),
- max_objects_(objects),
- p_head_(NULL),
- pool_index_(0),
- block_count_(0),
- blocks_in_use_(0),
- allocations_(0),
- deallocations_(0) {
- p_pool_ = (uint8_t*)new uint8_t[block_size_ * max_objects_];
- }
+template <std::size_t SIZE = 512, std::size_t OBJECTS = 4096>
+class FixedBlockAllocator
+ : public utils::Singleton<FixedBlockAllocator<SIZE, OBJECTS>> {
+ friend class utils::Singleton<FixedBlockAllocator<SIZE, OBJECTS>>;
public:
- static FixedBlockAllocator* getInstance() {
- if (!instance_) {
- instance_ = std::unique_ptr<FixedBlockAllocator>(
- new FixedBlockAllocator(DEFAULT_SIZE, OBJECTS));
+ ~FixedBlockAllocator() {
+ for (auto& p : p_pools_) {
+ delete[] p;
}
-
- return instance_.get();
}
- ~FixedBlockAllocator() { delete[] p_pool_; }
-
- TRANSPORT_ALWAYS_INLINE void* allocateBlock(size_t size = DEFAULT_SIZE) {
- assert(size <= DEFAULT_SIZE);
+ void* allocateBlock(size_t size = SIZE) {
+ assert(size <= SIZE);
uint32_t index;
+ SpinLock::Acquire locked(lock_);
void* p_block = pop();
if (!p_block) {
- if (pool_index_ < max_objects_) {
- {
- SpinLock::Acquire locked(lock_);
- index = pool_index_++;
- }
- p_block = (void*)(p_pool_ + (index * block_size_));
- } else {
- // TODO Consider increasing pool here instead of throwing an exception
- throw std::runtime_error("No more memory available from packet pool!");
+ if (TRANSPORT_EXPECT_FALSE(current_pool_index_ >= max_objects_)) {
+ // Allocate new memory block
+ TRANSPORT_LOGV("Allocating new block of %zu size", SIZE * OBJECTS);
+ p_pools_.emplace_front(
+ new typename std::aligned_storage<SIZE>::type[max_objects_]);
+ // reset current_pool_index_
+ current_pool_index_ = 0;
}
- }
- blocks_in_use_++;
- allocations_++;
+ auto& latest = p_pools_.front();
+ index = current_pool_index_++;
+ blocks_in_use_++;
+ allocations_++;
+ p_block = (void*)&latest[index];
+ }
return p_block;
}
- TRANSPORT_ALWAYS_INLINE void deallocateBlock(void* pBlock) {
+ void deallocateBlock(void* pBlock) {
+ SpinLock::Acquire locked(lock_);
push(pBlock);
- {
- SpinLock::Acquire locked(lock_);
- blocks_in_use_--;
- deallocations_++;
- }
+ blocks_in_use_--;
+ deallocations_++;
}
- TRANSPORT_ALWAYS_INLINE std::size_t blockSize() { return block_size_; }
+ public:
+ std::size_t blockSize() { return block_size_; }
- TRANSPORT_ALWAYS_INLINE uint32_t blockCount() { return block_count_; }
+ uint32_t blockCount() { return block_count_; }
- TRANSPORT_ALWAYS_INLINE uint32_t blocksInUse() { return blocks_in_use_; }
+ uint32_t blocksInUse() { return blocks_in_use_; }
- TRANSPORT_ALWAYS_INLINE uint32_t allocations() { return allocations_; }
+ uint32_t allocations() { return allocations_; }
- TRANSPORT_ALWAYS_INLINE uint32_t deallocations() { return deallocations_; }
+ uint32_t deallocations() { return deallocations_; }
private:
- TRANSPORT_ALWAYS_INLINE void push(void* p_memory) {
+ FixedBlockAllocator()
+ : block_size_(SIZE),
+ object_size_(SIZE),
+ max_objects_(OBJECTS),
+ p_head_(NULL),
+ current_pool_index_(0),
+ block_count_(0),
+ blocks_in_use_(0),
+ allocations_(0),
+ deallocations_(0) {
+ static_assert(SIZE >= sizeof(long*), "SIZE must be at least 8 bytes");
+ p_pools_.emplace_front(
+ new typename std::aligned_storage<SIZE>::type[max_objects_]);
+ }
+
+ void push(void* p_memory) {
Block* p_block = (Block*)p_memory;
- {
- SpinLock::Acquire locked(lock_);
- p_block->p_next = p_head_;
- p_head_ = p_block;
- }
+ p_block->p_next = p_head_;
+ p_head_ = p_block;
}
- TRANSPORT_ALWAYS_INLINE void* pop() {
+ void* pop() {
Block* p_block = nullptr;
- {
- SpinLock::Acquire locked(lock_);
- if (p_head_) {
- p_block = p_head_;
- p_head_ = p_head_->p_next;
- }
+ if (p_head_) {
+ p_block = p_head_;
+ p_head_ = p_head_->p_next;
}
return (void*)p_block;
@@ -119,8 +114,8 @@ class FixedBlockAllocator {
const std::size_t max_objects_;
Block* p_head_;
- uint8_t* p_pool_;
- uint32_t pool_index_;
+ uint32_t current_pool_index_;
+ std::list<typename std::aligned_storage<SIZE>::type*> p_pools_;
uint32_t block_count_;
uint32_t blocks_in_use_;
uint32_t allocations_;
@@ -133,4 +128,88 @@ template <std::size_t A, std::size_t B>
std::unique_ptr<FixedBlockAllocator<A, B>>
FixedBlockAllocator<A, B>::instance_ = nullptr;
+/**
+ * STL Allocator trait to be used with allocate_shared.
+ */
+template <typename T, typename Pool>
+class STLAllocator {
+ /**
+ * If STLAllocator is rebound to another type (!= T) using copy constructor,
+ * we may need to access private members of the source allocator to copy
+ * memory and pool.
+ */
+ template <typename U, typename P>
+ friend class STLAllocator;
+
+ public:
+ using size_type = std::size_t;
+ using difference_type = ptrdiff_t;
+ using pointer = T*;
+ using const_pointer = const T*;
+ using reference = T&;
+ using const_reference = const T&;
+ using value_type = T;
+
+ STLAllocator(pointer memory, Pool* memory_pool)
+ : memory_(memory), pool_(memory_pool) {
+ TRANSPORT_LOGV("Creating allocator. This: %p, memory: %p, memory_pool: %p",
+ this, memory, memory_pool);
+ }
+
+ ~STLAllocator() {}
+
+ template <typename U>
+ STLAllocator(const STLAllocator<U, Pool>& other) {
+ memory_ = other.memory_;
+ pool_ = other.pool_;
+ }
+
+ template <typename U>
+ struct rebind {
+ typedef STLAllocator<U, Pool> other;
+ };
+
+ pointer address(reference x) const { return &x; }
+ const_pointer address(const_reference x) const { return &x; }
+
+ pointer allocate(size_type n, pointer hint = 0) {
+ TRANSPORT_LOGV(
+ "Allocating memory (%zu). This: %p, memory: %p, memory_pool: %p", n,
+ this, memory_, pool_);
+ return static_cast<pointer>(memory_);
+ }
+
+ void deallocate(pointer p, size_type n) {
+ TRANSPORT_LOGV("Deallocating memory. This: %p, memory: %p, memory_pool: %p",
+ this, memory_, pool_);
+ pool_->deallocateBlock(memory_);
+ }
+
+ template <typename... Args>
+ void construct(pointer p, Args&&... args) {
+ new (static_cast<pointer>(p)) T(std::forward<Args>(args)...);
+ }
+
+ void destroy(pointer p) {
+ TRANSPORT_LOGV("Destroying object. This: %p, memory: %p, memory_pool: %p",
+ this, memory_, pool_);
+ p->~T();
+ }
+
+ private:
+ void* memory_;
+ Pool* pool_;
+};
+
+template <typename T, typename U, typename V>
+inline bool operator==(const STLAllocator<T, V>&, const STLAllocator<U, V>&) {
+ return true;
+}
+
+template <typename T, typename U, typename V>
+inline bool operator!=(const STLAllocator<T, V>& a,
+ const STLAllocator<U, V>& b) {
+ return !(a == b);
+}
+
} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/linux.h b/libtransport/includes/hicn/transport/utils/linux.h
index 5820528e1..105196fd2 100644
--- a/libtransport/includes/hicn/transport/utils/linux.h
+++ b/libtransport/includes/hicn/transport/utils/linux.h
@@ -17,14 +17,14 @@
#ifdef __linux__
+#include <arpa/inet.h>
#include <hicn/transport/portability/portability.h>
#include <hicn/transport/utils/log.h>
-
-#include <arpa/inet.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <stdio.h>
#include <sys/socket.h>
+
#include <string>
#define LINK_LOCAL_PREFIX 0xfe80
diff --git a/libtransport/includes/hicn/transport/utils/membuf.h b/libtransport/includes/hicn/transport/utils/membuf.h
index 9fc37dd25..0db87e9dd 100644
--- a/libtransport/includes/hicn/transport/utils/membuf.h
+++ b/libtransport/includes/hicn/transport/utils/membuf.h
@@ -23,6 +23,7 @@
#include <hicn/transport/portability/portability.h>
#include <hicn/transport/utils/branch_prediction.h>
+#include <stdlib.h>
#include <atomic>
#include <cassert>
@@ -35,8 +36,6 @@
#include <type_traits>
#include <vector>
-#include <stdlib.h>
-
#ifndef _WIN32
TRANSPORT_GNU_DISABLE_WARNING("-Wshadow")
#endif
@@ -50,6 +49,8 @@ class MemBuf {
enum TakeOwnershipOp { TAKE_OWNERSHIP };
enum CopyBufferOp { COPY_BUFFER };
+ using Ptr = std::shared_ptr<MemBuf>;
+
typedef void (*FreeFunction)(void* buf, void* userData);
static std::unique_ptr<MemBuf> create(std::size_t capacity);
@@ -106,13 +107,14 @@ class MemBuf {
FreeFunction freeFn = nullptr, void* userData = nullptr,
bool freeOnError = true);
- static std::unique_ptr<MemBuf> wrapBuffer(const void* buf,
+ static std::unique_ptr<MemBuf> wrapBuffer(const void* buf, std::size_t length,
std::size_t capacity);
- static MemBuf wrapBufferAsValue(const void* buf,
+ static MemBuf wrapBufferAsValue(const void* buf, std::size_t length,
std::size_t capacity) noexcept;
- MemBuf(WrapBufferOp op, const void* buf, std::size_t capacity) noexcept;
+ MemBuf(WrapBufferOp op, const void* buf, std::size_t length,
+ std::size_t capacity) noexcept;
/**
* Convenience function to create a new MemBuf object that copies data from a
@@ -147,6 +149,8 @@ class MemBuf {
std::size_t length() const { return length_; }
+ void setLength(std::size_t length) { length_ = length; }
+
std::size_t headroom() const { return std::size_t(data_ - buffer()); }
std::size_t tailroom() const { return std::size_t(bufferEnd() - tail()); }
@@ -689,6 +693,18 @@ class MemBuf {
void* userData = nullptr,
bool freeOnError = true);
+ /**
+ * Ensure the current MemBuf can hold at least capacity bytes and its
+ * memory is contiguous
+ */
+ bool ensureCapacity(std::size_t capacity);
+
+ /**
+ * Ensure packet buffer can hold at least 1500 bytes in contiguous memory and
+ * fill unused memory with placeholder
+ */
+ bool ensureCapacityAndFillUnused(std::size_t capacity, uint8_t placeholder);
+
/*
* Overridden operator new and delete.
* These perform specialized memory management to help support
@@ -700,6 +716,12 @@ class MemBuf {
void operator delete(void* ptr);
void operator delete(void* ptr, void* placement);
+ /**
+ * Override operator == and !=
+ */
+ bool operator ==(const MemBuf &other);
+ bool operator !=(const MemBuf &other);
+
// /**
// * Iteration support: a chain of MemBufs may be iterated through using
// * STL-style iterators over const ByteRanges. Iterators are only
diff --git a/libtransport/includes/hicn/transport/utils/move_wrapper.h b/libtransport/includes/hicn/transport/utils/move_wrapper.h
new file mode 100644
index 000000000..3aba345d6
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/move_wrapper.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright 2017 Facebook, Inc.
+ *
+ * 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 <type_traits>
+
+namespace utils {
+
+template <typename F>
+struct MoveWrapper : F {
+ MoveWrapper(F&& f) : F(std::move(f)) {}
+
+ MoveWrapper(MoveWrapper&&) = default;
+ MoveWrapper& operator=(MoveWrapper&&) = default;
+
+ MoveWrapper(const MoveWrapper&);
+ MoveWrapper& operator=(const MoveWrapper&);
+};
+
+template <typename T>
+auto moveHandler(T&& t) -> MoveWrapper<typename std::decay<T>::type> {
+ return std::move(t);
+}
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/noncopyable.h b/libtransport/includes/hicn/transport/utils/noncopyable.h
new file mode 100644
index 000000000..83923e647
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/noncopyable.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017-2019 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
+
+namespace utils {
+
+class NonCopyable {
+ protected:
+ NonCopyable() = default;
+ ~NonCopyable() = default;
+
+ NonCopyable(const NonCopyable&) = delete;
+ NonCopyable& operator=(const NonCopyable&) = delete;
+};
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/object_pool.h b/libtransport/includes/hicn/transport/utils/object_pool.h
index f78bd2aa2..a5e8b2eef 100644
--- a/libtransport/includes/hicn/transport/utils/object_pool.h
+++ b/libtransport/includes/hicn/transport/utils/object_pool.h
@@ -17,6 +17,7 @@
// TODO
#include <hicn/transport/utils/branch_prediction.h>
+#include <hicn/transport/utils/log.h>
#include <hicn/transport/utils/spinlock.h>
#include <deque>
@@ -33,6 +34,7 @@ class ObjectPool {
void operator()(T *t) {
if (pool_) {
+ TRANSPORT_LOGV("Back in pool");
pool_->add(t);
} else {
delete t;
@@ -44,10 +46,13 @@ class ObjectPool {
};
public:
- using Ptr = std::unique_ptr<T, ObjectDeleter>;
+ using Ptr = std::shared_ptr<T>;
ObjectPool() : destructor_(false) {}
+ // No copies
+ ObjectPool(const ObjectPool &other) = delete;
+
~ObjectPool() {
destructor_ = true;
for (auto &ptr : object_pool_) {
@@ -55,12 +60,17 @@ class ObjectPool {
}
}
+ bool empty() {
+ utils::SpinLock::Acquire locked(object_pool_lock_);
+ return object_pool_.empty();
+ }
+
std::pair<bool, Ptr> get() {
+ utils::SpinLock::Acquire locked(object_pool_lock_);
if (object_pool_.empty()) {
- return std::make_pair<bool, Ptr>(false, makePtr(nullptr));
+ return std::make_pair<bool, Ptr>(false, nullptr);
}
- utils::SpinLock::Acquire locked(object_pool_lock_);
auto ret = std::move(object_pool_.front());
object_pool_.pop_front();
return std::make_pair<bool, Ptr>(true, std::move(ret));
@@ -70,7 +80,7 @@ class ObjectPool {
utils::SpinLock::Acquire locked(object_pool_lock_);
if (TRANSPORT_EXPECT_TRUE(!destructor_)) {
- object_pool_.emplace_back(makePtr(object));
+ object_pool_.emplace_front(makePtr(object));
} else {
delete object;
}
@@ -79,12 +89,9 @@ class ObjectPool {
Ptr makePtr(T *object) { return Ptr(object, ObjectDeleter(this)); }
private:
- // No copies
- ObjectPool(const ObjectPool &other) = delete;
-
utils::SpinLock object_pool_lock_;
std::deque<Ptr> object_pool_;
- bool destructor_;
+ std::atomic<bool> destructor_;
};
-} // namespace utils \ No newline at end of file
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/shared_ptr_utils.h b/libtransport/includes/hicn/transport/utils/shared_ptr_utils.h
new file mode 100644
index 000000000..3387997b5
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/shared_ptr_utils.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ */
+
+#pragma once
+
+#include <memory>
+
+namespace utils {
+
+template <typename Base>
+inline std::shared_ptr<Base> shared_from_base(
+ std::enable_shared_from_this<Base>* base) {
+ return base->shared_from_this();
+}
+
+template <typename Base>
+inline std::shared_ptr<const Base> shared_from_base(
+ std::enable_shared_from_this<Base> const* base) {
+ return base->shared_from_this();
+}
+
+template <typename That>
+inline std::shared_ptr<That> shared_from(That* that) {
+ return std::static_pointer_cast<That>(shared_from_base(that));
+}
+
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/singleton.h b/libtransport/includes/hicn/transport/utils/singleton.h
new file mode 100644
index 000000000..7fd8b912f
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/singleton.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017-2019 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/utils/noncopyable.h>
+
+namespace utils {
+
+template <typename T>
+class Singleton {
+ public:
+ static T& getInstance() {
+ static T instance;
+ return instance;
+ }
+
+ protected:
+ Singleton() {}
+ ~Singleton() {}
+
+ public:
+ Singleton(Singleton const&) = delete;
+ Singleton& operator=(Singleton const&) = delete;
+};
+
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/string_utils.h b/libtransport/includes/hicn/transport/utils/string_utils.h
index bfda816f1..313c28cc6 100644
--- a/libtransport/includes/hicn/transport/utils/string_utils.h
+++ b/libtransport/includes/hicn/transport/utils/string_utils.h
@@ -72,4 +72,4 @@ static inline std::string trim_copy(std::string s) {
return s;
}
-} \ No newline at end of file
+} // namespace utils \ No newline at end of file