summaryrefslogtreecommitdiffstats
path: root/libtransport/includes
diff options
context:
space:
mode:
authorMauro Sardara <msardara@cisco.com>2020-02-21 11:52:28 +0100
committerMauro Sardara <msardara@cisco.com>2020-02-26 13:19:16 +0100
commitf4433f28b509a9f67ca85d79000ccf9c2f4b7a24 (patch)
tree0f754bc9d8222f3ace11849165753acd85be3b38 /libtransport/includes
parent0e7669445b6be1163189521eabed7dd0124043c8 (diff)
[HICN-534] Major rework on libtransport organization
Change-Id: I361b83a18b4fd59be136d5f0817fc28e17e89884 Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'libtransport/includes')
-rw-r--r--libtransport/includes/hicn/transport/CMakeLists.txt38
-rw-r--r--libtransport/includes/hicn/transport/core/CMakeLists.txt25
-rw-r--r--libtransport/includes/hicn/transport/core/content_object.h77
-rw-r--r--libtransport/includes/hicn/transport/core/interest.h71
-rw-r--r--libtransport/includes/hicn/transport/core/name.h142
-rw-r--r--libtransport/includes/hicn/transport/core/packet.h203
-rw-r--r--libtransport/includes/hicn/transport/core/payload_type.h29
-rw-r--r--libtransport/includes/hicn/transport/core/prefix.h80
-rw-r--r--libtransport/includes/hicn/transport/errors/CMakeLists.txt30
-rw-r--r--libtransport/includes/hicn/transport/errors/errors.h24
-rw-r--r--libtransport/includes/hicn/transport/errors/indexing_exception.h31
-rw-r--r--libtransport/includes/hicn/transport/errors/invalid_ip_address_exception.h31
-rw-r--r--libtransport/includes/hicn/transport/errors/malformed_ahpacket_exception.h31
-rw-r--r--libtransport/includes/hicn/transport/errors/malformed_name_exception.h31
-rw-r--r--libtransport/includes/hicn/transport/errors/malformed_packet_exception.h29
-rw-r--r--libtransport/includes/hicn/transport/errors/not_implemented_exception.h30
-rw-r--r--libtransport/includes/hicn/transport/errors/null_pointer_exception.h31
-rw-r--r--libtransport/includes/hicn/transport/errors/runtime_exception.h32
-rw-r--r--libtransport/includes/hicn/transport/errors/tokenizer_exception.h31
-rw-r--r--libtransport/includes/hicn/transport/errors/unexpected_manifest_exception.h31
-rw-r--r--libtransport/includes/hicn/transport/http/CMakeLists.txt25
-rw-r--r--libtransport/includes/hicn/transport/http/client_connection.h80
-rw-r--r--libtransport/includes/hicn/transport/http/default_values.h32
-rw-r--r--libtransport/includes/hicn/transport/http/facade.h20
-rw-r--r--libtransport/includes/hicn/transport/http/message.h70
-rw-r--r--libtransport/includes/hicn/transport/http/request.h56
-rw-r--r--libtransport/includes/hicn/transport/http/response.h58
-rw-r--r--libtransport/includes/hicn/transport/interfaces/CMakeLists.txt35
-rw-r--r--libtransport/includes/hicn/transport/interfaces/callbacks.h116
-rw-r--r--libtransport/includes/hicn/transport/interfaces/p2psecure_socket_consumer.h32
-rw-r--r--libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h36
-rw-r--r--libtransport/includes/hicn/transport/interfaces/publication_options.h43
-rw-r--r--libtransport/includes/hicn/transport/interfaces/rtc_socket_producer.h32
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_consumer.h298
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h69
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_options_keys.h118
-rw-r--r--libtransport/includes/hicn/transport/interfaces/socket_producer.h149
-rw-r--r--libtransport/includes/hicn/transport/interfaces/statistics.h121
-rw-r--r--libtransport/includes/hicn/transport/interfaces/verification_policy.h33
-rw-r--r--libtransport/includes/hicn/transport/portability/CMakeLists.txt31
-rw-r--r--libtransport/includes/hicn/transport/portability/c_portability.h36
-rw-r--r--libtransport/includes/hicn/transport/portability/portability.h50
-rw-r--r--libtransport/includes/hicn/transport/portability/win_portability.h42
-rw-r--r--libtransport/includes/hicn/transport/security/CMakeLists.txt27
-rw-r--r--libtransport/includes/hicn/transport/security/crypto_hash.h119
-rw-r--r--libtransport/includes/hicn/transport/security/crypto_hash_type.h31
-rw-r--r--libtransport/includes/hicn/transport/security/crypto_hasher.h68
-rw-r--r--libtransport/includes/hicn/transport/security/crypto_suite.h36
-rw-r--r--libtransport/includes/hicn/transport/security/identity.h63
-rw-r--r--libtransport/includes/hicn/transport/security/key_id.h25
-rw-r--r--libtransport/includes/hicn/transport/security/signer.h90
-rw-r--r--libtransport/includes/hicn/transport/security/verifier.h103
-rw-r--r--libtransport/includes/hicn/transport/utils/CMakeLists.txt39
-rw-r--r--libtransport/includes/hicn/transport/utils/array.h62
-rw-r--r--libtransport/includes/hicn/transport/utils/branch_prediction.h27
-rw-r--r--libtransport/includes/hicn/transport/utils/chrono_typedefs.h27
-rw-r--r--libtransport/includes/hicn/transport/utils/conversions.h37
-rw-r--r--libtransport/includes/hicn/transport/utils/daemonizator.h30
-rw-r--r--libtransport/includes/hicn/transport/utils/hash.h101
-rw-r--r--libtransport/includes/hicn/transport/utils/linux.h64
-rw-r--r--libtransport/includes/hicn/transport/utils/literals.h55
-rw-r--r--libtransport/includes/hicn/transport/utils/log.h1057
-rw-r--r--libtransport/includes/hicn/transport/utils/membuf.h921
-rw-r--r--libtransport/includes/hicn/transport/utils/object_pool.h90
-rw-r--r--libtransport/includes/hicn/transport/utils/ring_buffer.h129
-rw-r--r--libtransport/includes/hicn/transport/utils/spinlock.h53
-rw-r--r--libtransport/includes/hicn/transport/utils/string_tokenizer.h35
-rw-r--r--libtransport/includes/hicn/transport/utils/uri.h47
68 files changed, 5945 insertions, 0 deletions
diff --git a/libtransport/includes/hicn/transport/CMakeLists.txt b/libtransport/includes/hicn/transport/CMakeLists.txt
new file mode 100644
index 000000000..1099e701d
--- /dev/null
+++ b/libtransport/includes/hicn/transport/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Copyright (c) 2017-2020 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)
+
+include(GNUInstallDirs)
+
+set(ASIO_STANDALONE 1)
+
+add_subdirectory(core)
+add_subdirectory(errors)
+add_subdirectory(http)
+add_subdirectory(interfaces)
+add_subdirectory(portability)
+add_subdirectory(security)
+add_subdirectory(utils)
+
+set(LIBTRANSPORT_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}/../.. ""
+ CACHE INTERNAL
+ "" FORCE
+)
+
+set(LIBHICNTRANSPORT_TO_INSTALL_HEADER_FILES
+ ${HEADER_FILES} ""
+ CACHE INTERNAL
+ "" FORCE
+) \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/core/CMakeLists.txt b/libtransport/includes/hicn/transport/core/CMakeLists.txt
new file mode 100644
index 000000000..cb10745ff
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/CMakeLists.txt
@@ -0,0 +1,25 @@
+# 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}/content_object.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/interest.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/name.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/packet.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/payload_type.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/prefix.h
+)
+
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ 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
new file mode 100644
index 000000000..5af548fe4
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/content_object.h
@@ -0,0 +1,77 @@
+/*
+ * 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/name.h>
+#include <hicn/transport/core/packet.h>
+
+namespace transport {
+
+namespace core {
+
+// This class is used just to transfer buffer pointers
+// without making a copy, as std::vector<> would do
+
+class ContentObject : public Packet {
+ public:
+ using Ptr = utils::ObjectPool<ContentObject>::Ptr;
+ using HICNContentObject = hicn_header_t;
+
+ ContentObject(Packet::Format format = HF_INET6_TCP);
+
+ ContentObject(const Name &name, Packet::Format format = HF_INET6_TCP);
+
+ ContentObject(const Name &name, hicn_format_t format, 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;
+
+ ContentObject(ContentObject &&content_object);
+
+ ~ContentObject() override;
+
+ void replace(MemBufPtr &&buffer) override;
+
+ const Name &getName() const override;
+
+ Name &getWritableName() override;
+
+ void setName(const Name &name) override;
+
+ void setName(Name &&name) override;
+
+ uint32_t getPathLabel() const;
+
+ ContentObject &setPathLabel(uint32_t path_label);
+
+ void setLocator(const ip_address_t &ip_address) override;
+
+ ip_address_t getLocator() const override;
+
+ void setLifetime(uint32_t lifetime) override;
+
+ uint32_t getLifetime() const override;
+
+ private:
+ void resetForHash() override;
+};
+
+} // end namespace core
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/core/interest.h b/libtransport/includes/hicn/transport/core/interest.h
new file mode 100644
index 000000000..f0c546a8e
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/interest.h
@@ -0,0 +1,71 @@
+/*
+ * 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/name.h>
+#include <hicn/transport/core/packet.h>
+
+namespace transport {
+
+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);
+
+ Interest(const uint8_t *buffer, std::size_t size);
+ Interest(MemBufPtr &&buffer);
+
+ /*
+ * Enforce zero-copy.
+ */
+ Interest(const Interest &other_interest) = delete;
+ Interest &operator=(const Interest &other_interest) = delete;
+
+ Interest(Interest &&other_interest);
+
+ ~Interest() override;
+
+ void replace(MemBufPtr &&buffer) override;
+
+ const Name &getName() const override;
+
+ Name &getWritableName() override;
+
+ void setName(const Name &name) override;
+
+ void setName(Name &&name) override;
+
+ void setLocator(const ip_address_t &ip_address) override;
+
+ ip_address_t getLocator() const override;
+
+ void setLifetime(uint32_t lifetime) override;
+
+ uint32_t getLifetime() const override;
+
+ private:
+ void resetForHash() override;
+};
+
+} // end namespace core
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/core/name.h b/libtransport/includes/hicn/transport/core/name.h
new file mode 100644
index 000000000..ea72797ad
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/name.h
@@ -0,0 +1,142 @@
+/*
+ * 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/portability/portability.h>
+#include <hicn/transport/utils/branch_prediction.h>
+
+#include <list>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+extern "C" {
+#ifndef _WIN32
+TRANSPORT_CLANG_DISABLE_WARNING("-Wextern-c-compat")
+#endif
+#include <hicn/hicn.h>
+};
+
+#include <vector>
+
+namespace transport {
+
+namespace core {
+
+typedef struct sockaddr_in6 Sockaddr6;
+typedef struct sockaddr_in Sockaddr4;
+typedef struct sockaddr Sockaddr;
+
+enum class HashAlgorithm : uint8_t;
+
+class Name {
+ friend class Packet;
+ friend class ContentObject;
+ friend class Interest;
+
+ static const uint32_t standard_name_string_length = 100;
+
+ public:
+ using NameStruct = hicn_name_t;
+ using Type = hicn_name_type_t;
+
+ Name();
+
+ /**
+ * @brief Create name
+ * @param name The null-terminated URI string
+ */
+ Name(const char *name, uint32_t segment);
+
+ Name(int family, const uint8_t *ip_address, std::uint32_t suffix = 0);
+
+ Name(const std::string &uri, uint32_t segment);
+
+ Name(const std::string &uri);
+
+ Name(const Name &name);
+
+ Name &operator=(const Name &name);
+
+ bool operator==(const Name &name) const;
+
+ bool operator!=(const Name &name) const;
+
+ operator bool() const;
+
+ std::string toString() const;
+
+ bool equals(const Name &name, bool consider_segment = true) const;
+
+ uint32_t getHash32(bool consider_suffix = true) const;
+
+ void clear();
+
+ Type getType() const;
+
+ uint32_t getSuffix() const;
+
+ std::shared_ptr<Sockaddr> getAddress() const;
+
+ Name &setSuffix(uint32_t seq_number);
+
+ ip_prefix_t toIpAddress() const;
+
+ void copyToDestination(uint8_t *destination,
+ bool include_suffix = false) const;
+
+ int getAddressFamily() const;
+
+ private:
+ TRANSPORT_ALWAYS_INLINE const NameStruct *getConstStructReference() const {
+ return &name_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE NameStruct *getStructReference() { return &name_; }
+
+ NameStruct name_;
+};
+
+std::ostream &operator<<(std::ostream &os, const Name &name);
+
+template <typename T>
+struct hash {};
+
+template <>
+struct hash<transport::core::Name> {
+ size_t operator()(const transport::core::Name &name) const;
+};
+
+template <typename T>
+struct compare2 {};
+
+template <>
+struct compare2<transport::core::Name> {
+ 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> {
+ size_t operator()(const transport::core::Name &name) const;
+};
+
+} // end namespace std
diff --git a/libtransport/includes/hicn/transport/core/packet.h b/libtransport/includes/hicn/transport/core/packet.h
new file mode 100644
index 000000000..e80912cbe
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/packet.h
@@ -0,0 +1,203 @@
+/*
+ * 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/name.h>
+#include <hicn/transport/core/payload_type.h>
+#include <hicn/transport/portability/portability.h>
+#include <hicn/transport/security/crypto_hasher.h>
+#include <hicn/transport/security/crypto_suite.h>
+#include <hicn/transport/security/key_id.h>
+#include <hicn/transport/utils/branch_prediction.h>
+#include <hicn/transport/utils/membuf.h>
+#include <hicn/transport/utils/object_pool.h>
+
+namespace utils {
+class Signer;
+class Verifier;
+} // namespace utils
+
+namespace transport {
+
+namespace core {
+
+/*
+ * Basic IP packet, modelled as circular chain of buffers:
+ * Header = H
+ * Payload = P
+ *
+ * H_0 --> H_1 --> H_2 --> P_0 --> P_1 --> P_2
+ * \_______________________________________|
+ */
+
+class Packet : public std::enable_shared_from_this<Packet> {
+ friend class utils::Signer;
+ friend class utils::Verifier;
+
+ public:
+ using MemBufPtr = std::shared_ptr<utils::MemBuf>;
+ using Format = hicn_format_t;
+ static constexpr size_t default_mtu = 1500;
+
+ /**
+ * Create new IP packet. Here we allocate just the header,
+ * the eventual payload will be added by prepending the payload buffer
+ * to the buffer chain whose the fist buffer is the header itself.
+ */
+ Packet(Format format = HF_UNSPEC);
+
+ /**
+ * Create new IP packet using raw buffer.
+ */
+ Packet(const uint8_t *buffer, std::size_t size);
+ Packet(MemBufPtr &&buffer);
+
+ /*
+ * Enforce zero-copy lifestyle.
+ */
+ Packet(const Packet &other) = delete;
+ Packet &operator=(const Packet &other) = delete;
+
+ /*
+ * Move constructor.
+ */
+ Packet(Packet &&other);
+
+ friend bool operator==(const Packet &l_packet, const Packet &r_packet);
+
+ virtual ~Packet();
+
+ static std::size_t getHeaderSizeFromFormat(Format format,
+ std::size_t signature_size = 0);
+
+ static std::size_t getHeaderSizeFromBuffer(Format format,
+ const uint8_t *buffer);
+
+ static std::size_t getPayloadSizeFromBuffer(Format format,
+ const uint8_t *buffer);
+
+ static bool isInterest(const uint8_t *buffer);
+
+ static Format getFormatFromBuffer(const uint8_t *buffer);
+
+ virtual void replace(MemBufPtr &&buffer);
+
+ std::size_t payloadSize() const;
+
+ std::size_t headerSize() const;
+
+ const std::shared_ptr<utils::MemBuf> acquireMemBufReference() const;
+
+ virtual const Name &getName() const = 0;
+
+ virtual Name &getWritableName() = 0;
+
+ virtual void setName(const Name &name) = 0;
+
+ virtual void setName(Name &&name) = 0;
+
+ virtual void setLifetime(uint32_t lifetime) = 0;
+
+ virtual uint32_t getLifetime() const = 0;
+
+ Packet &appendPayload(const uint8_t *buffer, std::size_t length);
+
+ Packet &appendPayload(std::unique_ptr<utils::MemBuf> &&payload);
+
+ 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;
+
+ Packet &updateLength(std::size_t length = 0);
+
+ PayloadType getPayloadType() const;
+
+ Packet &setPayloadType(PayloadType payload_type);
+
+ Format getFormat() const;
+
+ void dump() const;
+
+ virtual void setLocator(const ip_address_t &locator) = 0;
+
+ virtual ip_address_t getLocator() const = 0;
+
+ void setSignatureTimestamp(const uint64_t &timestamp);
+
+ uint64_t getSignatureTimestamp() const;
+
+ void setValidationAlgorithm(const utils::CryptoSuite &validation_algorithm);
+
+ utils::CryptoSuite getValidationAlgorithm() const;
+
+ void setKeyId(const utils::KeyId &key_id);
+
+ utils::KeyId getKeyId() const;
+
+ virtual utils::CryptoHash computeDigest(HashAlgorithm algorithm) const;
+
+ void setChecksum();
+
+ bool checkIntegrity() const;
+
+ Packet &setSyn();
+ Packet &resetSyn();
+ bool testSyn() const;
+ Packet &setAck();
+ Packet &resetAck();
+ bool testAck() const;
+ Packet &setRst();
+ Packet &resetRst();
+ bool testRst() const;
+ Packet &setFin();
+ Packet &resetFin();
+ bool testFin() const;
+ Packet &resetFlags();
+ std::string printFlags() const;
+
+ Packet &setSrcPort(uint16_t srcPort);
+ Packet &setDstPort(uint16_t dstPort);
+ uint16_t getSrcPort() const;
+ uint16_t getDstPort() const;
+
+ Packet &setTTL(uint8_t hops);
+ uint8_t getTTL() const;
+
+ void resetPayload();
+
+ private:
+ virtual void resetForHash() = 0;
+ void setSignatureSize(std::size_t size_bytes);
+ std::size_t getSignatureSize() const;
+ uint8_t *getSignature() const;
+ void separateHeaderPayload();
+
+ protected:
+ Name name_;
+ MemBufPtr packet_;
+ hicn_header_t *packet_start_;
+ utils::MemBuf *header_head_;
+ utils::MemBuf *payload_head_;
+ mutable Format format_;
+
+ static const core::Name base_name;
+};
+
+} // end namespace core
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/core/payload_type.h b/libtransport/includes/hicn/transport/core/payload_type.h
new file mode 100644
index 000000000..fa79db35a
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/payload_type.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 transport {
+
+namespace core {
+
+enum class PayloadType : uint16_t {
+ CONTENT_OBJECT = HPT_DATA,
+ MANIFEST = HPT_MANIFEST,
+};
+
+} // end namespace core
+
+} // end namespace transport \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/core/prefix.h b/libtransport/includes/hicn/transport/core/prefix.h
new file mode 100644
index 000000000..c3805f13f
--- /dev/null
+++ b/libtransport/includes/hicn/transport/core/prefix.h
@@ -0,0 +1,80 @@
+/*
+ * 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/name.h>
+
+namespace transport {
+
+namespace core {
+
+class Prefix {
+ public:
+ Prefix();
+
+ Prefix(const char *prefix);
+
+ Prefix(const std::string &prefix);
+
+ Prefix(std::string &&prefix);
+
+ Prefix(std::string &prefix, uint16_t prefix_length);
+
+ Prefix(const core::Name &content_name, uint16_t prefix_length);
+
+ std::unique_ptr<Sockaddr> toSockaddr();
+
+ uint16_t getPrefixLength();
+
+ Prefix &setPrefixLength(uint16_t prefix_length);
+
+ std::string getNetwork() const;
+
+ int contains(const ip_address_t &content_name) const;
+
+ int contains(const core::Name &content_name) const;
+
+ Name getName() const;
+
+ Name getRandomName() const;
+
+ Name getName(const core::Name &mask, const core::Name &components,
+ const core::Name &content_name) const;
+
+ Name mapName(const core::Name &content_name) const;
+
+ Prefix &setNetwork(std::string &network);
+
+ int getAddressFamily();
+
+ Prefix &setAddressFamily(int address_family);
+
+ Name makeRandomName() const;
+
+ ip_prefix_t &toIpPrefixStruct();
+
+ private:
+ static bool checkPrefixLengthAndAddressFamily(uint16_t prefix_length,
+ int family);
+
+ void buildPrefix(std::string &prefix, uint16_t prefix_length, int family);
+
+ ip_prefix_t ip_prefix_;
+};
+
+} // end namespace core
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/errors/CMakeLists.txt b/libtransport/includes/hicn/transport/errors/CMakeLists.txt
new file mode 100644
index 000000000..5b04ace10
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/CMakeLists.txt
@@ -0,0 +1,30 @@
+# 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}/not_implemented_exception.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/invalid_ip_address_exception.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/malformed_name_exception.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/errors.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/malformed_packet_exception.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/runtime_exception.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/tokenizer_exception.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/null_pointer_exception.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/malformed_ahpacket_exception.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/unexpected_manifest_exception.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/indexing_exception.h
+)
+
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/errors/errors.h b/libtransport/includes/hicn/transport/errors/errors.h
new file mode 100644
index 000000000..512e35736
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/errors.h
@@ -0,0 +1,24 @@
+/*
+ * 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/invalid_ip_address_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
diff --git a/libtransport/includes/hicn/transport/errors/indexing_exception.h b/libtransport/includes/hicn/transport/errors/indexing_exception.h
new file mode 100644
index 000000000..731314f0e
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/indexing_exception.h
@@ -0,0 +1,31 @@
+/*
+ * 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 <stdexcept>
+
+namespace errors {
+
+class IndexingException : public std::logic_error {
+ public:
+ IndexingException() : std::logic_error("") {}
+
+ virtual char const *what() const noexcept override {
+ return "Impossible to retrieve next index to download.";
+ }
+};
+
+} // end namespace errors
diff --git a/libtransport/includes/hicn/transport/errors/invalid_ip_address_exception.h b/libtransport/includes/hicn/transport/errors/invalid_ip_address_exception.h
new file mode 100644
index 000000000..60226f576
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/invalid_ip_address_exception.h
@@ -0,0 +1,31 @@
+/*
+ * 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 <stdexcept>
+
+namespace errors {
+
+class InvalidIpAddressException : public std::runtime_error {
+ public:
+ InvalidIpAddressException() : std::runtime_error("") {}
+
+ virtual char const *what() const noexcept override {
+ return "Malformed IP address.";
+ }
+};
+
+} // end namespace errors \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/errors/malformed_ahpacket_exception.h b/libtransport/includes/hicn/transport/errors/malformed_ahpacket_exception.h
new file mode 100644
index 000000000..f0cfe0b82
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/malformed_ahpacket_exception.h
@@ -0,0 +1,31 @@
+/*
+ * 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 <stdexcept>
+
+namespace errors {
+
+class MalformedAHPacketException : public std::runtime_error {
+ public:
+ MalformedAHPacketException() : std::runtime_error("") {}
+
+ virtual char const *what() const noexcept override {
+ return "Malformed AH packet.";
+ }
+};
+
+} // end namespace errors
diff --git a/libtransport/includes/hicn/transport/errors/malformed_name_exception.h b/libtransport/includes/hicn/transport/errors/malformed_name_exception.h
new file mode 100644
index 000000000..4ef45d2e8
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/malformed_name_exception.h
@@ -0,0 +1,31 @@
+/*
+ * 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 <stdexcept>
+
+namespace errors {
+
+class MalformedNameException : public std::runtime_error {
+ public:
+ MalformedNameException() : std::runtime_error("") {}
+
+ virtual char const *what() const noexcept override {
+ return "Malformed IP address.";
+ }
+};
+
+} // end namespace errors
diff --git a/libtransport/includes/hicn/transport/errors/malformed_packet_exception.h b/libtransport/includes/hicn/transport/errors/malformed_packet_exception.h
new file mode 100644
index 000000000..ec5c97e6e
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/malformed_packet_exception.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 <stdexcept>
+
+namespace errors {
+
+class MalformedPacketException : public std::runtime_error {
+ public:
+ MalformedPacketException() : std::runtime_error("") {}
+
+ char const *what() const noexcept override { return "Malformed IP packet."; }
+};
+
+} // end namespace errors
diff --git a/libtransport/includes/hicn/transport/errors/not_implemented_exception.h b/libtransport/includes/hicn/transport/errors/not_implemented_exception.h
new file mode 100644
index 000000000..e9869163d
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/not_implemented_exception.h
@@ -0,0 +1,30 @@
+/*
+ * 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 <stdexcept>
+
+namespace errors {
+
+class NotImplementedException : public std::logic_error {
+ public:
+ NotImplementedException() : std::logic_error("") {}
+ virtual char const *what() const noexcept override {
+ return "Function not yet implemented.";
+ }
+};
+
+} // end namespace errors
diff --git a/libtransport/includes/hicn/transport/errors/null_pointer_exception.h b/libtransport/includes/hicn/transport/errors/null_pointer_exception.h
new file mode 100644
index 000000000..bd06485ed
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/null_pointer_exception.h
@@ -0,0 +1,31 @@
+/*
+ * 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 <stdexcept>
+
+namespace errors {
+
+class NullPointerException : public std::runtime_error {
+ public:
+ NullPointerException() : std::runtime_error("") {}
+
+ char const *what() const noexcept override {
+ return "Null pointer exception.";
+ }
+};
+
+} // end namespace errors
diff --git a/libtransport/includes/hicn/transport/errors/runtime_exception.h b/libtransport/includes/hicn/transport/errors/runtime_exception.h
new file mode 100644
index 000000000..ba5128a7e
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/runtime_exception.h
@@ -0,0 +1,32 @@
+/*
+ * 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 <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+
+namespace errors {
+
+class RuntimeException : public std::runtime_error {
+ public:
+ RuntimeException() : std::runtime_error("") {}
+
+ RuntimeException(std::string what) : runtime_error(what){};
+};
+
+} // end namespace errors \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/errors/tokenizer_exception.h b/libtransport/includes/hicn/transport/errors/tokenizer_exception.h
new file mode 100644
index 000000000..76eda838e
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/tokenizer_exception.h
@@ -0,0 +1,31 @@
+/*
+ * 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 <stdexcept>
+
+namespace errors {
+
+class TokenizerException : public std::logic_error {
+ public:
+ TokenizerException() : std::logic_error("") {}
+
+ virtual char const *what() const noexcept override {
+ return "No more tokens available.";
+ }
+};
+
+} // end namespace errors
diff --git a/libtransport/includes/hicn/transport/errors/unexpected_manifest_exception.h b/libtransport/includes/hicn/transport/errors/unexpected_manifest_exception.h
new file mode 100644
index 000000000..6f71471e4
--- /dev/null
+++ b/libtransport/includes/hicn/transport/errors/unexpected_manifest_exception.h
@@ -0,0 +1,31 @@
+/*
+ * 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 <stdexcept>
+
+namespace errors {
+
+class UnexpectedManifestException : public std::logic_error {
+ public:
+ UnexpectedManifestException() : std::logic_error("") {}
+
+ virtual char const *what() const noexcept override {
+ return "Received unexpected manifest.";
+ }
+};
+
+} // end namespace errors
diff --git a/libtransport/includes/hicn/transport/http/CMakeLists.txt b/libtransport/includes/hicn/transport/http/CMakeLists.txt
new file mode 100644
index 000000000..9cf618c21
--- /dev/null
+++ b/libtransport/includes/hicn/transport/http/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright (c) 2017-2020 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}/client_connection.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/request.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/default_values.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/facade.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/response.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/message.h
+)
+
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/http/client_connection.h b/libtransport/includes/hicn/transport/http/client_connection.h
new file mode 100644
index 000000000..262756a09
--- /dev/null
+++ b/libtransport/includes/hicn/transport/http/client_connection.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017-2020 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/http/default_values.h>
+#include <hicn/transport/http/request.h>
+#include <hicn/transport/http/response.h>
+#include <hicn/transport/interfaces/socket_consumer.h>
+#include <hicn/transport/interfaces/socket_producer.h>
+#include <hicn/transport/utils/uri.h>
+
+#include <vector>
+
+namespace transport {
+
+namespace http {
+
+using namespace interface;
+using namespace core;
+
+class HTTPClientConnection {
+ static constexpr uint32_t max_buffer_capacity = 64 * 1024;
+
+ public:
+ class ReadBytesCallback {
+ public:
+ virtual void onBytesReceived(std::unique_ptr<utils::MemBuf> &&buffer) = 0;
+ virtual void onSuccess(std::size_t bytes) = 0;
+ virtual void onError(const std::error_code ec) = 0;
+ };
+
+ enum class RC : uint32_t { DOWNLOAD_FAILED, DOWNLOAD_SUCCESS };
+
+ HTTPClientConnection();
+
+ ~HTTPClientConnection();
+
+ RC get(const std::string &url, HTTPHeaders headers = {},
+ HTTPPayload &&payload = nullptr,
+ std::shared_ptr<HTTPResponse> response = nullptr,
+ ReadBytesCallback *callback = nullptr,
+ std::string ipv6_first_word = "b001");
+
+ RC sendRequest(const std::string &url, HTTPMethod method,
+ HTTPHeaders headers = {}, HTTPPayload &&payload = nullptr,
+ std::shared_ptr<HTTPResponse> response = nullptr,
+ ReadBytesCallback *callback = nullptr,
+ std::string ipv6_first_word = "b001");
+
+ std::shared_ptr<HTTPResponse> response();
+
+ HTTPClientConnection &stop();
+
+ interface::ConsumerSocket &getConsumer();
+
+ HTTPClientConnection &setTimeout(const std::chrono::seconds &timeout);
+
+ HTTPClientConnection &setCertificate(const std::string &cert_path);
+
+ private:
+ class Implementation;
+ Implementation *implementation_;
+};
+
+} // end namespace http
+
+} // end namespace transport \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/http/default_values.h b/libtransport/includes/hicn/transport/http/default_values.h
new file mode 100644
index 000000000..2d5a6b821
--- /dev/null
+++ b/libtransport/includes/hicn/transport/http/default_values.h
@@ -0,0 +1,32 @@
+/*
+ * 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>
+
+namespace transport {
+
+namespace http {
+
+namespace default_values {
+
+const uint16_t ipv6_first_word = 0xb001; // Network byte order
+
+} // namespace default_values
+
+} // namespace http
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/http/facade.h b/libtransport/includes/hicn/transport/http/facade.h
new file mode 100644
index 000000000..8a465ce94
--- /dev/null
+++ b/libtransport/includes/hicn/transport/http/facade.h
@@ -0,0 +1,20 @@
+/*
+ * 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/http/client_connection.h>
+
+namespace libl4 = transport; \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/http/message.h b/libtransport/includes/hicn/transport/http/message.h
new file mode 100644
index 000000000..b8756224f
--- /dev/null
+++ b/libtransport/includes/hicn/transport/http/message.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017-2020 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
+
+#ifdef _WIN32
+#include <hicn/transport/portability/win_portability.h>
+#endif
+
+#include <hicn/transport/utils/membuf.h>
+
+#include <map>
+#include <sstream>
+#include <vector>
+
+#define HTTP_VERSION "1.1"
+
+namespace transport {
+
+namespace http {
+
+typedef enum { GET, POST, PUT, PATCH, DELETE } HTTPMethod;
+
+static std::map<HTTPMethod, std::string> method_map = {
+ {GET, "GET"}, {POST, "POST"}, {PUT, "PUT"},
+ {PATCH, "PATCH"}, {DELETE, "DELETE"},
+};
+
+typedef std::map<std::string, std::string> HTTPHeaders;
+typedef std::unique_ptr<utils::MemBuf> HTTPPayload;
+
+class HTTPMessage {
+ public:
+ virtual ~HTTPMessage() = default;
+
+ const HTTPHeaders getHeaders() { return headers_; };
+
+ void coalescePayloadBuffer() {
+ auto it = headers_.find("Content-Length");
+ if (it != headers_.end()) {
+ auto content_length = std::stoul(it->second);
+ payload_->gather(content_length);
+ }
+ }
+
+ HTTPPayload &&getPayload() { return std::move(payload_); }
+
+ std::string getHttpVersion() const { return http_version_; };
+
+ protected:
+ HTTPHeaders headers_;
+ HTTPPayload payload_;
+ std::string http_version_;
+};
+
+} // end namespace http
+
+} // end namespace transport \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/http/request.h b/libtransport/includes/hicn/transport/http/request.h
new file mode 100644
index 000000000..54904d696
--- /dev/null
+++ b/libtransport/includes/hicn/transport/http/request.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017-2020 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/http/message.h>
+
+#include <map>
+#include <sstream>
+#include <vector>
+
+namespace transport {
+
+namespace http {
+
+class HTTPRequest : public HTTPMessage {
+ public:
+ HTTPRequest();
+ HTTPRequest(HTTPMethod method, const std::string &url,
+ const HTTPHeaders &headers, HTTPPayload &&payload);
+
+ void init(HTTPMethod method, const std::string &url,
+ const HTTPHeaders &headers, HTTPPayload &&payload);
+
+ std::string getQueryString() const;
+
+ std::string getPath() const;
+
+ std::string getProtocol() const;
+
+ std::string getLocator() const;
+
+ std::string getPort() const;
+
+ std::string getRequestString() const;
+
+ private:
+ std::string query_string_, path_, protocol_, locator_, port_;
+ std::string request_string_;
+};
+
+} // end namespace http
+
+} // end namespace transport \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/http/response.h b/libtransport/includes/hicn/transport/http/response.h
new file mode 100644
index 000000000..bab41acb8
--- /dev/null
+++ b/libtransport/includes/hicn/transport/http/response.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017-2020 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/http/message.h>
+#include <hicn/transport/utils/array.h>
+
+#include <map>
+#include <sstream>
+#include <vector>
+
+namespace transport {
+
+namespace http {
+
+class HTTPResponse : public HTTPMessage {
+ public:
+ HTTPResponse();
+
+ HTTPResponse(std::unique_ptr<utils::MemBuf> &&response);
+
+ void appendResponseChunk(std::unique_ptr<utils::MemBuf> &&response_chunk);
+
+ const std::string &getStatusCode() const;
+
+ const std::string &getStatusString() const;
+
+ void parse(std::unique_ptr<utils::MemBuf> &&response);
+
+ bool parseHeaders(std::unique_ptr<utils::MemBuf> &&buffer);
+
+ static std::size_t parseHeaders(const uint8_t *buffer, std::size_t size,
+ HTTPHeaders &headers,
+ std::string &http_version,
+ std::string &status_code,
+ std::string &status_string);
+
+ private:
+ std::string status_code_;
+ std::string status_string_;
+};
+
+} // end namespace http
+
+} // end namespace transport \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt b/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt
new file mode 100644
index 000000000..38e6143f0
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt
@@ -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.
+
+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}/statistics.h
+)
+
+if (${OPENSSL_VERSION} VERSION_EQUAL "1.1.1a" OR ${OPENSSL_VERSION} VERSION_GREATER "1.1.1a")
+ list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/p2psecure_socket_producer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/p2psecure_socket_consumer.h
+ )
+endif()
+
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE)
diff --git a/libtransport/includes/hicn/transport/interfaces/callbacks.h b/libtransport/includes/hicn/transport/interfaces/callbacks.h
new file mode 100644
index 000000000..6ae07797e
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/callbacks.h
@@ -0,0 +1,116 @@
+/*
+ * 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/interfaces/statistics.h>
+#include <hicn/transport/interfaces/verification_policy.h>
+
+#include <functional>
+#include <system_error>
+
+namespace utils {
+class MemBuf;
+}
+
+namespace transport {
+
+namespace protocol {
+
+class IcnObserver;
+
+} // namespace protocol
+
+namespace core {
+class ContentObject;
+class Interest;
+} // namespace core
+
+namespace interface {
+
+// Forward declarations
+class ConsumerSocket;
+class ProducerSocket;
+
+/**
+ * The ConsumerInterestCallback will be called in different parts of the
+ * consumer socket processing pipeline, with a ConsumerSocket and an Interest as
+ * parameters.
+ */
+using ConsumerInterestCallback =
+ std::function<void(ConsumerSocket &, const core::Interest &)>;
+
+/**
+ * The ConsumerTimerCallback is called periodically for exposing to applications
+ * a summary of the statistics of the transport protocol in use.
+ */
+using ConsumerTimerCallback =
+ std::function<void(ConsumerSocket &, const TransportStatistics &stats)>;
+
+/**
+ * The ProducerContentCallback will be called by the producer socket right after
+ * a content has been segmented and published.
+ */
+using ProducerContentCallback = std::function<void(
+ ProducerSocket &, const std::error_code &, uint64_t bytes_written)>;
+
+/**
+ * The ConsumerContentObjectCallback will be called in different parts of the
+ * consumer socket processing pipeline, with a ConsumerSocket and an
+ * ContentObject as parameters.
+ */
+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.
+ */
+using ProducerContentObjectCallback =
+ std::function<void(ProducerSocket &, core::ContentObject &)>;
+
+/**
+ * The ProducerContentObjectCallback will be called in different parts of the
+ * consumer socket processing pipeline, with a ProducerSocket and an
+ * Interest as parameters.
+ */
+using ProducerInterestCallback =
+ std::function<void(ProducerSocket &, core::Interest &)>;
+
+extern std::nullptr_t VOID_HANDLER;
+
+} // namespace interface
+
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_consumer.h b/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_consumer.h
new file mode 100644
index 000000000..097b0a8c0
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_consumer.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020 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/interfaces/socket_consumer.h>
+
+namespace transport {
+
+namespace interface {
+
+class P2PSecureConsumerSocket : public ConsumerSocket {
+ public:
+ P2PSecureConsumerSocket(int handshake_protocol, int protocol);
+ ~P2PSecureConsumerSocket() = default;
+};
+
+} // namespace interface
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h b/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h
new file mode 100644
index 000000000..6f0d48bb9
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2020 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/interfaces/socket_producer.h>
+
+#include <hicn/transport/security/identity.h>
+
+namespace transport {
+
+namespace interface {
+
+class P2PSecureProducerSocket : public ProducerSocket {
+ public:
+ P2PSecureProducerSocket();
+ P2PSecureProducerSocket(bool rtc,
+ const std::shared_ptr<utils::Identity> &identity);
+ ~P2PSecureProducerSocket() = default;
+};
+
+} // namespace interface
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/interfaces/publication_options.h b/libtransport/includes/hicn/transport/interfaces/publication_options.h
new file mode 100644
index 000000000..6910e5371
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/publication_options.h
@@ -0,0 +1,43 @@
+/*
+ * 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/name.h>
+
+namespace transport {
+
+namespace interface {
+
+class PublicationOptions {
+ public:
+ template <typename T>
+ PublicationOptions(T&& name, uint32_t lifetime)
+ : name_(std::forward<T&&>(name)),
+ content_lifetime_milliseconds_(lifetime) {}
+
+ TRANSPORT_ALWAYS_INLINE const core::Name& getName() const { return name_; }
+ TRANSPORT_ALWAYS_INLINE uint32_t getLifetime() const {
+ return content_lifetime_milliseconds_;
+ }
+
+ private:
+ core::Name name_;
+ uint32_t content_lifetime_milliseconds_;
+ // TODO Signature
+};
+} // namespace interface
+
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/interfaces/rtc_socket_producer.h b/libtransport/includes/hicn/transport/interfaces/rtc_socket_producer.h
new file mode 100644
index 000000000..218240f83
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/rtc_socket_producer.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020 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/interfaces/socket_producer.h>
+
+namespace transport {
+
+namespace interface {
+
+class RTCProducerSocket : public ProducerSocket {
+ public:
+ RTCProducerSocket();
+ ~RTCProducerSocket() = default;
+};
+
+} // namespace interface
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_consumer.h b/libtransport/includes/hicn/transport/interfaces/socket_consumer.h
new file mode 100644
index 000000000..e9e671edd
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/socket_consumer.h
@@ -0,0 +1,298 @@
+/*
+ * 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/config.h>
+#include <hicn/transport/core/name.h>
+#include <hicn/transport/core/prefix.h>
+#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 <asio/io_service.hpp>
+
+#define CONSUMER_FINISHED 0
+#define CONSUMER_BUSY 1
+#define CONSUMER_RUNNING 2
+
+namespace transport {
+
+namespace implementation {
+class ConsumerSocket;
+}
+
+namespace interface {
+
+using namespace core;
+
+/**
+ * @brief Main interface for consumer applications.
+ *
+ * The consumer socket is the main interface for a consumer application.
+ * It allows to retrieve an application data from one/many producers, by
+ * hiding all the complexity of the transport protocol used underneath.
+ */
+class ConsumerSocket {
+ public:
+ /**
+ * The ReadCallback is a class which can be used by the transport for both
+ * querying the application needs and notifying events.
+ *
+ * Beware that the methods of this class will be called synchronously while
+ * the transport is working, so the operations the application is performing
+ * on the data retrieved should be executed in another thread in an
+ * asynchronous manner. Blocking one of these callbacks means blocking the
+ * transport.
+ */
+ class ReadCallback {
+ public:
+ virtual ~ReadCallback() = default;
+
+ /**
+ * This API will specify to the transport whether the buffer should be
+ * allocated by the application (and then the retrieved content will be
+ * copied there) or the transport should allocate the buffer and "move" it
+ * to the application. In other words, if isBufferMovable return true, the
+ * transport will transfer the ownership of the read buffer to the
+ * application, without performing an additional copy, while if it returns
+ * false the transport will use the getReadBuffer API.
+ *
+ * By default this method returns true.
+ *
+ */
+ virtual bool isBufferMovable() noexcept { return true; }
+
+ /**
+ * This method will be called by the transport when the content is
+ * available. The application can then allocate its own buffer and provide
+ * the address to the transport, which will use it for writing the data.
+ * Note that if the application won't allocate enough memory this method
+ * will be called several times, until the internal read buffer will be
+ * emptied. For ensuring this method will be called once, applications
+ * should allocate at least maxBufferSize() bytes.
+ *
+ * @param application_buffer - Pointer to the application's buffer.
+ * @param max_length - The length of the application buffer.
+ */
+ virtual void getReadBuffer(uint8_t **application_buffer,
+ size_t *max_length) = 0;
+
+ /**
+ * This method will be called by the transport after calling getReadBuffer,
+ * in order to notify the application that length bytes are available in the
+ * buffer. The max_length size of the buffer could be larger than the actual
+ * amount of bytes written.
+ *
+ * @param length - The number of bytes placed in the buffer.
+ */
+ virtual void readDataAvailable(size_t length) noexcept = 0;
+
+ /**
+ * This method will be called by the transport for understanding how many
+ * bytes it should read (at most) before notifying the application.
+ *
+ * By default it reads 64 KB.
+ */
+ virtual size_t maxBufferSize() const { return 64 * 1024; }
+
+ /**
+ * This method will be called by the transport iff (isBufferMovable ==
+ * true). The unique_ptr underlines the fact that the ownership of the
+ * buffer is being transferred to the application.
+ *
+ * @param buffer - The buffer
+ */
+ virtual void readBufferAvailable(
+ std::unique_ptr<utils::MemBuf> &&buffer) noexcept {}
+
+ /**
+ * readError() will be invoked if an error occurs reading from the
+ * transport.
+ *
+ * @param ec - An error code describing the error.
+ */
+ virtual void readError(const std::error_code ec) noexcept = 0;
+
+ /**
+ * This callback will be invoked when the whole content is retrieved. The
+ * transport itself knows when a content is retrieved (since it is not an
+ * opaque bytestream like TCP), and the transport itself is able to tell
+ * the application when the transfer is done.
+ */
+ virtual void readSuccess(std::size_t total_size) noexcept = 0;
+ };
+
+ /**
+ * @brief Create a new consumer socket.
+ *
+ * @param protocol - The transport protocol to use. So far the following
+ * transport are supported:
+ * - CBR: Constant bitrate
+ * - Raaqm: Based on paper: Optimal multipath congestion control and request
+ * forwarding in information-centric networks: Protocol design and
+ * experimentation. G Carofiglio, M Gallo, L Muscariello. Computer Networks
+ * 110, 104-117
+ * - RTC: Real time communication
+ */
+ explicit ConsumerSocket(int protocol);
+
+ /**
+ * @brief Destroy the consumer socket.
+ */
+ ~ConsumerSocket();
+
+ /**
+ * @brief Connect the consumer socket to the underlying hICN forwarder.
+ */
+ void connect();
+
+ /**
+ * @brief Check whether consumer socket is active or not.
+ */
+ bool isRunning();
+
+ /**
+ * Retrieve a content using the protocol specified in the constructor.
+ * This function blocks until the whole content is downloaded.
+ * For monitoring the status of the download, the application MUST set the
+ * ConsumerRead callback. This callback will be called periodically (depending
+ * on the needs of the application), allowing the application to save the
+ * retrieved data.
+ *
+ * @param name - The name of the content to retrieve.
+ *
+ * @return CONSUMER_BUSY if a pending download exists
+ * @return CONSUMER_FINISHED when the download finishes
+ *
+ * Notice that the fact consume() returns CONSUMER_FINISHED does not imply the
+ * content retrieval succeeded. This information can be obtained from the
+ * error code in CONTENT_RETRIEVED callback.
+ */
+ int consume(const Name &name);
+ 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.
+ */
+ void stop();
+
+ /**
+ * Resume the download from the same exact point it stopped.
+ */
+ void resume();
+
+ /**
+ * Get the io_service which is running the transport protocol event loop.
+ *
+ * @return A reference to the internal io_service where the transport protocol
+ * is running.
+ */
+ asio::io_service &getIoService();
+
+ int setSocketOption(int socket_option_key, ReadCallback *socket_option_value);
+
+ int getSocketOption(int socket_option_key,
+ ReadCallback **socket_option_value);
+
+ int setSocketOption(int socket_option_key, double socket_option_value);
+
+ int setSocketOption(int socket_option_key, uint32_t socket_option_value);
+
+ int setSocketOption(int socket_option_key,
+ std::nullptr_t socket_option_value);
+
+ int setSocketOption(int socket_option_key, bool socket_option_value);
+
+ 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);
+
+ int setSocketOption(int socket_option_key,
+ interface::IcnObserver *socket_option_value);
+
+ int setSocketOption(
+ int socket_option_key,
+ const std::shared_ptr<utils::Verifier> &socket_option_value);
+
+ int setSocketOption(int socket_option_key,
+ const std::string &socket_option_value);
+
+ int setSocketOption(int socket_option_key,
+ ConsumerTimerCallback socket_option_value);
+
+ int getSocketOption(int socket_option_key, double &socket_option_value);
+
+ int getSocketOption(int socket_option_key, uint32_t &socket_option_value);
+
+ int getSocketOption(int socket_option_key, bool &socket_option_value);
+
+ int getSocketOption(int socket_option_key, Name **socket_option_value);
+
+ 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);
+
+ int getSocketOption(int socket_option_key, std::string &socket_option_value);
+
+ int getSocketOption(int socket_option_key,
+ ConsumerTimerCallback **socket_option_value);
+
+ int getSocketOption(int socket_option_key,
+ interface::TransportStatistics **socket_option_value);
+
+ protected:
+ ConsumerSocket();
+ std::unique_ptr<implementation::ConsumerSocket> socket_;
+};
+
+} // namespace interface
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h b/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h
new file mode 100644
index 000000000..bcf103b8c
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h
@@ -0,0 +1,69 @@
+/*
+ * 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/base.h>
+#include <chrono>
+#include <cstdint>
+
+namespace transport {
+
+namespace interface {
+
+namespace default_values {
+
+static constexpr uint32_t interest_lifetime = 1001; // milliseconds
+static constexpr uint32_t never_expire_time = HICN_MAX_LIFETIME;
+static constexpr uint32_t content_object_expiry_time =
+ never_expire_time; // milliseconds -> 50 seconds
+static constexpr uint32_t content_object_packet_size =
+ 1500; // The ethernet MTU
+static constexpr uint32_t producer_socket_output_buffer_size =
+ 150000; // Content Object
+static constexpr uint32_t log_2_default_buffer_size = 12;
+static constexpr uint32_t signature_size = 260; // bytes
+static constexpr uint32_t key_locator_size = 60; // bytes
+static constexpr uint32_t limit_guard = 80; // bytes
+static constexpr uint32_t digest_size = 34; // bytes
+static constexpr uint32_t max_out_of_order_segments = 3; // content object
+
+// RAAQM
+static constexpr int sample_number = 30;
+static constexpr double gamma_value = 1;
+static constexpr double beta_value = 0.8;
+static constexpr double drop_factor = 0.2;
+static constexpr double minimum_drop_probability = 0.00001;
+static constexpr int path_id = 0;
+static constexpr double rate_alpha = 0.8;
+
+// Rate estimation
+static constexpr uint32_t batch = 50;
+static constexpr uint32_t kv = 20;
+static constexpr double alpha = 0.8;
+static constexpr uint32_t rate_choice = 0;
+
+// maximum allowed values
+static constexpr uint32_t transport_protocol_min_retransmissions = 0;
+static constexpr uint32_t transport_protocol_max_retransmissions = 128;
+static constexpr uint32_t max_content_object_size = 8096;
+static constexpr uint32_t min_window_size = 1; // Interests
+static constexpr uint32_t max_window_size = 256 * 2; // Interests
+
+} // namespace default_values
+
+} // namespace interface
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h b/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h
new file mode 100644
index 000000000..7910a4422
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h
@@ -0,0 +1,118 @@
+/*
+ * 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
+
+#define SOCKET_OPTION_GET 0
+#define SOCKET_OPTION_NOT_GET 1
+#define SOCKET_OPTION_SET 2
+#define SOCKET_OPTION_NOT_SET 3
+#define SOCKET_OPTION_DEFAULT 12345
+
+namespace transport {
+
+namespace interface {
+
+typedef enum {
+ RAAQM = 0,
+ CBR = 1,
+ RTC = 2,
+} TransportProtocolAlgorithms;
+
+typedef enum {
+ INPUT_BUFFER_SIZE = 101,
+ OUTPUT_BUFFER_SIZE = 102,
+ NETWORK_NAME = 103,
+ NAME_SUFFIX = 104,
+ MAX_INTEREST_RETX = 105,
+ 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,
+ ASYNC_MODE = 114,
+ MAKE_MANIFEST = 115,
+ PORTAL = 116,
+ RUNNING = 117,
+ APPLICATION_BUFFER = 118,
+ HASH_ALGORITHM = 119,
+ CRYPTO_SUITE = 120,
+ SIGNER = 121,
+ VERIFIER = 122,
+ CERTIFICATE = 123,
+ VERIFY_SIGNATURE = 124,
+ STATS_INTERVAL = 125,
+} GeneralTransportOptions;
+
+typedef enum {
+ SAMPLE_NUMBER = 201,
+ GAMMA_VALUE = 202,
+ BETA_VALUE = 203,
+ DROP_FACTOR = 204,
+ MINIMUM_DROP_PROBABILITY = 205,
+ PATH_ID = 206,
+ RTT_STATS = 207,
+} RaaqmTransportOptions;
+
+typedef enum {
+ RATE_ESTIMATION_ALPHA = 301,
+ RATE_ESTIMATION_OBSERVER = 302,
+ RATE_ESTIMATION_BATCH_PARAMETER = 303,
+ RATE_ESTIMATION_CHOICE = 304,
+} RateEstimationOptions;
+
+typedef enum {
+ INTEREST_OUTPUT = 401,
+ INTEREST_RETRANSMISSION = 402,
+ INTEREST_EXPIRED = 403,
+ INTEREST_SATISFIED = 404,
+ CONTENT_OBJECT_INPUT = 411,
+ CONTENT_OBJECT_TO_VERIFY = 413,
+ VERIFICATION_FAILED = 414,
+ READ_CALLBACK = 415,
+ STATS_SUMMARY = 416
+} ConsumerCallbacksOptions;
+
+typedef enum {
+ INTEREST_INPUT = 501,
+ INTEREST_DROP = 502,
+ INTEREST_PASS = 503,
+ CACHE_HIT = 506,
+ CACHE_MISS = 508,
+ NEW_CONTENT_OBJECT = 509,
+ CONTENT_OBJECT_SIGN = 513,
+ CONTENT_OBJECT_READY = 510,
+ CONTENT_OBJECT_OUTPUT = 511,
+ CONTENT_PRODUCED = 512,
+} ProducerCallbacksOptions;
+
+typedef enum { OUTPUT_INTERFACE = 601 } DataLinkOptions;
+
+typedef enum {
+ VIRTUAL_DOWNLOAD = 701,
+ USE_CFG_FILE = 702,
+ STATISTICS
+} OtherOptions;
+
+typedef enum {
+ SHA_256 = 801,
+ RSA_256 = 802,
+} SignatureType;
+
+} // namespace interface
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/interfaces/socket_producer.h b/libtransport/includes/hicn/transport/interfaces/socket_producer.h
new file mode 100644
index 000000000..3fe99fbd4
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/socket_producer.h
@@ -0,0 +1,149 @@
+/*
+ * 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/config.h>
+#include <hicn/transport/core/name.h>
+#include <hicn/transport/core/prefix.h>
+#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 <asio/io_service.hpp>
+
+namespace transport {
+
+namespace implementation {
+class ProducerSocket;
+}
+
+namespace interface {
+
+using namespace core;
+
+class ProducerSocket {
+ public:
+ explicit ProducerSocket(int protocol = 0);
+
+ virtual ~ProducerSocket();
+
+ void connect();
+
+ 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);
+ }
+
+ uint32_t produce(Name content_name, std::unique_ptr<utils::MemBuf> &&buffer,
+ bool is_last = true, uint32_t start_offset = 0);
+
+ void produce(ContentObject &content_object);
+
+ void produce(const uint8_t *buffer, size_t buffer_size) {
+ produce(utils::MemBuf::copyBuffer(buffer, buffer_size));
+ }
+
+ void produce(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);
+
+ void asyncProduce(Name content_name, std::unique_ptr<utils::MemBuf> &&buffer,
+ bool is_last, uint32_t offset,
+ uint32_t **last_segment = nullptr);
+
+ void asyncProduce(ContentObject &content_object);
+
+ void registerPrefix(const Prefix &producer_namespace);
+
+ void serveForever();
+
+ void stop();
+
+ asio::io_service &getIoService();
+
+ int setSocketOption(int socket_option_key, uint32_t socket_option_value);
+
+ int setSocketOption(int socket_option_key,
+ std::nullptr_t socket_option_value);
+
+ int setSocketOption(int socket_option_key, bool socket_option_value);
+
+ int setSocketOption(int socket_option_key, Name *socket_option_value);
+
+ int setSocketOption(int socket_option_key,
+ std::list<Prefix> socket_option_value);
+
+ int setSocketOption(int socket_option_key,
+ ProducerContentObjectCallback socket_option_value);
+
+ int setSocketOption(int socket_option_key,
+ ProducerInterestCallback socket_option_value);
+
+ int setSocketOption(int socket_option_key,
+ ProducerContentCallback socket_option_value);
+
+ int setSocketOption(int socket_option_key, HashAlgorithm socket_option_value);
+
+ int setSocketOption(int socket_option_key,
+ utils::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::string &socket_option_value);
+
+ int getSocketOption(int socket_option_key, uint32_t &socket_option_value);
+
+ int getSocketOption(int socket_option_key, bool &socket_option_value);
+
+ int getSocketOption(int socket_option_key,
+ std::list<Prefix> &socket_option_value);
+
+ int getSocketOption(int socket_option_key,
+ ProducerContentObjectCallback **socket_option_value);
+
+ int getSocketOption(int socket_option_key,
+ ProducerContentCallback **socket_option_value);
+
+ int getSocketOption(int socket_option_key,
+ ProducerInterestCallback **socket_option_value);
+
+ int getSocketOption(int socket_option_key,
+ HashAlgorithm &socket_option_value);
+
+ int getSocketOption(int socket_option_key,
+ utils::CryptoSuite &socket_option_value);
+
+ int getSocketOption(int socket_option_key,
+ std::shared_ptr<utils::Signer> &socket_option_value);
+
+ int getSocketOption(int socket_option_key, std::string &socket_option_value);
+
+ protected:
+ ProducerSocket(bool);
+ std::unique_ptr<implementation::ProducerSocket> socket_;
+};
+
+} // namespace interface
+
+} // namespace transport
diff --git a/libtransport/includes/hicn/transport/interfaces/statistics.h b/libtransport/includes/hicn/transport/interfaces/statistics.h
new file mode 100644
index 000000000..26831fbf1
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/statistics.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/portability/c_portability.h>
+
+#include <cstdint>
+
+namespace transport {
+
+namespace interface {
+
+class IcnObserver {
+ public:
+ virtual ~IcnObserver(){};
+
+ virtual void notifyStats(double throughput) = 0;
+ virtual void notifyDownloadTime(double downloadTime) = 0;
+};
+
+class TransportStatistics {
+ static constexpr double default_alpha = 0.7;
+
+ public:
+ TransportStatistics(double alpha = default_alpha)
+ : retx_count_(0),
+ bytes_received_(0),
+ average_rtt_(0),
+ avg_window_size_(0),
+ interest_tx_(0),
+ alpha_(alpha),
+ loss_ratio_(0.0),
+ queuing_delay_(0.0) {}
+
+ TRANSPORT_ALWAYS_INLINE void updateRetxCount(uint64_t retx) {
+ retx_count_ += retx;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateBytesRecv(uint64_t bytes) {
+ bytes_received_ += bytes;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateAverageRtt(uint64_t rtt) {
+ average_rtt_ = (alpha_ * average_rtt_) + ((1. - alpha_) * double(rtt));
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateAverageWindowSize(double current_window) {
+ avg_window_size_ =
+ (alpha_ * avg_window_size_) + ((1. - alpha_) * current_window);
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateInterestTx(uint64_t int_tx) {
+ interest_tx_ += int_tx;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateLossRatio(double loss_ratio) {
+ loss_ratio_ = loss_ratio;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void updateQueuingDelay(double queuing_delay) {
+ queuing_delay_ = queuing_delay;
+ }
+
+ TRANSPORT_ALWAYS_INLINE uint64_t getRetxCount() const { return retx_count_; }
+
+ TRANSPORT_ALWAYS_INLINE uint64_t getBytesRecv() const {
+ return bytes_received_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE double getAverageRtt() const { return average_rtt_; }
+
+ TRANSPORT_ALWAYS_INLINE double getAverageWindowSize() const {
+ return avg_window_size_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE uint64_t getInterestTx() const {
+ return interest_tx_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE double getLossRatio() const { return loss_ratio_; }
+
+ TRANSPORT_ALWAYS_INLINE double getQueuingDelay() const {
+ return queuing_delay_;
+ }
+
+ TRANSPORT_ALWAYS_INLINE void reset() {
+ retx_count_ = 0;
+ bytes_received_ = 0;
+ average_rtt_ = 0;
+ avg_window_size_ = 0;
+ interest_tx_ = 0;
+ loss_ratio_ = 0;
+ }
+
+ private:
+ uint64_t retx_count_;
+ uint64_t bytes_received_;
+ double average_rtt_;
+ double avg_window_size_;
+ uint64_t interest_tx_;
+ double alpha_;
+ double loss_ratio_;
+ double queuing_delay_;
+};
+
+} // namespace interface
+
+} // end namespace transport
diff --git a/libtransport/includes/hicn/transport/interfaces/verification_policy.h b/libtransport/includes/hicn/transport/interfaces/verification_policy.h
new file mode 100644
index 000000000..cb5140ac1
--- /dev/null
+++ b/libtransport/includes/hicn/transport/interfaces/verification_policy.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2020 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>
+
+namespace transport {
+namespace interface {
+
+/**
+ * This policy allows the application to tell the transport what to do in case
+ * the verification of a content object fails.
+ */
+enum class VerificationPolicy : std::uint8_t {
+ DROP_PACKET,
+ ACCEPT_PACKET,
+ ABORT_SESSION
+};
+} // namespace interface
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/portability/CMakeLists.txt b/libtransport/includes/hicn/transport/portability/CMakeLists.txt
new file mode 100644
index 000000000..469b11192
--- /dev/null
+++ b/libtransport/includes/hicn/transport/portability/CMakeLists.txt
@@ -0,0 +1,31 @@
+# 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}/c_portability.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/portability.h
+)
+
+list(APPEND SOURCE_FILES
+ ""
+)
+
+if(WIN32)
+ list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/win_portability.h
+ )
+endif()
+
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/portability/c_portability.h b/libtransport/includes/hicn/transport/portability/c_portability.h
new file mode 100644
index 000000000..71e976a81
--- /dev/null
+++ b/libtransport/includes/hicn/transport/portability/c_portability.h
@@ -0,0 +1,36 @@
+/*
+ * 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
+
+// noinline
+#ifdef _MSC_VER
+#define TRANSPORT_NOINLINE __declspec(noinline)
+#elif defined(__clang__) || defined(__GNUC__)
+#define TRANSPORT_NOINLINE __attribute__((__noinline__))
+#else
+#define TRANSPORT_NOINLINE
+#endif
+
+// always inline
+#ifdef _MSC_VER
+#define TRANSPORT_ALWAYS_INLINE __forceinline
+#elif defined(__clang__) || defined(__GNUC__)
+#define TRANSPORT_ALWAYS_INLINE inline __attribute__((__always_inline__))
+#else
+#define TRANSPORT_ALWAYS_INLINE inline
+#endif \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/portability/portability.h b/libtransport/includes/hicn/transport/portability/portability.h
new file mode 100644
index 000000000..1d97a346e
--- /dev/null
+++ b/libtransport/includes/hicn/transport/portability/portability.h
@@ -0,0 +1,50 @@
+/*
+ * 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
+
+#ifdef _WIN32
+#include <hicn/transport/portability/win_portability.h>
+#endif
+
+#include <hicn/transport/portability/c_portability.h>
+
+#include <string.h>
+#include <cstddef>
+
+namespace portability {
+
+constexpr bool little_endian_arch = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__;
+constexpr bool big_endian_arch = !little_endian_arch;
+
+#if defined(__GNUC__)
+#define _TRANSPORT_GNU_DISABLE_WARNING(warning) #warning
+#define TRANSPORT_GNU_DISABLE_WARNING(warning) \
+ _Pragma(_TRANSPORT_GNU_DISABLE_WARNING(GCC diagnostic ignored warning))
+
+#ifdef __clang__
+#define TRANSPORT_CLANG_DISABLE_WARNING(warning) \
+ TRANSPORT_GNU_DISABLE_WARNING(warning)
+#define TRANSPORT_GCC_DISABLE_WARNING(warning)
+#else
+#define TRANSPORT_CLANG_DISABLE_WARNING(warning)
+#define TRANSPORT_GCC_DISABLE_WARNING(warning) \
+ TRANSPORT_GNU_DISABLE_WARNING(warning)
+#endif
+#endif
+
+} // namespace portability
diff --git a/libtransport/includes/hicn/transport/portability/win_portability.h b/libtransport/includes/hicn/transport/portability/win_portability.h
new file mode 100644
index 000000000..65d949291
--- /dev/null
+++ b/libtransport/includes/hicn/transport/portability/win_portability.h
@@ -0,0 +1,42 @@
+/*
+ * 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
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include <fcntl.h>
+#include <io.h>
+#include <parc/windows/parc_Utils.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <time.h>
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2ipdef.h>
+#include <ws2tcpip.h>
+#include <algorithm>
+
+#define __ORDER_LITTLE_ENDIAN__ 0x41424344UL
+#define __ORDER_BIG_ENDIAN__ 0x44434241UL
+#define __BYTE_ORDER__ ('ABCD')
+#undef DELETE
+
+#define HAVE_STRUCT_TIMESPEC
+#include <pthread.h> \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/security/CMakeLists.txt b/libtransport/includes/hicn/transport/security/CMakeLists.txt
new file mode 100644
index 000000000..58a96780b
--- /dev/null
+++ b/libtransport/includes/hicn/transport/security/CMakeLists.txt
@@ -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.
+
+cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/signer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/verifier.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_hasher.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_suite.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_hash.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/crypto_hash_type.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/identity.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/key_id.h
+)
+
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/security/crypto_hash.h b/libtransport/includes/hicn/transport/security/crypto_hash.h
new file mode 100644
index 000000000..5a58f258b
--- /dev/null
+++ b/libtransport/includes/hicn/transport/security/crypto_hash.h
@@ -0,0 +1,119 @@
+/*
+ * 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/security/crypto_hash_type.h>
+#include <hicn/transport/utils/array.h>
+
+extern "C" {
+#include <parc/security/parc_CryptoHash.h>
+};
+
+#include <cstring>
+#include <unordered_map>
+
+namespace utils {
+
+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 utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/security/crypto_hash_type.h b/libtransport/includes/hicn/transport/security/crypto_hash_type.h
new file mode 100644
index 000000000..b7597e208
--- /dev/null
+++ b/libtransport/includes/hicn/transport/security/crypto_hash_type.h
@@ -0,0 +1,31 @@
+/*
+ * 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>
+};
+
+namespace utils {
+
+enum class CryptoHashType : uint8_t {
+ SHA_256 = PARCCryptoHashType_SHA256,
+ SHA_512 = PARCCryptoHashType_SHA512,
+ CRC32C = PARCCryptoHashType_CRC32C,
+ NULL_HASH = PARCCryptoHashType_NULL
+};
+
+} \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/security/crypto_hasher.h b/libtransport/includes/hicn/transport/security/crypto_hasher.h
new file mode 100644
index 000000000..9367c3bc8
--- /dev/null
+++ b/libtransport/includes/hicn/transport/security/crypto_hasher.h
@@ -0,0 +1,68 @@
+/*
+ * 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/security/crypto_hash.h>
+
+extern "C" {
+#include <parc/security/parc_CryptoHasher.h>
+};
+
+namespace utils {
+
+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 utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/security/crypto_suite.h b/libtransport/includes/hicn/transport/security/crypto_suite.h
new file mode 100644
index 000000000..017938f8f
--- /dev/null
+++ b/libtransport/includes/hicn/transport/security/crypto_suite.h
@@ -0,0 +1,36 @@
+/*
+ * 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 utils {
+
+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
+};
+}
diff --git a/libtransport/includes/hicn/transport/security/identity.h b/libtransport/includes/hicn/transport/security/identity.h
new file mode 100644
index 000000000..c5d4b975d
--- /dev/null
+++ b/libtransport/includes/hicn/transport/security/identity.h
@@ -0,0 +1,63 @@
+/*
+ * 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/security/crypto_suite.h>
+#include <hicn/transport/security/signer.h>
+
+#include <core/manifest_format.h>
+
+extern "C" {
+#include <parc/security/parc_Identity.h>
+#include <parc/security/parc_IdentityFile.h>
+#include <parc/security/parc_Pkcs12KeyStore.h>
+};
+
+#include <string>
+
+namespace utils {
+
+class Identity {
+ public:
+ Identity(const std::string &keystore_name,
+ const std::string &keystore_password, CryptoSuite suite,
+ unsigned int signature_length, unsigned int validity_days,
+ const std::string &subject_name);
+
+ Identity(const Identity &other);
+
+ Identity(std::string &file_name, std::string &password,
+ transport::core::HashAlgorithm hash_algorithm);
+
+ ~Identity();
+
+ static Identity generateIdentity(const std::string &subject_name);
+
+ std::string getFileName();
+
+ std::string getPassword();
+
+ std::shared_ptr<Signer> getSigner();
+
+ size_t getSignatureLength() const;
+
+ private:
+ PARCIdentity *identity_;
+ std::shared_ptr<Signer> signer_;
+ transport::core::HashAlgorithm hash_algorithm_;
+};
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/security/key_id.h b/libtransport/includes/hicn/transport/security/key_id.h
new file mode 100644
index 000000000..d67b73d7a
--- /dev/null
+++ b/libtransport/includes/hicn/transport/security/key_id.h
@@ -0,0 +1,25 @@
+/*
+ * 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 utils {
+
+using KeyId = std::pair<uint8_t*, uint8_t>;
+
+}
diff --git a/libtransport/includes/hicn/transport/security/signer.h b/libtransport/includes/hicn/transport/security/signer.h
new file mode 100644
index 000000000..31b21462b
--- /dev/null
+++ b/libtransport/includes/hicn/transport/security/signer.h
@@ -0,0 +1,90 @@
+/*
+ * 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>
+
+extern "C" {
+#include <parc/security/parc_CryptoHashType.h>
+#include <parc/security/parc_CryptoSuite.h>
+#include <parc/security/parc_KeyStore.h>
+#include <parc/security/parc_Signer.h>
+#include <parc/security/parc_SymmetricKeySigner.h>
+}
+
+namespace utils {
+
+using Packet = transport::core::Packet;
+
+/**
+ * A signer can use a single key (asymmetric or symmetric) to sign a packet.
+ */
+class Signer {
+ friend class Identity;
+
+ public:
+ /**
+ * Create a Signer
+ *
+ * @param keyStore A keystore containing a private key or simmetric key to
+ * use to sign packet with this Signer.
+ * @param suite CryptoSuite to use to verify the signature
+ */
+ Signer(PARCKeyStore *keyStore, CryptoSuite suite);
+
+ /**
+ * Create a Signer
+ *
+ * @param passphrase A string from which the symmetric key will be derived
+ * @param suite CryptoSuite to use to verify the signature
+ */
+ Signer(const std::string &passphrase, CryptoSuite suite);
+
+ Signer(const PARCSigner *signer, CryptoSuite suite);
+
+ Signer(const PARCSigner *signer);
+
+ ~Signer();
+
+ /**
+ * @brief Sign a packet
+ *
+ * This method is general and must be used for Public-private key signature,
+ * HMAC and CRC.
+ *
+ * @param packet A pointer to the header of the packet to sign. Mutable
+ * field in the packet must be set to 0.
+ * @param key_id Indentifier of the key to use to generate the signature.
+ */
+ void sign(Packet &packet);
+
+ size_t getSignatureLength();
+
+ PARCKeyStore *getKeyStore();
+
+ private:
+ PARCBufferComposer *composer_ = nullptr;
+ PARCBuffer *key_buffer_ = nullptr;
+ PARCSymmetricKeyStore *symmetricKeyStore_ = nullptr;
+ PARCSigner *signer_ = nullptr;
+ PARCSignature *signature_ = nullptr;
+ PARCKeyId *key_id_ = nullptr;
+ CryptoSuite suite_;
+ size_t signature_length_;
+ static uint8_t zeros[200];
+};
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/security/verifier.h b/libtransport/includes/hicn/transport/security/verifier.h
new file mode 100644
index 000000000..7ec6e7eda
--- /dev/null
+++ b/libtransport/includes/hicn/transport/security/verifier.h
@@ -0,0 +1,103 @@
+/*
+ * 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>
+
+extern "C" {
+#include <parc/security/parc_CertificateFactory.h>
+#include <parc/security/parc_InMemoryVerifier.h>
+#include <parc/security/parc_KeyId.h>
+#include <parc/security/parc_Security.h>
+#include <parc/security/parc_SymmetricKeySigner.h>
+#include <parc/security/parc_Verifier.h>
+}
+
+namespace utils {
+
+using Packet = transport::core::Packet;
+
+/**
+ * A verifier holds a crypto cache that contains all the keys to use for
+ * verify signatures/hmacs.
+ */
+class Verifier {
+ public:
+ Verifier();
+
+ ~Verifier();
+
+ /**
+ * @brief Check if a key is already in this Verifier.
+ *
+ * A PARCVerifier contains a CryptoCache with a set of key to use for
+ * verification purposes.
+ *
+ * @param keyId Identifier of the key to match in the CryptoCache of the
+ * Verifier.
+ * @return true if the key is found, false otherwise.
+ */
+ bool hasKey(PARCKeyId *keyId);
+
+ /**
+ * @brief Add a key to this Verifier
+ *
+ * @param key to add
+ * @return true if the key was added successfully, false otherwise.
+ */
+ bool addKey(PARCKey *key);
+
+ PARCKeyId *addKeyFromPassphrase(const std::string &passphrase,
+ CryptoSuite suite);
+
+ PARCKeyId *addKeyFromCertificate(const std::string &file_name);
+
+ /**
+ * @brief Verify a Signature
+ *
+ * This method is general and must be used for Public-private key signature,
+ * HMAC and CRC.
+ *
+ * @param signature A pointer to the buffer holding the signature
+ * @param sign_len Lenght of the signature (must be consistent with the type
+ * of the key)
+ * @param bufferSigned A pointer to the packet header signed with
+ * signature. Mutable fields and the signature field in the packet must be
+ * set to 0
+ * @param buf_len Lenght of bufferSigned
+ * @param suite CryptoSuite to use to verify the signature
+ * @param key_id Indentifier of the key to use to verify the signature. The
+ * key must be already present in the Verifier.
+ */
+ int verify(const Packet &packet);
+
+ CryptoHash getPacketHash(const Packet &packet,
+ std::shared_ptr<CryptoHasher> hasher);
+
+ private:
+ PARCVerifier *verifier_ = nullptr;
+ PARCCertificateFactory *factory_ = nullptr;
+ PARCCertificate *certificate_ = nullptr;
+ PARCKeyId *keyId_ = nullptr;
+ PARCKey *key_ = nullptr;
+ PARCBuffer *key_buffer_ = nullptr;
+ PARCSymmetricKeyStore *symmetricKeyStore_ = nullptr;
+ PARCSigner *signer_ = nullptr;
+ PARCBufferComposer *composer_ = nullptr;
+ static uint8_t zeros[200];
+};
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/CMakeLists.txt b/libtransport/includes/hicn/transport/utils/CMakeLists.txt
new file mode 100644
index 000000000..396bd06d6
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/CMakeLists.txt
@@ -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.
+
+cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/array.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/string_tokenizer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hash.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/uri.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/chrono_typedefs.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/branch_prediction.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/ring_buffer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/literals.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/conversions.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/linux.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/log.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/object_pool.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/membuf.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/spinlock.h
+)
+
+if(NOT WIN32)
+ list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/daemonizator.h
+ )
+endif()
+
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/array.h b/libtransport/includes/hicn/transport/utils/array.h
new file mode 100644
index 000000000..7c0ed65d8
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/array.h
@@ -0,0 +1,62 @@
+/*
+ * 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/portability/portability.h>
+
+#include <cstddef>
+
+namespace utils {
+
+template <typename T = uint8_t>
+class Array {
+ public:
+ explicit Array(const T *array, size_t size) : array_(array), size_(size) {
+ this->array_ = array;
+ this->size_ = size;
+ }
+
+ Array() : array_(nullptr), size_(0) {
+ this->array_ = nullptr;
+ this->size_ = 0;
+ }
+
+ TRANSPORT_ALWAYS_INLINE const T *data() const { return array_; }
+
+ TRANSPORT_ALWAYS_INLINE T *writableData() const {
+ return const_cast<T *>(array_);
+ }
+
+ TRANSPORT_ALWAYS_INLINE std::size_t length() const { return size_; }
+
+ TRANSPORT_ALWAYS_INLINE Array &setData(const T *data) {
+ array_ = data;
+ return *this;
+ }
+
+ TRANSPORT_ALWAYS_INLINE Array &setSize(std::size_t size) {
+ size_ = size;
+ return *this;
+ }
+
+ TRANSPORT_ALWAYS_INLINE bool empty() { return !size_; }
+
+ private:
+ const T *array_;
+ std::size_t size_;
+};
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/branch_prediction.h b/libtransport/includes/hicn/transport/utils/branch_prediction.h
new file mode 100644
index 000000000..8cbfaca76
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/branch_prediction.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
+
+#undef TRANSPORT_EXPECT_TRUE
+#undef TRANSPORT_EXPECT_FALSE
+
+#ifndef _WIN32
+#define TRANSPORT_EXPECT_TRUE(x) __builtin_expect((x), 1)
+#define TRANSPORT_EXPECT_FALSE(x) __builtin_expect((x), 0)
+#else
+#define TRANSPORT_EXPECT_TRUE(x) (x)
+#define TRANSPORT_EXPECT_FALSE(x) (x)
+#endif \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/chrono_typedefs.h b/libtransport/includes/hicn/transport/utils/chrono_typedefs.h
new file mode 100644
index 000000000..8f28e763c
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/chrono_typedefs.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 <chrono>
+
+namespace utils {
+
+using SteadyClock = std::chrono::steady_clock;
+using TimePoint = SteadyClock::time_point;
+using Milliseconds = std::chrono::milliseconds;
+using Microseconds = std::chrono::microseconds;
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/conversions.h b/libtransport/includes/hicn/transport/utils/conversions.h
new file mode 100644
index 000000000..24b529206
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/conversions.h
@@ -0,0 +1,37 @@
+/*
+ * 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/portability/portability.h>
+
+#include <stdio.h>
+#include <cstdint>
+#include <string>
+
+namespace utils {
+
+static TRANSPORT_ALWAYS_INLINE int convertStringToMacAddress(
+ const std::string& mac_address, uint8_t* mac_byte_array) {
+ const char* mac = mac_address.c_str();
+
+ sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mac_byte_array[0],
+ &mac_byte_array[1], &mac_byte_array[2], &mac_byte_array[3],
+ &mac_byte_array[4], &mac_byte_array[5]);
+
+ return 0;
+}
+
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/daemonizator.h b/libtransport/includes/hicn/transport/utils/daemonizator.h
new file mode 100644
index 000000000..028d74865
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/daemonizator.h
@@ -0,0 +1,30 @@
+/*
+ * 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
+
+#ifndef _WIN32
+
+#include <cstdlib>
+namespace utils {
+
+class Daemonizator {
+ public:
+ static void daemonize(bool close_fds = true);
+};
+
+} // namespace utils
+
+#endif \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/hash.h b/libtransport/includes/hicn/transport/utils/hash.h
new file mode 100644
index 000000000..6815ca4bf
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/hash.h
@@ -0,0 +1,101 @@
+/*
+ * 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 <hicn/transport/portability/portability.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+namespace utils {
+
+namespace hash {
+
+/*
+ * Fowler / Noll / Vo (FNV) Hash
+ * http://www.isthe.com/chongo/tech/comp/fnv/
+ */
+
+const uint32_t FNV_32_HASH_START = 2166136261UL;
+const uint64_t FNV_64_HASH_START = 14695981039346656037ULL;
+
+TRANSPORT_ALWAYS_INLINE uint32_t fnv32(const char *s,
+ uint32_t hash = FNV_32_HASH_START) {
+ for (; *s; ++s) {
+ hash +=
+ (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
+ hash ^= *s;
+ }
+ return hash;
+}
+
+TRANSPORT_ALWAYS_INLINE uint32_t fnv32_buf(const void *buf, size_t n,
+ uint32_t hash = FNV_32_HASH_START) {
+ // forcing signed char, since other platforms can use unsigned
+ const signed char *char_buf = reinterpret_cast<const signed char *>(buf);
+
+ for (size_t i = 0; i < n; ++i) {
+ hash +=
+ (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
+ hash ^= char_buf[i];
+ }
+
+ return hash;
+}
+
+TRANSPORT_ALWAYS_INLINE uint32_t fnv32(const std::string &str,
+ uint32_t hash = FNV_32_HASH_START) {
+ return fnv32_buf(str.data(), str.size(), hash);
+}
+
+TRANSPORT_ALWAYS_INLINE uint64_t fnv64(const char *s,
+ uint64_t hash = FNV_64_HASH_START) {
+ for (; *s; ++s) {
+ hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) +
+ (hash << 8) + (hash << 40);
+ hash ^= *s;
+ }
+ return hash;
+}
+
+TRANSPORT_ALWAYS_INLINE uint64_t fnv64_buf(const void *buf, size_t n,
+ uint64_t hash = FNV_64_HASH_START) {
+ // forcing signed char, since other platforms can use unsigned
+ const signed char *char_buf = reinterpret_cast<const signed char *>(buf);
+
+ for (size_t i = 0; i < n; ++i) {
+ hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) +
+ (hash << 8) + (hash << 40);
+ hash ^= char_buf[i];
+ }
+ return hash;
+}
+
+TRANSPORT_ALWAYS_INLINE uint64_t fnv64(const std::string &str,
+ uint64_t hash = FNV_64_HASH_START) {
+ return fnv64_buf(str.data(), str.size(), hash);
+}
+
+} // namespace hash
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/linux.h b/libtransport/includes/hicn/transport/utils/linux.h
new file mode 100644
index 000000000..5820528e1
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/linux.h
@@ -0,0 +1,64 @@
+/*
+ * 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
+
+#ifdef __linux__
+
+#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
+
+namespace utils {
+
+static TRANSPORT_ALWAYS_INLINE int retrieveInterfaceAddress(
+ const std::string &interface_name, struct sockaddr_in6 *address) {
+ struct ifaddrs *ifap, *ifa;
+ char addr[INET6_ADDRSTRLEN];
+
+ getifaddrs(&ifap);
+
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr->sa_family == AF_INET6 &&
+ strcmp(ifa->ifa_name, interface_name.c_str()) == 0) {
+ struct sockaddr_in6 *tmp = (struct sockaddr_in6 *)ifa->ifa_addr;
+ uint16_t prefix = 0;
+ memcpy(&prefix, tmp->sin6_addr.s6_addr, sizeof(uint16_t));
+
+ if (htons(LINK_LOCAL_PREFIX) != prefix) {
+ *address = *(struct sockaddr_in6 *)ifa->ifa_addr;
+ getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), addr,
+ sizeof(addr), NULL, 0, NI_NUMERICHOST);
+ TRANSPORT_LOGI("Interface: %s\tAddress: %s", ifa->ifa_name, addr);
+ }
+ }
+ }
+
+ freeifaddrs(ifap);
+
+ return 0;
+}
+
+} // namespace utils
+
+#endif // __linux__ \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/literals.h b/libtransport/includes/hicn/transport/utils/literals.h
new file mode 100644
index 000000000..bd00e0a58
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/literals.h
@@ -0,0 +1,55 @@
+/*
+ * 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/portability/portability.h>
+
+#include <cstdint>
+
+TRANSPORT_ALWAYS_INLINE std::uint8_t operator"" _U8(unsigned long long value) {
+ return static_cast<std::uint8_t>(value);
+}
+
+TRANSPORT_ALWAYS_INLINE std::uint16_t operator"" _U16(
+ unsigned long long value) {
+ return static_cast<std::uint16_t>(value);
+}
+
+TRANSPORT_ALWAYS_INLINE std::uint32_t operator"" _U32(
+ unsigned long long value) {
+ return static_cast<std::uint32_t>(value);
+}
+
+TRANSPORT_ALWAYS_INLINE std::uint64_t operator"" _U64(
+ unsigned long long value) {
+ return static_cast<std::uint64_t>(value);
+}
+
+TRANSPORT_ALWAYS_INLINE std::int8_t operator"" _I8(unsigned long long value) {
+ return static_cast<std::int8_t>(value);
+}
+
+TRANSPORT_ALWAYS_INLINE std::int16_t operator"" _I16(unsigned long long value) {
+ return static_cast<std::int16_t>(value);
+}
+
+TRANSPORT_ALWAYS_INLINE std::int32_t operator"" _I32(unsigned long long value) {
+ return static_cast<std::int32_t>(value);
+}
+
+TRANSPORT_ALWAYS_INLINE std::int64_t operator"" _I64(unsigned long long value) {
+ return static_cast<std::int64_t>(value);
+} \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/log.h b/libtransport/includes/hicn/transport/utils/log.h
new file mode 100644
index 000000000..3c4f1277a
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/log.h
@@ -0,0 +1,1057 @@
+/*
+ * 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.
+ */
+
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 wonder-mice
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#pragma once
+
+/* To detect incompatible changes you can define TRANSPORT_LOG_VERSION_REQUIRED
+ * to be the current value of TRANSPORT_LOG_VERSION before including this file
+ * (or via compiler command line):
+ *
+ * #define TRANSPORT_LOG_VERSION_REQUIRED 4
+ * #include <hicn/transport_log.h>
+ *
+ * Compilation will fail when included file has different version.
+ */
+#define TRANSPORT_LOG_VERSION 4
+#if defined(TRANSPORT_LOG_VERSION_REQUIRED)
+#if TRANSPORT_LOG_VERSION_REQUIRED != TRANSPORT_LOG_VERSION
+#error different transport_log version required
+#endif
+#endif
+
+/* Log level guideline:
+ * - TRANSPORT_LOG_FATAL - happened something impossible and absolutely
+ * unexpected. Process can't continue and must be terminated. Example: division
+ * by zero, unexpected modifications from other thread.
+ * - TRANSPORT_LOG_ERROR - happened something possible, but highly unexpected.
+ * The process is able to recover and continue execution. Example: out of memory
+ * (could also be FATAL if not handled properly).
+ * - TRANSPORT_LOG_WARN - happened something that *usually* should not happen
+ * and significantly changes application behavior for some period of time.
+ * Example: configuration file not found, auth error.
+ * - TRANSPORT_LOG_INFO - happened significant life cycle event or major state
+ * transition.
+ * Example: app started, user logged in.
+ * - TRANSPORT_LOG_DEBUG - minimal set of events that could help to reconstruct
+ * the execution path. Usually disabled in release builds.
+ * - TRANSPORT_LOG_VERBOSE - all other events. Usually disabled in release
+ * builds.
+ *
+ * *Ideally*, log file of debugged, well tested, production ready application
+ * should be empty or very small. Choosing a right log level is as important as
+ * providing short and self descriptive log message.
+ */
+#define TRANSPORT_LOG_VERBOSE 1
+#define TRANSPORT_LOG_DEBUG 2
+#define TRANSPORT_LOG_INFO 3
+#define TRANSPORT_LOG_WARN 4
+#define TRANSPORT_LOG_ERROR 5
+#define TRANSPORT_LOG_FATAL 6
+#define TRANSPORT_LOG_NONE 0xFF
+
+/* "Current" log level is a compile time check and has no runtime overhead. Log
+ * level that is below current log level it said to be "disabled". Otherwise,
+ * it's "enabled". Log messages that are disabled has no runtime overhead - they
+ * are converted to no-op by preprocessor and then eliminated by compiler.
+ * Current log level is configured per compilation module (.c/.cpp/.m file) by
+ * defining TRANSPORT_LOG_DEF_LEVEL or TRANSPORT_LOG_LEVEL. TRANSPORT_LOG_LEVEL
+ * has higer priority and when defined overrides value provided by
+ * TRANSPORT_LOG_DEF_LEVEL.
+ *
+ * Common practice is to define default current log level with
+ * TRANSPORT_LOG_DEF_LEVEL in build script (e.g. Makefile, CMakeLists.txt, gyp,
+ * etc.) for the entire project or target:
+ *
+ * CC_ARGS := -DTRANSPORT_LOG_DEF_LEVEL=TRANSPORT_LOG_INFO
+ *
+ * And when necessary to override it with TRANSPORT_LOG_LEVEL in .c/.cpp/.m
+ * files before including transport_log.h:
+ *
+ * #define TRANSPORT_LOG_LEVEL TRANSPORT_LOG_VERBOSE
+ * #include <hicn/transport_log.h>
+ *
+ * If both TRANSPORT_LOG_DEF_LEVEL and TRANSPORT_LOG_LEVEL are undefined, then
+ * TRANSPORT_LOG_INFO will be used for release builds (NDEBUG is defined) and
+ * TRANSPORT_LOG_DEBUG otherwise (NDEBUG is not defined).
+ */
+#if defined(TRANSPORT_LOG_LEVEL)
+#define _TRANSPORT_LOG_LEVEL TRANSPORT_LOG_LEVEL
+#elif defined(TRANSPORT_LOG_DEF_LEVEL)
+#define _TRANSPORT_LOG_LEVEL TRANSPORT_LOG_DEF_LEVEL
+#else
+#ifdef NDEBUG
+#define _TRANSPORT_LOG_LEVEL TRANSPORT_LOG_INFO
+#else
+#define _TRANSPORT_LOG_LEVEL TRANSPORT_LOG_DEBUG
+#endif
+#endif
+
+/* "Output" log level is a runtime check. When log level is below output log
+ * level it said to be "turned off" (or just "off" for short). Otherwise it's
+ * "turned on" (or just "on"). Log levels that were "disabled" (see
+ * TRANSPORT_LOG_LEVEL and TRANSPORT_LOG_DEF_LEVEL) can't be "turned on", but
+ * "enabled" log levels could be "turned off". Only messages with log level
+ * which is "turned on" will reach output facility. All other messages will be
+ * ignored (and their arguments will not be evaluated). Output log level is a
+ * global property and configured per process using
+ * transport_log_set_output_level() function which can be called at any time.
+ *
+ * Though in some cases it could be useful to configure output log level per
+ * compilation module or per library. There are two ways to achieve that:
+ * - Define TRANSPORT_LOG_OUTPUT_LEVEL to expresion that evaluates to desired
+ * output log level.
+ * - Copy transport_log.h and transport_log.c files into your library and build
+ * it with TRANSPORT_LOG_LIBRARY_PREFIX defined to library specific prefix. See
+ * TRANSPORT_LOG_LIBRARY_PREFIX for more details.
+ *
+ * When defined, TRANSPORT_LOG_OUTPUT_LEVEL must evaluate to integral value that
+ * corresponds to desired output log level. Use it only when compilation module
+ * is required to have output log level which is different from global output
+ * log level set by transport_log_set_output_level() function. For other cases,
+ * consider defining TRANSPORT_LOG_LEVEL or using
+ * transport_log_set_output_level() function.
+ *
+ * Example:
+ *
+ * #define TRANSPORT_LOG_OUTPUT_LEVEL g_module_log_level
+ * #include <hicn/transport_log.h>
+ * static int g_module_log_level = TRANSPORT_LOG_INFO;
+ * static void foo() {
+ * TRANSPORT_LOGI("Will check g_module_log_level for output log level");
+ * }
+ * void debug_log(bool on) {
+ * g_module_log_level = on? TRANSPORT_LOG_DEBUG: TRANSPORT_LOG_INFO;
+ * }
+ *
+ * Note on performance. This expression will be evaluated each time message is
+ * logged (except when message log level is "disabled" - see TRANSPORT_LOG_LEVEL
+ * for details). Keep this expression as simple as possible, otherwise it will
+ * not only add runtime overhead, but also will increase size of call site
+ * (which will result in larger executable). The prefered way is to use integer
+ * variable (as in example above). If structure must be used, log_level field
+ * must be the first field in this structure:
+ *
+ * #define TRANSPORT_LOG_OUTPUT_LEVEL (g_config.log_level)
+ * #include <hicn/transport_log.h>
+ * struct config {
+ * int log_level;
+ * unsigned other_field;
+ * [...]
+ * };
+ * static config g_config = {TRANSPORT_LOG_INFO, 0, ...};
+ *
+ * This allows compiler to generate more compact load instruction (no need to
+ * specify offset since it's zero). Calling a function to get output log level
+ * is generaly a bad idea, since it will increase call site size and runtime
+ * overhead even further.
+ */
+#if defined(TRANSPORT_LOG_OUTPUT_LEVEL)
+#define _TRANSPORT_LOG_OUTPUT_LEVEL TRANSPORT_LOG_OUTPUT_LEVEL
+#else
+#define _TRANSPORT_LOG_OUTPUT_LEVEL _transport_log_global_output_lvl
+#endif
+
+/* "Tag" is a compound string that could be associated with a log message. It
+ * consists of tag prefix and tag (both are optional).
+ *
+ * Tag prefix is a global property and configured per process using
+ * transport_log_set_tag_prefix() function. Tag prefix identifies context in
+ * which component or module is running (e.g. process name). For example, the
+ * same library could be used in both client and server processes that work on
+ * the same machine. Tag prefix could be used to easily distinguish between
+ * them. For more details about tag prefix see transport_log_set_tag_prefix()
+ * function. Tag prefix
+ *
+ * Tag identifies component or module. It is configured per compilation module
+ * (.c/.cpp/.m file) by defining TRANSPORT_LOG_TAG or TRANSPORT_LOG_DEF_TAG.
+ * TRANSPORT_LOG_TAG has higer priority and when defined overrides value
+ * provided by TRANSPORT_LOG_DEF_TAG. When defined, value must evaluate to
+ * (const char *), so for strings double quotes must be used.
+ *
+ * Default tag could be defined with TRANSPORT_LOG_DEF_TAG in build script (e.g.
+ * Makefile, CMakeLists.txt, gyp, etc.) for the entire project or target:
+ *
+ * CC_ARGS := -DTRANSPORT_LOG_DEF_TAG=\"MISC\"
+ *
+ * And when necessary could be overriden with TRANSPORT_LOG_TAG in .c/.cpp/.m
+ * files before including transport_log.h:
+ *
+ * #define TRANSPORT_LOG_TAG "MAIN"
+ * #include <hicn/transport_log.h>
+ *
+ * If both TRANSPORT_LOG_DEF_TAG and TRANSPORT_LOG_TAG are undefined no tag will
+ * be added to the log message (tag prefix still could be added though).
+ *
+ * Output example:
+ *
+ * 04-29 22:43:20.244 40059 1299 I hello.MAIN Number of arguments: 1
+ * | |
+ * | +- tag (e.g. module)
+ * +- tag prefix (e.g. process name)
+ */
+#if defined(TRANSPORT_LOG_TAG)
+#define _TRANSPORT_LOG_TAG TRANSPORT_LOG_TAG
+#elif defined(TRANSPORT_LOG_DEF_TAG)
+#define _TRANSPORT_LOG_TAG TRANSPORT_LOG_DEF_TAG
+#else
+#define _TRANSPORT_LOG_TAG 0
+#endif
+
+/* Source location is part of a log line that describes location (function or
+ * method name, file name and line number, e.g. "runloop@main.cpp:68") of a
+ * log statement that produced it.
+ * Source location formats are:
+ * - TRANSPORT_LOG_SRCLOC_NONE - don't add source location to log line.
+ * - TRANSPORT_LOG_SRCLOC_SHORT - add source location in short form (file and
+ * line number, e.g. "@main.cpp:68").
+ * - TRANSPORT_LOG_SRCLOC_LONG - add source location in long form (function or
+ * method name, file and line number, e.g. "runloop@main.cpp:68").
+ */
+#define TRANSPORT_LOG_SRCLOC_NONE 0
+#define TRANSPORT_LOG_SRCLOC_SHORT 1
+#define TRANSPORT_LOG_SRCLOC_LONG 2
+
+/* Source location format is configured per compilation module (.c/.cpp/.m
+ * file) by defining TRANSPORT_LOG_DEF_SRCLOC or TRANSPORT_LOG_SRCLOC.
+ * TRANSPORT_LOG_SRCLOC has higer priority and when defined overrides value
+ * provided by TRANSPORT_LOG_DEF_SRCLOC.
+ *
+ * Common practice is to define default format with TRANSPORT_LOG_DEF_SRCLOC in
+ * build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire
+ * project or target:
+ *
+ * CC_ARGS := -DTRANSPORT_LOG_DEF_SRCLOC=TRANSPORT_LOG_SRCLOC_LONG
+ *
+ * And when necessary to override it with TRANSPORT_LOG_SRCLOC in .c/.cpp/.m
+ * files before including transport_log.h:
+ *
+ * #define TRANSPORT_LOG_SRCLOC TRANSPORT_LOG_SRCLOC_NONE
+ * #include <hicn/transport_log.h>
+ *
+ * If both TRANSPORT_LOG_DEF_SRCLOC and TRANSPORT_LOG_SRCLOC are undefined, then
+ * TRANSPORT_LOG_SRCLOC_NONE will be used for release builds (NDEBUG is defined)
+ * and TRANSPORT_LOG_SRCLOC_LONG otherwise (NDEBUG is not defined).
+ */
+#if defined(TRANSPORT_LOG_SRCLOC)
+#define _TRANSPORT_LOG_SRCLOC TRANSPORT_LOG_SRCLOC
+#elif defined(TRANSPORT_LOG_DEF_SRCLOC)
+#define _TRANSPORT_LOG_SRCLOC TRANSPORT_LOG_DEF_SRCLOC
+#else
+#ifdef NDEBUG
+#define _TRANSPORT_LOG_SRCLOC TRANSPORT_LOG_SRCLOC_NONE
+#else
+#define _TRANSPORT_LOG_SRCLOC TRANSPORT_LOG_SRCLOC_LONG
+#endif
+#endif
+#if TRANSPORT_LOG_SRCLOC_LONG == _TRANSPORT_LOG_SRCLOC
+#define _TRANSPORT_LOG_SRCLOC_FUNCTION _TRANSPORT_LOG_FUNCTION
+#else
+#define _TRANSPORT_LOG_SRCLOC_FUNCTION 0
+#endif
+
+/* Censoring provides conditional logging of secret information, also known as
+ * Personally Identifiable Information (PII) or Sensitive Personal Information
+ * (SPI). Censoring can be either enabled (TRANSPORT_LOG_CENSORED) or disabled
+ * (TRANSPORT_LOG_UNCENSORED). When censoring is enabled, log statements marked
+ * as "secrets" will be ignored and will have zero overhead (arguments also will
+ * not be evaluated).
+ */
+#define TRANSPORT_LOG_CENSORED 1
+#define TRANSPORT_LOG_UNCENSORED 0
+
+/* Censoring is configured per compilation module (.c/.cpp/.m file) by defining
+ * TRANSPORT_LOG_DEF_CENSORING or TRANSPORT_LOG_CENSORING.
+ * TRANSPORT_LOG_CENSORING has higer priority and when defined overrides value
+ * provided by TRANSPORT_LOG_DEF_CENSORING.
+ *
+ * Common practice is to define default censoring with
+ * TRANSPORT_LOG_DEF_CENSORING in build script (e.g. Makefile, CMakeLists.txt,
+ * gyp, etc.) for the entire project or target:
+ *
+ * CC_ARGS := -DTRANSPORT_LOG_DEF_CENSORING=TRANSPORT_LOG_CENSORED
+ *
+ * And when necessary to override it with TRANSPORT_LOG_CENSORING in .c/.cpp/.m
+ * files before including transport_log.h (consider doing it only for debug
+ * purposes and be very careful not to push such temporary changes to source
+ * control):
+ *
+ * #define TRANSPORT_LOG_CENSORING TRANSPORT_LOG_UNCENSORED
+ * #include <hicn/transport_log.h>
+ *
+ * If both TRANSPORT_LOG_DEF_CENSORING and TRANSPORT_LOG_CENSORING are
+ * undefined, then TRANSPORT_LOG_CENSORED will be used for release builds
+ * (NDEBUG is defined) and TRANSPORT_LOG_UNCENSORED otherwise (NDEBUG is not
+ * defined).
+ */
+#if defined(TRANSPORT_LOG_CENSORING)
+#define _TRANSPORT_LOG_CENSORING TRANSPORT_LOG_CENSORING
+#elif defined(TRANSPORT_LOG_DEF_CENSORING)
+#define _TRANSPORT_LOG_CENSORING TRANSPORT_LOG_DEF_CENSORING
+#else
+#ifdef NDEBUG
+#define _TRANSPORT_LOG_CENSORING TRANSPORT_LOG_CENSORED
+#else
+#define _TRANSPORT_LOG_CENSORING TRANSPORT_LOG_UNCENSORED
+#endif
+#endif
+
+/* Check censoring at compile time. Evaluates to true when censoring is disabled
+ * (i.e. when secrets will be logged). For example:
+ *
+ * #if TRANSPORT_LOG_SECRETS
+ * char ssn[16];
+ * getSocialSecurityNumber(ssn);
+ * TRANSPORT_LOGI("Customer ssn: %s", ssn);
+ * #endif
+ *
+ * See TRANSPORT_LOG_SECRET() macro for a more convenient way of guarding single
+ * log statement.
+ */
+#define TRANSPORT_LOG_SECRETS \
+ (TRANSPORT_LOG_UNCENSORED == _TRANSPORT_LOG_CENSORING)
+
+/* Static (compile-time) initialization support allows to configure logging
+ * before entering main() function. This mostly useful in C++ where functions
+ * and methods could be called during initialization of global objects. Those
+ * functions and methods could record log messages too and for that reason
+ * static initialization of logging configuration is customizable.
+ *
+ * Macros below allow to specify values to use for initial configuration:
+ * - TRANSPORT_LOG_EXTERN_TAG_PREFIX - tag prefix (default: none)
+ * - TRANSPORT_LOG_EXTERN_GLOBAL_FORMAT - global format options (default: see
+ * TRANSPORT_LOG_MEM_WIDTH in transport_log.c)
+ * - TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT - global output facility (default:
+ * stderr or platform specific, see TRANSPORT_LOG_USE_XXX macros in
+ * transport_log.c)
+ * - TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL - global output log level
+ * (default: 0 - all levals are "turned on")
+ *
+ * For example, in log_config.c:
+ *
+ * #include <hicn/transport_log.h>
+ * TRANSPORT_LOG_DEFINE_TAG_PREFIX = "MyApp";
+ * TRANSPORT_LOG_DEFINE_GLOBAL_FORMAT = {CUSTOM_MEM_WIDTH};
+ * TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT = {TRANSPORT_LOG_PUT_STD,
+ * custom_output_callback, 0}; TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL =
+ * TRANSPORT_LOG_INFO;
+ *
+ * However, to use any of those macros transport_log library must be compiled
+ * with following macros defined:
+ * - to use TRANSPORT_LOG_DEFINE_TAG_PREFIX define
+ * TRANSPORT_LOG_EXTERN_TAG_PREFIX
+ * - to use TRANSPORT_LOG_DEFINE_GLOBAL_FORMAT define
+ * TRANSPORT_LOG_EXTERN_GLOBAL_FORMAT
+ * - to use TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT define
+ * TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT
+ * - to use TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL define
+ * TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL
+ *
+ * When transport_log library compiled with one of TRANSPORT_LOG_EXTERN_XXX
+ * macros defined, corresponding TRANSPORT_LOG_DEFINE_XXX macro MUST be used
+ * exactly once somewhere. Otherwise build will fail with link error (undefined
+ * symbol).
+ */
+#define TRANSPORT_LOG_DEFINE_TAG_PREFIX const char *_transport_log_tag_prefix
+#define TRANSPORT_LOG_DEFINE_GLOBAL_FORMAT \
+ transport_log_format _transport_log_global_format
+#define TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT \
+ transport_log_output _transport_log_global_output
+#define TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL \
+ int _transport_log_global_output_lvl
+
+/* Pointer to global format options. Direct modification is not allowed. Use
+ * transport_log_set_mem_width() instead. Could be used to initialize
+ * transport_log_spec structure:
+ *
+ * const transport_log_output g_output = {TRANSPORT_LOG_PUT_STD,
+ * output_callback, 0}; const transport_log_spec g_spec =
+ * {TRANSPORT_LOG_GLOBAL_FORMAT, &g_output}; TRANSPORT_LOGI_AUX(&g_spec,
+ * "Hello");
+ */
+#define TRANSPORT_LOG_GLOBAL_FORMAT \
+ ((const transport_log_format *)&_transport_log_global_format)
+
+/* Pointer to global output variable. Direct modification is not allowed. Use
+ * transport_log_set_output_v() or transport_log_set_output_p() instead. Could
+ * be used to initialize transport_log_spec structure:
+ *
+ * const transport_log_format g_format = {40};
+ * const transport_log_spec g_spec = {g_format, TRANSPORT_LOG_GLOBAL_OUTPUT};
+ * TRANSPORT_LOGI_AUX(&g_spec, "Hello");
+ */
+#define TRANSPORT_LOG_GLOBAL_OUTPUT \
+ ((const transport_log_output *)&_transport_log_global_output)
+
+/* When defined, all library symbols produced by linker will be prefixed with
+ * provided value. That allows to use transport_log library privately in another
+ * libraries without exposing transport_log symbols in their original form (to
+ * avoid possible conflicts with other libraries / components that also could
+ * use transport_log for logging). Value must be without quotes, for example:
+ *
+ * CC_ARGS := -DTRANSPORT_LOG_LIBRARY_PREFIX=my_lib_
+ *
+ * Note, that in this mode TRANSPORT_LOG_LIBRARY_PREFIX must be defined when
+ * building transport_log library AND it also must be defined to the same value
+ * when building a library that uses it. For example, consider fictional
+ * KittyHttp library that wants to use transport_log for logging. First approach
+ * that could be taken is to add transport_log.h and transport_log.c to the
+ * KittyHttp's source code tree directly. In that case it will be enough just to
+ * define TRANSPORT_LOG_LIBRARY_PREFIX in KittyHttp's build script:
+ *
+ * // KittyHttp/CMakeLists.txt
+ * target_compile_definitions(KittyHttp PRIVATE
+ * "TRANSPORT_LOG_LIBRARY_PREFIX=KittyHttp_")
+ *
+ * If KittyHttp doesn't want to include transport_log source code in its source
+ * tree and wants to build transport_log as a separate library than
+ * transport_log library must be built with TRANSPORT_LOG_LIBRARY_PREFIX defined
+ * to KittyHttp_ AND KittyHttp library itself also needs to define
+ * TRANSPORT_LOG_LIBRARY_PREFIX to KittyHttp_. It can do so either in its build
+ * script, as in example above, or by providing a wrapper header that KittyHttp
+ * library will need to use instead of transport_log.h:
+ *
+ * // KittyHttpLogging.h
+ * #define TRANSPORT_LOG_LIBRARY_PREFIX KittyHttp_
+ * #include <hicn/transport_log.h>
+ *
+ * Regardless of the method chosen, the end result is that transport_log symbols
+ * will be prefixed with "KittyHttp_", so if a user of KittyHttp (say
+ * DogeBrowser) also uses transport_log for logging, they will not interferer
+ * with each other. Both will have their own log level, output facility, format
+ * options etc.
+ */
+#ifdef TRANSPORT_LOG_LIBRARY_PREFIX
+#define _TRANSPORT_LOG_DECOR__(prefix, name) prefix##name
+#define _TRANSPORT_LOG_DECOR_(prefix, name) _TRANSPORT_LOG_DECOR__(prefix, name)
+#define _TRANSPORT_LOG_DECOR(name) \
+ _TRANSPORT_LOG_DECOR_(TRANSPORT_LOG_LIBRARY_PREFIX, name)
+
+#define transport_log_set_tag_prefix \
+ _TRANSPORT_LOG_DECOR(transport_log_set_tag_prefix)
+#define transport_log_set_mem_width \
+ _TRANSPORT_LOG_DECOR(transport_log_set_mem_width)
+#define transport_log_set_output_level \
+ _TRANSPORT_LOG_DECOR(transport_log_set_output_level)
+#define transport_log_set_output_v \
+ _TRANSPORT_LOG_DECOR(transport_log_set_output_v)
+#define transport_log_set_output_p \
+ _TRANSPORT_LOG_DECOR(transport_log_set_output_p)
+#define transport_log_out_stderr_callback \
+ _TRANSPORT_LOG_DECOR(transport_log_out_stderr_callback)
+#define _transport_log_tag_prefix \
+ _TRANSPORT_LOG_DECOR(_transport_log_tag_prefix)
+#define _transport_log_global_format \
+ _TRANSPORT_LOG_DECOR(_transport_log_global_format)
+#define _transport_log_global_output \
+ _TRANSPORT_LOG_DECOR(_transport_log_global_output)
+#define _transport_log_global_output_lvl \
+ _TRANSPORT_LOG_DECOR(_transport_log_global_output_lvl)
+#define _transport_log_write_d _TRANSPORT_LOG_DECOR(_transport_log_write_d)
+#define _transport_log_write_aux_d \
+ _TRANSPORT_LOG_DECOR(_transport_log_write_aux_d)
+#define _transport_log_write _TRANSPORT_LOG_DECOR(_transport_log_write)
+#define _transport_log_write_aux _TRANSPORT_LOG_DECOR(_transport_log_write_aux)
+#define _transport_log_write_mem_d \
+ _TRANSPORT_LOG_DECOR(_transport_log_write_mem_d)
+#define _transport_log_write_mem_aux_d \
+ _TRANSPORT_LOG_DECOR(_transport_log_write_mem_aux_d)
+#define _transport_log_write_mem _TRANSPORT_LOG_DECOR(_transport_log_write_mem)
+#define _transport_log_write_mem_aux \
+ _TRANSPORT_LOG_DECOR(_transport_log_write_mem_aux)
+#define _transport_log_stderr_spec \
+ _TRANSPORT_LOG_DECOR(_transport_log_stderr_spec)
+#endif
+
+#if defined(__printflike)
+#define _TRANSPORT_LOG_PRINTFLIKE(str_index, first_to_check) \
+ __printflike(str_index, first_to_check)
+#elif defined(__GNUC__)
+#define _TRANSPORT_LOG_PRINTFLIKE(str_index, first_to_check) \
+ __attribute__((format(__printf__, str_index, first_to_check)))
+#else
+#define _TRANSPORT_LOG_PRINTFLIKE(str_index, first_to_check)
+#endif
+
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__GNUC__)
+#define _TRANSPORT_LOG_FUNCTION __FUNCTION__
+#else
+#define _TRANSPORT_LOG_FUNCTION __func__
+#endif
+
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+#define _TRANSPORT_LOG_INLINE __inline
+#define _TRANSPORT_LOG_IF(cond) \
+ __pragma(warning(push)) __pragma(warning(disable : 4127)) if (cond) \
+ __pragma(warning(pop))
+#define _TRANSPORT_LOG_WHILE(cond) \
+ __pragma(warning(push)) __pragma(warning(disable : 4127)) while (cond) \
+ __pragma(warning(pop))
+#else
+#define _TRANSPORT_LOG_INLINE inline
+#define _TRANSPORT_LOG_IF(cond) if (cond)
+#define _TRANSPORT_LOG_WHILE(cond) while (cond)
+#endif
+#define _TRANSPORT_LOG_NEVER _TRANSPORT_LOG_IF(0)
+#define _TRANSPORT_LOG_ONCE _TRANSPORT_LOG_WHILE(0)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Set tag prefix. Prefix will be separated from the tag with dot ('.').
+ * Use 0 or empty string to disable (default). Common use is to set it to
+ * the process (or build target) name (e.g. to separate client and server
+ * processes). Function will NOT copy provided prefix string, but will store the
+ * pointer. Hence specified prefix string must remain valid. See
+ * TRANSPORT_LOG_DEFINE_TAG_PREFIX for a way to set it before entering main()
+ * function. See TRANSPORT_LOG_TAG for more information about tag and tag
+ * prefix.
+ */
+void transport_log_set_tag_prefix(const char *const prefix);
+
+/* Set number of bytes per log line in memory (ASCII-HEX) output. Example:
+ *
+ * I hello.MAIN 4c6f72656d20697073756d20646f6c6f Lorem ipsum dolo
+ * |<- w bytes ->| |<- w chars ->|
+ *
+ * See TRANSPORT_LOGF_MEM and TRANSPORT_LOGF_MEM_AUX for more details.
+ */
+void transport_log_set_mem_width(const unsigned w);
+
+/* Set "output" log level. See TRANSPORT_LOG_LEVEL and
+ * TRANSPORT_LOG_OUTPUT_LEVEL for more info about log levels.
+ */
+void transport_log_set_output_level(const int lvl);
+
+/* Put mask is a set of flags that define what fields will be added to each
+ * log message. Default value is TRANSPORT_LOG_PUT_STD and other flags could be
+ * used to alter its behavior. See transport_log_set_output_v() for more
+ * details.
+ *
+ * Note about TRANSPORT_LOG_PUT_SRC: it will be added only in debug builds
+ * (NDEBUG is not defined).
+ */
+enum {
+ TRANSPORT_LOG_PUT_CTX = 1 << 0, /* context (time, pid, tid, log level) */
+ TRANSPORT_LOG_PUT_TAG = 1 << 1, /* tag (including tag prefix) */
+ TRANSPORT_LOG_PUT_SRC = 1 << 2, /* source location (file, line, function) */
+ TRANSPORT_LOG_PUT_MSG = 1 << 3, /* message text (formatted string) */
+ TRANSPORT_LOG_PUT_STD = 0xffff, /* everything (default) */
+};
+
+typedef struct transport_log_message {
+ int lvl; /* Log level of the message */
+ const char *tag; /* Associated tag (without tag prefix) */
+ char *buf; /* Buffer start */
+ char *e; /* Buffer end (last position where EOL with 0 could be written) */
+ char *p; /* Buffer content end (append position) */
+ char *tag_b; /* Prefixed tag start */
+ char *tag_e; /* Prefixed tag end (if != tag_b, points to msg separator) */
+ char *msg_b; /* Message start (expanded format string) */
+} transport_log_message;
+
+/* Type of output callback function. It will be called for each log line allowed
+ * by both "current" and "output" log levels ("enabled" and "turned on").
+ * Callback function is allowed to modify content of the buffers pointed by the
+ * msg, but it's not allowed to modify any of msg fields. Buffer pointed by msg
+ * is UTF-8 encoded (no BOM mark).
+ */
+typedef void (*transport_log_output_cb)(const transport_log_message *msg,
+ void *arg);
+
+/* Format options. For more details see transport_log_set_mem_width().
+ */
+typedef struct transport_log_format {
+ unsigned mem_width; /* Bytes per line in memory (ASCII-HEX) dump */
+} transport_log_format;
+
+/* Output facility.
+ */
+typedef struct transport_log_output {
+ unsigned
+ mask; /* What to put into log line buffer (see TRANSPORT_LOG_PUT_XXX) */
+ void *arg; /* User provided output callback argument */
+ transport_log_output_cb callback; /* Output callback function */
+} transport_log_output;
+
+/* Set output callback function.
+ *
+ * Mask allows to control what information will be added to the log line buffer
+ * before callback function is invoked. Default mask value is
+ * TRANSPORT_LOG_PUT_STD.
+ */
+void transport_log_set_output_v(const unsigned mask, void *const arg,
+ const transport_log_output_cb callback);
+static _TRANSPORT_LOG_INLINE void transport_log_set_output_p(
+ const transport_log_output *const output) {
+ transport_log_set_output_v(output->mask, output->arg, output->callback);
+}
+
+/* Used with _AUX macros and allows to override global format and output
+ * facility. Use TRANSPORT_LOG_GLOBAL_FORMAT and TRANSPORT_LOG_GLOBAL_OUTPUT for
+ * values from global configuration. Example:
+ *
+ * static const transport_log_output module_output = {
+ * TRANSPORT_LOG_PUT_STD, 0, custom_output_callback
+ * };
+ * static const transport_log_spec module_spec = {
+ * TRANSPORT_LOG_GLOBAL_FORMAT, &module_output
+ * };
+ * TRANSPORT_LOGI_AUX(&module_spec, "Position: %ix%i", x, y);
+ *
+ * See TRANSPORT_LOGF_AUX and TRANSPORT_LOGF_MEM_AUX for details.
+ */
+typedef struct transport_log_spec {
+ const transport_log_format *format;
+ const transport_log_output *output;
+} transport_log_spec;
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Execute log statement if condition is true. Example:
+ *
+ * TRANSPORT_LOG_IF(1 < 2, TRANSPORT_LOGI("Log this"));
+ * TRANSPORT_LOG_IF(1 > 2, TRANSPORT_LOGI("Don't log this"));
+ *
+ * Keep in mind though, that if condition can't be evaluated at compile time,
+ * then it will be evaluated at run time. This will increase exectuable size
+ * and can have noticeable performance overhead. Try to limit conditions to
+ * expressions that can be evaluated at compile time.
+ */
+#define TRANSPORT_LOG_IF(cond, f) \
+ do { \
+ _TRANSPORT_LOG_IF((cond)) { f; } \
+ } \
+ _TRANSPORT_LOG_ONCE
+
+/* Mark log statement as "secret". Log statements that are marked as secrets
+ * will NOT be executed when censoring is enabled (see TRANSPORT_LOG_CENSORED).
+ * Example:
+ *
+ * TRANSPORT_LOG_SECRET(TRANSPORT_LOGI("Credit card: %s", credit_card));
+ * TRANSPORT_LOG_SECRET(TRANSPORT_LOGD_MEM(cipher, cipher_sz, "Cipher
+ * bytes:"));
+ */
+#define TRANSPORT_LOG_SECRET(f) TRANSPORT_LOG_IF(TRANSPORT_LOG_SECRETS, f)
+
+/* Check "current" log level at compile time (ignoring "output" log level).
+ * Evaluates to true when specified log level is enabled. For example:
+ *
+ * #if TRANSPORT_LOG_ENABLED_DEBUG
+ * const char *const g_enum_strings[] = {
+ * "enum_value_0", "enum_value_1", "enum_value_2"
+ * };
+ * #endif
+ * // ...
+ * #if TRANSPORT_LOG_ENABLED_DEBUG
+ * TRANSPORT_LOGD("enum value: %s", g_enum_strings[v]);
+ * #endif
+ *
+ * See TRANSPORT_LOG_LEVEL for details.
+ */
+#define TRANSPORT_LOG_ENABLED(lvl) ((lvl) >= _TRANSPORT_LOG_LEVEL)
+#define TRANSPORT_LOG_ENABLED_VERBOSE \
+ TRANSPORT_LOG_ENABLED(TRANSPORT_LOG_VERBOSE)
+#define TRANSPORT_LOG_ENABLED_DEBUG TRANSPORT_LOG_ENABLED(TRANSPORT_LOG_DEBUG)
+#define TRANSPORT_LOG_ENABLED_INFO TRANSPORT_LOG_ENABLED(TRANSPORT_LOG_INFO)
+#define TRANSPORT_LOG_ENABLED_WARN TRANSPORT_LOG_ENABLED(TRANSPORT_LOG_WARN)
+#define TRANSPORT_LOG_ENABLED_ERROR TRANSPORT_LOG_ENABLED(TRANSPORT_LOG_ERROR)
+#define TRANSPORT_LOG_ENABLED_FATAL TRANSPORT_LOG_ENABLED(TRANSPORT_LOG_FATAL)
+
+/* Check "output" log level at run time (taking into account "current" log
+ * level as well). Evaluates to true when specified log level is turned on AND
+ * enabled. For example:
+ *
+ * if (TRANSPORT_LOG_ON_DEBUG)
+ * {
+ * char hash[65];
+ * sha256(data_ptr, data_sz, hash);
+ * TRANSPORT_LOGD("data: len=%u, sha256=%s", data_sz, hash);
+ * }
+ *
+ * See TRANSPORT_LOG_OUTPUT_LEVEL for details.
+ */
+#define TRANSPORT_LOG_ON(lvl) \
+ (TRANSPORT_LOG_ENABLED((lvl)) && (lvl) >= _TRANSPORT_LOG_OUTPUT_LEVEL)
+#define TRANSPORT_LOG_ON_VERBOSE TRANSPORT_LOG_ON(TRANSPORT_LOG_VERBOSE)
+#define TRANSPORT_LOG_ON_DEBUG TRANSPORT_LOG_ON(TRANSPORT_LOG_DEBUG)
+#define TRANSPORT_LOG_ON_INFO TRANSPORT_LOG_ON(TRANSPORT_LOG_INFO)
+#define TRANSPORT_LOG_ON_WARN TRANSPORT_LOG_ON(TRANSPORT_LOG_WARN)
+#define TRANSPORT_LOG_ON_ERROR TRANSPORT_LOG_ON(TRANSPORT_LOG_ERROR)
+#define TRANSPORT_LOG_ON_FATAL TRANSPORT_LOG_ON(TRANSPORT_LOG_FATAL)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char *_transport_log_tag_prefix;
+extern transport_log_format _transport_log_global_format;
+extern transport_log_output _transport_log_global_output;
+extern int _transport_log_global_output_lvl;
+extern const transport_log_spec _transport_log_stderr_spec;
+
+void _transport_log_write_d(const char *const func, const char *const file,
+ const unsigned line, const int lvl,
+ const char *const tag, const char *const fmt, ...)
+ _TRANSPORT_LOG_PRINTFLIKE(6, 7);
+void _transport_log_write_aux_d(const char *const func, const char *const file,
+ const unsigned line,
+ const transport_log_spec *const log,
+ const int lvl, const char *const tag,
+ const char *const fmt, ...)
+ _TRANSPORT_LOG_PRINTFLIKE(7, 8);
+void _transport_log_write(const int lvl, const char *const tag,
+ const char *const fmt, ...)
+ _TRANSPORT_LOG_PRINTFLIKE(3, 4);
+void _transport_log_write_aux(const transport_log_spec *const log,
+ const int lvl, const char *const tag,
+ const char *const fmt, ...)
+ _TRANSPORT_LOG_PRINTFLIKE(4, 5);
+void _transport_log_write_mem_d(const char *const func, const char *const file,
+ const unsigned line, const int lvl,
+ const char *const tag, const void *const d,
+ const unsigned d_sz, const char *const fmt, ...)
+ _TRANSPORT_LOG_PRINTFLIKE(8, 9);
+void _transport_log_write_mem_aux_d(const char *const func,
+ const char *const file, const unsigned line,
+ const transport_log_spec *const log,
+ const int lvl, const char *const tag,
+ const void *const d, const unsigned d_sz,
+ const char *const fmt, ...)
+ _TRANSPORT_LOG_PRINTFLIKE(9, 10);
+void _transport_log_write_mem(const int lvl, const char *const tag,
+ const void *const d, const unsigned d_sz,
+ const char *const fmt, ...)
+ _TRANSPORT_LOG_PRINTFLIKE(5, 6);
+void _transport_log_write_mem_aux(const transport_log_spec *const log,
+ const int lvl, const char *const tag,
+ const void *const d, const unsigned d_sz,
+ const char *const fmt, ...)
+ _TRANSPORT_LOG_PRINTFLIKE(6, 7);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Message logging macros:
+ * - TRANSPORT_LOGV("format string", args, ...)
+ * - TRANSPORT_LOGD("format string", args, ...)
+ * - TRANSPORT_LOGI("format string", args, ...)
+ * - TRANSPORT_LOGW("format string", args, ...)
+ * - TRANSPORT_LOGE("format string", args, ...)
+ * - TRANSPORT_LOGF("format string", args, ...)
+ *
+ * Memory logging macros:
+ * - TRANSPORT_LOGV_MEM(data_ptr, data_sz, "format string", args, ...)
+ * - TRANSPORT_LOGD_MEM(data_ptr, data_sz, "format string", args, ...)
+ * - TRANSPORT_LOGI_MEM(data_ptr, data_sz, "format string", args, ...)
+ * - TRANSPORT_LOGW_MEM(data_ptr, data_sz, "format string", args, ...)
+ * - TRANSPORT_LOGE_MEM(data_ptr, data_sz, "format string", args, ...)
+ * - TRANSPORT_LOGF_MEM(data_ptr, data_sz, "format string", args, ...)
+ *
+ * Auxiliary logging macros:
+ * - TRANSPORT_LOGV_AUX(&log_instance, "format string", args, ...)
+ * - TRANSPORT_LOGD_AUX(&log_instance, "format string", args, ...)
+ * - TRANSPORT_LOGI_AUX(&log_instance, "format string", args, ...)
+ * - TRANSPORT_LOGW_AUX(&log_instance, "format string", args, ...)
+ * - TRANSPORT_LOGE_AUX(&log_instance, "format string", args, ...)
+ * - TRANSPORT_LOGF_AUX(&log_instance, "format string", args, ...)
+ *
+ * Auxiliary memory logging macros:
+ * - TRANSPORT_LOGV_MEM_AUX(&log_instance, data_ptr, data_sz, "format string",
+ * args, ...)
+ * - TRANSPORT_LOGD_MEM_AUX(&log_instance, data_ptr, data_sz, "format string",
+ * args, ...)
+ * - TRANSPORT_LOGI_MEM_AUX(&log_instance, data_ptr, data_sz, "format string",
+ * args, ...)
+ * - TRANSPORT_LOGW_MEM_AUX(&log_instance, data_ptr, data_sz, "format string",
+ * args, ...)
+ * - TRANSPORT_LOGE_MEM_AUX(&log_instance, data_ptr, data_sz, "format string",
+ * args, ...)
+ * - TRANSPORT_LOGF_MEM_AUX(&log_instance, data_ptr, data_sz, "format string",
+ * args, ...)
+ *
+ * Preformatted string logging macros:
+ * - TRANSPORT_LOGV_STR("preformatted string");
+ * - TRANSPORT_LOGD_STR("preformatted string");
+ * - TRANSPORT_LOGI_STR("preformatted string");
+ * - TRANSPORT_LOGW_STR("preformatted string");
+ * - TRANSPORT_LOGE_STR("preformatted string");
+ * - TRANSPORT_LOGF_STR("preformatted string");
+ *
+ * Explicit log level and tag macros:
+ * - TRANSPORT_LOG_WRITE(level, tag, "format string", args, ...)
+ * - TRANSPORT_LOG_WRITE_MEM(level, tag, data_ptr, data_sz, "format string",
+ * args, ...)
+ * - TRANSPORT_LOG_WRITE_AUX(&log_instance, level, tag, "format string", args,
+ * ...)
+ * - TRANSPORT_LOG_WRITE_MEM_AUX(&log_instance, level, tag, data_ptr, data_sz,
+ * "format string", args, ...)
+ *
+ * Format string follows printf() conventions. Both data_ptr and data_sz could
+ * be 0. Tag can be 0 as well. Most compilers will verify that type of arguments
+ * match format specifiers in format string.
+ *
+ * Library assuming UTF-8 encoding for all strings (char *), including format
+ * string itself.
+ */
+#if TRANSPORT_LOG_SRCLOC_NONE == _TRANSPORT_LOG_SRCLOC
+#define TRANSPORT_LOG_WRITE(lvl, tag, ...) \
+ do { \
+ if (TRANSPORT_LOG_ON(lvl)) _transport_log_write(lvl, tag, __VA_ARGS__); \
+ } \
+ _TRANSPORT_LOG_ONCE
+#define TRANSPORT_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \
+ do { \
+ if (TRANSPORT_LOG_ON(lvl)) \
+ _transport_log_write_mem(lvl, tag, d, d_sz, __VA_ARGS__); \
+ } \
+ _TRANSPORT_LOG_ONCE
+#define TRANSPORT_LOG_WRITE_AUX(log, lvl, tag, ...) \
+ do { \
+ if (TRANSPORT_LOG_ON(lvl)) \
+ _transport_log_write_aux(log, lvl, tag, __VA_ARGS__); \
+ } \
+ _TRANSPORT_LOG_ONCE
+#define TRANSPORT_LOG_WRITE_MEM_AUX(log, lvl, tag, d, d_sz, ...) \
+ do { \
+ if (TRANSPORT_LOG_ON(lvl)) \
+ _transport_log_write_mem_aux(log, lvl, tag, d, d_sz, __VA_ARGS__); \
+ } \
+ _TRANSPORT_LOG_ONCE
+#else
+#define TRANSPORT_LOG_WRITE(lvl, tag, ...) \
+ do { \
+ if (TRANSPORT_LOG_ON(lvl)) \
+ _transport_log_write_d(_TRANSPORT_LOG_SRCLOC_FUNCTION, __FILE__, \
+ __LINE__, lvl, tag, __VA_ARGS__); \
+ } \
+ _TRANSPORT_LOG_ONCE
+#define TRANSPORT_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \
+ do { \
+ if (TRANSPORT_LOG_ON(lvl)) \
+ _transport_log_write_mem_d(_TRANSPORT_LOG_SRCLOC_FUNCTION, __FILE__, \
+ __LINE__, lvl, tag, d, d_sz, __VA_ARGS__); \
+ } \
+ _TRANSPORT_LOG_ONCE
+#define TRANSPORT_LOG_WRITE_AUX(log, lvl, tag, ...) \
+ do { \
+ if (TRANSPORT_LOG_ON(lvl)) \
+ _transport_log_write_aux_d(_TRANSPORT_LOG_SRCLOC_FUNCTION, __FILE__, \
+ __LINE__, log, lvl, tag, __VA_ARGS__); \
+ } \
+ _TRANSPORT_LOG_ONCE
+#define TRANSPORT_LOG_WRITE_MEM_AUX(log, lvl, tag, d, d_sz, ...) \
+ do { \
+ if (TRANSPORT_LOG_ON(lvl)) \
+ _transport_log_write_mem_aux_d(_TRANSPORT_LOG_SRCLOC_FUNCTION, __FILE__, \
+ __LINE__, log, lvl, tag, d, d_sz, \
+ __VA_ARGS__); \
+ } \
+ _TRANSPORT_LOG_ONCE
+#endif
+
+static _TRANSPORT_LOG_INLINE void _transport_log_unused(const int dummy, ...) {
+ (void)dummy;
+}
+
+#define _TRANSPORT_LOG_UNUSED(...) \
+ do { \
+ _TRANSPORT_LOG_NEVER _transport_log_unused(0, __VA_ARGS__); \
+ } \
+ _TRANSPORT_LOG_ONCE
+
+#if TRANSPORT_LOG_ENABLED_VERBOSE
+#define TRANSPORT_LOGV(...) \
+ TRANSPORT_LOG_WRITE(TRANSPORT_LOG_VERBOSE, _TRANSPORT_LOG_TAG, __VA_ARGS__)
+#define TRANSPORT_LOGV_AUX(log, ...) \
+ TRANSPORT_LOG_WRITE_AUX(log, TRANSPORT_LOG_VERBOSE, _TRANSPORT_LOG_TAG, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGV_MEM(d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM(TRANSPORT_LOG_VERBOSE, _TRANSPORT_LOG_TAG, d, d_sz, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGV_MEM_AUX(log, d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM(log, TRANSPORT_LOG_VERBOSE, _TRANSPORT_LOG_TAG, d, \
+ d_sz, __VA_ARGS__)
+#else
+#define TRANSPORT_LOGV(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGV_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGV_MEM(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGV_MEM_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#endif
+
+#if TRANSPORT_LOG_ENABLED_DEBUG
+#define TRANSPORT_LOGD(...) \
+ TRANSPORT_LOG_WRITE(TRANSPORT_LOG_DEBUG, _TRANSPORT_LOG_TAG, __VA_ARGS__)
+#define TRANSPORT_LOGD_AUX(log, ...) \
+ TRANSPORT_LOG_WRITE_AUX(log, TRANSPORT_LOG_DEBUG, _TRANSPORT_LOG_TAG, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGD_MEM(d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM(TRANSPORT_LOG_DEBUG, _TRANSPORT_LOG_TAG, d, d_sz, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGD_MEM_AUX(log, d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM_AUX(log, TRANSPORT_LOG_DEBUG, _TRANSPORT_LOG_TAG, d, \
+ d_sz, __VA_ARGS__)
+#else
+#define TRANSPORT_LOGD(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGD_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGD_MEM(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGD_MEM_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#endif
+
+#if TRANSPORT_LOG_ENABLED_INFO
+#define TRANSPORT_LOGI(...) \
+ TRANSPORT_LOG_WRITE(TRANSPORT_LOG_INFO, _TRANSPORT_LOG_TAG, __VA_ARGS__)
+#define TRANSPORT_LOGI_AUX(log, ...) \
+ TRANSPORT_LOG_WRITE_AUX(log, TRANSPORT_LOG_INFO, _TRANSPORT_LOG_TAG, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGI_MEM(d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM(TRANSPORT_LOG_INFO, _TRANSPORT_LOG_TAG, d, d_sz, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGI_MEM_AUX(log, d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM_AUX(log, TRANSPORT_LOG_INFO, _TRANSPORT_LOG_TAG, d, \
+ d_sz, __VA_ARGS__)
+#else
+#define TRANSPORT_LOGI(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGI_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGI_MEM(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGI_MEM_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#endif
+
+#if TRANSPORT_LOG_ENABLED_WARN
+#define TRANSPORT_LOGW(...) \
+ TRANSPORT_LOG_WRITE(TRANSPORT_LOG_WARN, _TRANSPORT_LOG_TAG, __VA_ARGS__)
+#define TRANSPORT_LOGW_AUX(log, ...) \
+ TRANSPORT_LOG_WRITE_AUX(log, TRANSPORT_LOG_WARN, _TRANSPORT_LOG_TAG, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGW_MEM(d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM(TRANSPORT_LOG_WARN, _TRANSPORT_LOG_TAG, d, d_sz, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGW_MEM_AUX(log, d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM_AUX(log, TRANSPORT_LOG_WARN, _TRANSPORT_LOG_TAG, d, \
+ d_sz, __VA_ARGS__)
+#else
+#define TRANSPORT_LOGW(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGW_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGW_MEM(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGW_MEM_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#endif
+
+#if TRANSPORT_LOG_ENABLED_ERROR
+#define TRANSPORT_LOGE(...) \
+ TRANSPORT_LOG_WRITE(TRANSPORT_LOG_ERROR, _TRANSPORT_LOG_TAG, __VA_ARGS__)
+#define TRANSPORT_LOGE_AUX(log, ...) \
+ TRANSPORT_LOG_WRITE_AUX(log, TRANSPORT_LOG_ERROR, _TRANSPORT_LOG_TAG, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGE_MEM(d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM(TRANSPORT_LOG_ERROR, _TRANSPORT_LOG_TAG, d, d_sz, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGE_MEM_AUX(log, d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM_AUX(log, TRANSPORT_LOG_ERROR, _TRANSPORT_LOG_TAG, d, \
+ d_sz, __VA_ARGS__)
+#else
+#define TRANSPORT_LOGE(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGE_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGE_MEM(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGE_MEM_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#endif
+
+#if TRANSPORT_LOG_ENABLED_FATAL
+#define TRANSPORT_LOGF(...) \
+ TRANSPORT_LOG_WRITE(TRANSPORT_LOG_FATAL, _TRANSPORT_LOG_TAG, __VA_ARGS__)
+#define TRANSPORT_LOGF_AUX(log, ...) \
+ TRANSPORT_LOG_WRITE_AUX(log, TRANSPORT_LOG_FATAL, _TRANSPORT_LOG_TAG, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGF_MEM(d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM(TRANSPORT_LOG_FATAL, _TRANSPORT_LOG_TAG, d, d_sz, \
+ __VA_ARGS__)
+#define TRANSPORT_LOGF_MEM_AUX(log, d, d_sz, ...) \
+ TRANSPORT_LOG_WRITE_MEM_AUX(log, TRANSPORT_LOG_FATAL, _TRANSPORT_LOG_TAG, d, \
+ d_sz, __VA_ARGS__)
+#else
+#define TRANSPORT_LOGF(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGF_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGF_MEM(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#define TRANSPORT_LOGF_MEM_AUX(...) _TRANSPORT_LOG_UNUSED(__VA_ARGS__)
+#endif
+
+#define TRANSPORT_LOGV_STR(s) TRANSPORT_LOGV("%s", (s))
+#define TRANSPORT_LOGD_STR(s) TRANSPORT_LOGD("%s", (s))
+#define TRANSPORT_LOGI_STR(s) TRANSPORT_LOGI("%s", (s))
+#define TRANSPORT_LOGW_STR(s) TRANSPORT_LOGW("%s", (s))
+#define TRANSPORT_LOGE_STR(s) TRANSPORT_LOGE("%s", (s))
+#define TRANSPORT_LOGF_STR(s) TRANSPORT_LOGF("%s", (s))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Output to standard error stream. Library uses it by default, though in few
+ * cases it could be necessary to specify it explicitly. For example, when
+ * transport_log library is compiled with TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT,
+ * application must define and initialize global output variable:
+ *
+ * TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT = {TRANSPORT_LOG_OUT_STDERR};
+ *
+ * Another example is when using custom output, stderr could be used as a
+ * fallback when custom output facility failed to initialize:
+ *
+ * transport_log_set_output_v(TRANSPORT_LOG_OUT_STDERR);
+ */
+enum { TRANSPORT_LOG_OUT_STDERR_MASK = TRANSPORT_LOG_PUT_STD };
+void transport_log_out_stderr_callback(const transport_log_message *const msg,
+ void *arg);
+#define TRANSPORT_LOG_OUT_STDERR \
+ TRANSPORT_LOG_OUT_STDERR_MASK, 0, transport_log_out_stderr_callback
+
+/* Predefined spec for stderr. Uses global format options
+ * (TRANSPORT_LOG_GLOBAL_FORMAT) and TRANSPORT_LOG_OUT_STDERR. Could be used to
+ * force output to stderr for a particular message. Example:
+ *
+ * f = fopen("foo.log", "w");
+ * if (!f)
+ * TRANSPORT_LOGE_AUX(TRANSPORT_LOG_STDERR, "Failed to open log file");
+ */
+#define TRANSPORT_LOG_STDERR (&_transport_log_stderr_spec)
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/membuf.h b/libtransport/includes/hicn/transport/utils/membuf.h
new file mode 100644
index 000000000..9fc37dd25
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/membuf.h
@@ -0,0 +1,921 @@
+/*
+ * Copyright 2013-present 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.
+ */
+
+/*
+ * The code in this file if adapated from the IOBuf of folly:
+ * https://github.com/facebook/folly/blob/master/folly/io/IOBuf.h
+ */
+
+#pragma once
+
+#include <hicn/transport/portability/portability.h>
+#include <hicn/transport/utils/branch_prediction.h>
+
+#include <atomic>
+#include <cassert>
+#include <cinttypes>
+#include <cstddef>
+#include <cstring>
+#include <iterator>
+#include <limits>
+#include <memory>
+#include <type_traits>
+#include <vector>
+
+#include <stdlib.h>
+
+#ifndef _WIN32
+TRANSPORT_GNU_DISABLE_WARNING("-Wshadow")
+#endif
+
+namespace utils {
+
+class MemBuf {
+ public:
+ enum CreateOp { CREATE };
+ enum WrapBufferOp { WRAP_BUFFER };
+ enum TakeOwnershipOp { TAKE_OWNERSHIP };
+ enum CopyBufferOp { COPY_BUFFER };
+
+ typedef void (*FreeFunction)(void* buf, void* userData);
+
+ static std::unique_ptr<MemBuf> create(std::size_t capacity);
+ MemBuf(CreateOp, std::size_t capacity);
+
+ /**
+ * Create a new MemBuf, using a single memory allocation to allocate space
+ * for both the MemBuf object and the data storage space.
+ *
+ * This saves one memory allocation. However, it can be wasteful if you
+ * later need to grow the buffer using reserve(). If the buffer needs to be
+ * reallocated, the space originally allocated will not be freed() until the
+ * MemBuf object itself is also freed. (It can also be slightly wasteful in
+ * some cases where you clone this MemBuf and then free the original MemBuf.)
+ */
+ static std::unique_ptr<MemBuf> createCombined(std::size_t capacity);
+
+ /**
+ * Create a new IOBuf, using separate memory allocations for the IOBuf object
+ * for the IOBuf and the data storage space.
+ *
+ * This requires two memory allocations, but saves space in the long run
+ * if you know that you will need to reallocate the data buffer later.
+ */
+ static std::unique_ptr<MemBuf> createSeparate(std::size_t capacity);
+
+ /**
+ * Allocate a new MemBuf chain with the requested total capacity, allocating
+ * no more than maxBufCapacity to each buffer.
+ */
+ static std::unique_ptr<MemBuf> createChain(size_t totalCapacity,
+ std::size_t maxBufCapacity);
+
+ static std::unique_ptr<MemBuf> takeOwnership(void* buf, std::size_t capacity,
+ FreeFunction freeFn = nullptr,
+ void* userData = nullptr,
+ bool freeOnError = true) {
+ return takeOwnership(buf, capacity, capacity, freeFn, userData,
+ freeOnError);
+ }
+
+ MemBuf(TakeOwnershipOp op, void* buf, std::size_t capacity,
+ FreeFunction freeFn = nullptr, void* userData = nullptr,
+ bool freeOnError = true)
+ : MemBuf(op, buf, capacity, capacity, freeFn, userData, freeOnError) {}
+
+ static std::unique_ptr<MemBuf> takeOwnership(void* buf, std::size_t capacity,
+ std::size_t length,
+ FreeFunction freeFn = nullptr,
+ void* userData = nullptr,
+ bool freeOnError = true);
+
+ MemBuf(TakeOwnershipOp, void* buf, std::size_t capacity, std::size_t length,
+ FreeFunction freeFn = nullptr, void* userData = nullptr,
+ bool freeOnError = true);
+
+ static std::unique_ptr<MemBuf> wrapBuffer(const void* buf,
+ std::size_t capacity);
+
+ static MemBuf wrapBufferAsValue(const void* buf,
+ std::size_t capacity) noexcept;
+
+ MemBuf(WrapBufferOp op, const void* buf, std::size_t capacity) noexcept;
+
+ /**
+ * Convenience function to create a new MemBuf object that copies data from a
+ * user-supplied buffer, optionally allocating a given amount of
+ * headroom and tailroom.
+ */
+ static std::unique_ptr<MemBuf> copyBuffer(const void* buf, std::size_t size,
+ std::size_t headroom = 0,
+ std::size_t minTailroom = 0);
+
+ MemBuf(CopyBufferOp op, const void* buf, std::size_t size,
+ std::size_t headroom = 0, std::size_t minTailroom = 0);
+
+ /**
+ * Convenience function to free a chain of MemBufs held by a unique_ptr.
+ */
+ static void destroy(std::unique_ptr<MemBuf>&& data) {
+ auto destroyer = std::move(data);
+ }
+
+ ~MemBuf();
+
+ bool empty() const;
+
+ const uint8_t* data() const { return data_; }
+
+ uint8_t* writableData() { return data_; }
+
+ const uint8_t* tail() const { return data_ + length_; }
+
+ uint8_t* writableTail() { return data_ + length_; }
+
+ std::size_t length() const { return length_; }
+
+ std::size_t headroom() const { return std::size_t(data_ - buffer()); }
+
+ std::size_t tailroom() const { return std::size_t(bufferEnd() - tail()); }
+
+ const uint8_t* buffer() const { return buf_; }
+
+ uint8_t* writableBuffer() { return buf_; }
+
+ const uint8_t* bufferEnd() const { return buf_ + capacity_; }
+
+ std::size_t capacity() const { return capacity_; }
+
+ MemBuf* next() { return next_; }
+
+ const MemBuf* next() const { return next_; }
+
+ MemBuf* prev() { return prev_; }
+
+ const MemBuf* prev() const { return prev_; }
+
+ /**
+ * Shift the data forwards in the buffer.
+ *
+ * This shifts the data pointer forwards in the buffer to increase the
+ * headroom. This is commonly used to increase the headroom in a newly
+ * allocated buffer.
+ *
+ * The caller is responsible for ensuring that there is sufficient
+ * tailroom in the buffer before calling advance().
+ *
+ * If there is a non-zero data length, advance() will use memmove() to shift
+ * the data forwards in the buffer. In this case, the caller is responsible
+ * for making sure the buffer is unshared, so it will not affect other MemBufs
+ * that may be sharing the same underlying buffer.
+ */
+ void advance(std::size_t amount) {
+ // In debug builds, assert if there is a problem.
+ assert(amount <= tailroom());
+
+ if (length_ > 0) {
+ memmove(data_ + amount, data_, length_);
+ }
+ data_ += amount;
+ }
+
+ /**
+ * Shift the data backwards in the buffer.
+ *
+ * The caller is responsible for ensuring that there is sufficient headroom
+ * in the buffer before calling retreat().
+ *
+ * If there is a non-zero data length, retreat() will use memmove() to shift
+ * the data backwards in the buffer. In this case, the caller is responsible
+ * for making sure the buffer is unshared, so it will not affect other MemBufs
+ * that may be sharing the same underlying buffer.
+ */
+ void retreat(std::size_t amount) {
+ // In debug builds, assert if there is a problem.
+ assert(amount <= headroom());
+
+ if (length_ > 0) {
+ memmove(data_ - amount, data_, length_);
+ }
+ data_ -= amount;
+ }
+
+ void prepend(std::size_t amount) {
+ data_ -= amount;
+ length_ += amount;
+ }
+
+ void append(std::size_t amount) { length_ += amount; }
+
+ void trimStart(std::size_t amount) {
+ data_ += amount;
+ length_ -= amount;
+ }
+
+ void trimEnd(std::size_t amount) { length_ -= amount; }
+
+ // Never call clear on cloned membuf sharing different
+ // portions of the same underlying buffer.
+ // Use the trim functions instead.
+ void clear() {
+ data_ = writableBuffer();
+ length_ = 0;
+ }
+
+ void reserve(std::size_t minHeadroom, std::size_t minTailroom) {
+ // Maybe we don't need to do anything.
+ if (headroom() >= minHeadroom && tailroom() >= minTailroom) {
+ return;
+ }
+ // If the buffer is empty but we have enough total room (head + tail),
+ // move the data_ pointer around.
+ if (length() == 0 && headroom() + tailroom() >= minHeadroom + minTailroom) {
+ data_ = writableBuffer() + minHeadroom;
+ return;
+ }
+ // Bah, we have to do actual work.
+ reserveSlow(minHeadroom, minTailroom);
+ }
+
+ bool isChained() const {
+ assert((next_ == this) == (prev_ == this));
+ return next_ != this;
+ }
+
+ size_t countChainElements() const;
+
+ std::size_t computeChainDataLength() const;
+
+ void prependChain(std::unique_ptr<MemBuf>&& iobuf);
+
+ void appendChain(std::unique_ptr<MemBuf>&& iobuf) {
+ // Just use prependChain() on the next element in our chain
+ next_->prependChain(std::move(iobuf));
+ }
+
+ std::unique_ptr<MemBuf> unlink() {
+ next_->prev_ = prev_;
+ prev_->next_ = next_;
+ prev_ = this;
+ next_ = this;
+ return std::unique_ptr<MemBuf>(this);
+ }
+
+ /**
+ * Remove this MemBuf from its current chain and return a unique_ptr to
+ * the MemBuf that formerly followed it in the chain.
+ */
+ std::unique_ptr<MemBuf> pop() {
+ MemBuf* next = next_;
+ next_->prev_ = prev_;
+ prev_->next_ = next_;
+ prev_ = this;
+ next_ = this;
+ return std::unique_ptr<MemBuf>((next == this) ? nullptr : next);
+ }
+
+ /**
+ * Remove a subchain from this chain.
+ *
+ * Remove the subchain starting at head and ending at tail from this chain.
+ *
+ * Returns a unique_ptr pointing to head. (In other words, ownership of the
+ * head of the subchain is transferred to the caller.) If the caller ignores
+ * the return value and lets the unique_ptr be destroyed, the subchain will
+ * be immediately destroyed.
+ *
+ * The subchain referenced by the specified head and tail must be part of the
+ * same chain as the current MemBuf, but must not contain the current MemBuf.
+ * However, the specified head and tail may be equal to each other (i.e.,
+ * they may be a subchain of length 1).
+ */
+ std::unique_ptr<MemBuf> separateChain(MemBuf* head, MemBuf* tail) {
+ assert(head != this);
+ assert(tail != this);
+
+ head->prev_->next_ = tail->next_;
+ tail->next_->prev_ = head->prev_;
+
+ head->prev_ = tail;
+ tail->next_ = head;
+
+ return std::unique_ptr<MemBuf>(head);
+ }
+
+ /**
+ * Return true if at least one of the MemBufs in this chain are shared,
+ * or false if all of the MemBufs point to unique buffers.
+ *
+ * Use isSharedOne() to only check this MemBuf rather than the entire chain.
+ */
+ bool isShared() const {
+ const MemBuf* current = this;
+ while (true) {
+ if (current->isSharedOne()) {
+ return true;
+ }
+ current = current->next_;
+ if (current == this) {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Return true if all MemBufs in this chain are managed by the usual
+ * refcounting mechanism (and so the lifetime of the underlying memory
+ * can be extended by clone()).
+ */
+ bool isManaged() const {
+ const MemBuf* current = this;
+ while (true) {
+ if (!current->isManagedOne()) {
+ return false;
+ }
+ current = current->next_;
+ if (current == this) {
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Return true if this MemBuf is managed by the usual refcounting mechanism
+ * (and so the lifetime of the underlying memory can be extended by
+ * cloneOne()).
+ */
+ bool isManagedOne() const { return sharedInfo(); }
+
+ /**
+ * Return true if other MemBufs are also pointing to the buffer used by this
+ * MemBuf, and false otherwise.
+ *
+ * If this MemBuf points at a buffer owned by another (non-MemBuf) part of the
+ * code (i.e., if the MemBuf was created using wrapBuffer(), or was cloned
+ * from such an MemBuf), it is always considered shared.
+ *
+ * This only checks the current MemBuf, and not other MemBufs in the chain.
+ */
+ bool isSharedOne() const {
+ // If this is a user-owned buffer, it is always considered shared
+ if ((TRANSPORT_EXPECT_FALSE(!sharedInfo()))) {
+ return true;
+ }
+
+ if ((TRANSPORT_EXPECT_FALSE(sharedInfo()->externallyShared))) {
+ return true;
+ }
+
+ if ((TRANSPORT_EXPECT_TRUE(!(flags() & flag_maybe_shared)))) {
+ return false;
+ }
+
+ // flag_maybe_shared is set, so we need to check the reference count.
+ // (Checking the reference count requires an atomic operation, which is why
+ // we prefer to only check flag_maybe_shared if possible.)
+ bool shared = sharedInfo()->refcount.load(std::memory_order_acquire) > 1;
+ if (!shared) {
+ // we're the last one left
+ clearFlags(flag_maybe_shared);
+ }
+ return shared;
+ }
+
+ /**
+ * Ensure that this MemBuf has a unique buffer that is not shared by other
+ * MemBufs.
+ *
+ * unshare() operates on an entire chain of MemBuf objects. If the chain is
+ * shared, it may also coalesce the chain when making it unique. If the
+ * chain is coalesced, subsequent MemBuf objects in the current chain will be
+ * automatically deleted.
+ *
+ * Note that buffers owned by other (non-MemBuf) users are automatically
+ * considered shared.
+ *
+ * Throws std::bad_alloc on error. On error the MemBuf chain will be
+ * unmodified.
+ *
+ * Currently unshare may also throw std::overflow_error if it tries to
+ * coalesce. (TODO: In the future it would be nice if unshare() were smart
+ * enough not to coalesce the entire buffer if the data is too large.
+ * However, in practice this seems unlikely to become an issue.)
+ */
+ void unshare() {
+ if (isChained()) {
+ unshareChained();
+ } else {
+ unshareOne();
+ }
+ }
+
+ /**
+ * Ensure that this MemBuf has a unique buffer that is not shared by other
+ * MemBufs.
+ *
+ * unshareOne() operates on a single MemBuf object. This MemBuf will have a
+ * unique buffer after unshareOne() returns, but other MemBufs in the chain
+ * may still be shared after unshareOne() returns.
+ *
+ * Throws std::bad_alloc on error. On error the MemBuf will be unmodified.
+ */
+ void unshareOne() {
+ if (isSharedOne()) {
+ unshareOneSlow();
+ }
+ }
+
+ /**
+ * Mark the underlying buffers in this chain as shared with external memory
+ * management mechanism. This will make isShared() always returns true.
+ *
+ * This function is not thread-safe, and only safe to call immediately after
+ * creating an MemBuf, before it has been shared with other threads.
+ */
+ void markExternallyShared();
+
+ /**
+ * Mark the underlying buffer that this MemBuf refers to as shared with
+ * external memory management mechanism. This will make isSharedOne() always
+ * returns true.
+ *
+ * This function is not thread-safe, and only safe to call immediately after
+ * creating an MemBuf, before it has been shared with other threads.
+ */
+ void markExternallySharedOne() {
+ SharedInfo* info = sharedInfo();
+ if (info) {
+ info->externallyShared = true;
+ }
+ }
+
+ /**
+ * Ensure that the memory that MemBufs in this chain refer to will continue to
+ * be allocated for as long as the MemBufs of the chain (or any clone()s
+ * created from this point onwards) is alive.
+ *
+ * This only has an effect for user-owned buffers (created with the
+ * WRAP_BUFFER constructor or wrapBuffer factory function), in which case
+ * those buffers are unshared.
+ */
+ void makeManaged() {
+ if (isChained()) {
+ makeManagedChained();
+ } else {
+ makeManagedOne();
+ }
+ }
+
+ /**
+ * Ensure that the memory that this MemBuf refers to will continue to be
+ * allocated for as long as this MemBuf (or any clone()s created from this
+ * point onwards) is alive.
+ *
+ * This only has an effect for user-owned buffers (created with the
+ * WRAP_BUFFER constructor or wrapBuffer factory function), in which case
+ * those buffers are unshared.
+ */
+ void makeManagedOne() {
+ if (!isManagedOne()) {
+ // We can call the internal function directly; unmanaged implies shared.
+ unshareOneSlow();
+ }
+ }
+
+ // /**
+ // * Coalesce this MemBuf chain into a single buffer.
+ // *
+ // * This method moves all of the data in this MemBuf chain into a single
+ // * contiguous buffer, if it is not already in one buffer. After coalesce()
+ // * returns, this MemBuf will be a chain of length one. Other MemBufs in
+ // the
+ // * chain will be automatically deleted.
+ // *
+ // * After coalescing, the MemBuf will have at least as much headroom as the
+ // * first MemBuf in the chain, and at least as much tailroom as the last
+ // MemBuf
+ // * in the chain.
+ // *
+ // * Throws std::bad_alloc on error. On error the MemBuf chain will be
+ // * unmodified.
+ // *
+ // * Returns ByteRange that points to the data MemBuf stores.
+ // */
+ // ByteRange coalesce() {
+ // const std::size_t newHeadroom = headroom();
+ // const std::size_t newTailroom = prev()->tailroom();
+ // return coalesceWithHeadroomTailroom(newHeadroom, newTailroom);
+ // }
+
+ // /**
+ // * This is similar to the coalesce() method, except this allows to set a
+ // * headroom and tailroom after coalescing.
+ // *
+ // * Returns ByteRange that points to the data MemBuf stores.
+ // */
+ // ByteRange coalesceWithHeadroomTailroom(std::size_t newHeadroom,
+ // std::size_t newTailroom) {
+ // if (isChained()) {
+ // coalesceAndReallocate(newHeadroom, computeChainDataLength(), this,
+ // newTailroom);
+ // }
+ // return ByteRange(data_, length_);
+ // }
+
+ /**
+ * Ensure that this chain has at least maxLength bytes available as a
+ * contiguous memory range.
+ *
+ * This method coalesces whole buffers in the chain into this buffer as
+ * necessary until this buffer's length() is at least maxLength.
+ *
+ * After coalescing, the MemBuf will have at least as much headroom as the
+ * first MemBuf in the chain, and at least as much tailroom as the last MemBuf
+ * that was coalesced.
+ *
+ * Throws std::bad_alloc or std::overflow_error on error. On error the MemBuf
+ * chain will be unmodified. Throws std::overflow_error if maxLength is
+ * longer than the total chain length.
+ *
+ * Upon return, either enough of the chain was coalesced into a contiguous
+ * region, or the entire chain was coalesced. That is,
+ * length() >= maxLength || !isChained() is true.
+ */
+ void gather(std::size_t maxLength) {
+ if (!isChained() || length_ >= maxLength) {
+ return;
+ }
+ coalesceSlow(maxLength);
+ }
+
+ /**
+ * Return a new MemBuf chain sharing the same data as this chain.
+ *
+ * The new MemBuf chain will normally point to the same underlying data
+ * buffers as the original chain. (The one exception to this is if some of
+ * the MemBufs in this chain contain small internal data buffers which cannot
+ * be shared.)
+ */
+ std::unique_ptr<MemBuf> clone() const;
+
+ /**
+ * Similar to clone(). But returns MemBuf by value rather than heap-allocating
+ * it.
+ */
+ MemBuf cloneAsValue() const;
+
+ /**
+ * Return a new MemBuf with the same data as this MemBuf.
+ *
+ * The new MemBuf returned will not be part of a chain (even if this MemBuf is
+ * part of a larger chain).
+ */
+ std::unique_ptr<MemBuf> cloneOne() const;
+
+ /**
+ * Similar to cloneOne(). But returns MemBuf by value rather than
+ * heap-allocating it.
+ */
+ MemBuf cloneOneAsValue() const;
+
+ /**
+ * Return a new unchained MemBuf that may share the same data as this chain.
+ *
+ * If the MemBuf chain is not chained then the new MemBuf will point to the
+ * same underlying data buffer as the original chain. Otherwise, it will clone
+ * and coalesce the MemBuf chain.
+ *
+ * The new MemBuf will have at least as much headroom as the first MemBuf in
+ * the chain, and at least as much tailroom as the last MemBuf in the chain.
+ *
+ * Throws std::bad_alloc on error.
+ */
+ std::unique_ptr<MemBuf> cloneCoalesced() const;
+
+ /**
+ * This is similar to the cloneCoalesced() method, except this allows to set a
+ * headroom and tailroom for the new MemBuf.
+ */
+ std::unique_ptr<MemBuf> cloneCoalescedWithHeadroomTailroom(
+ std::size_t newHeadroom, std::size_t newTailroom) const;
+
+ /**
+ * Similar to cloneCoalesced(). But returns MemBuf by value rather than
+ * heap-allocating it.
+ */
+ MemBuf cloneCoalescedAsValue() const;
+
+ /**
+ * This is similar to the cloneCoalescedAsValue() method, except this allows
+ * to set a headroom and tailroom for the new MemBuf.
+ */
+ MemBuf cloneCoalescedAsValueWithHeadroomTailroom(
+ std::size_t newHeadroom, std::size_t newTailroom) const;
+
+ /**
+ * Similar to Clone(). But use other as the head node. Other nodes in the
+ * chain (if any) will be allocted on heap.
+ */
+ void cloneInto(MemBuf& other) const { other = cloneAsValue(); }
+
+ /**
+ * Similar to CloneOne(). But to fill an existing MemBuf instead of a new
+ * MemBuf.
+ */
+ void cloneOneInto(MemBuf& other) const { other = cloneOneAsValue(); }
+
+ /**
+ * Return an iovector suitable for e.g. writev()
+ *
+ * auto iov = buf->getIov();
+ * auto xfer = writev(fd, iov.data(), iov.size());
+ *
+ * Naturally, the returned iovector is invalid if you modify the buffer
+ * chain.
+ */
+ std::vector<struct iovec> getIov() const;
+
+ /**
+ * Update an existing iovec array with the MemBuf data.
+ *
+ * New iovecs will be appended to the existing vector; anything already
+ * present in the vector will be left unchanged.
+ *
+ * Naturally, the returned iovec data will be invalid if you modify the
+ * buffer chain.
+ */
+ void appendToIov(std::vector<struct iovec>* iov) const;
+
+ /**
+ * Fill an iovec array with the MemBuf data.
+ *
+ * Returns the number of iovec filled. If there are more buffer than
+ * iovec, returns 0. This version is suitable to use with stack iovec
+ * arrays.
+ *
+ * Naturally, the filled iovec data will be invalid if you modify the
+ * buffer chain.
+ */
+ size_t fillIov(struct iovec* iov, size_t len) const;
+
+ /**
+ * A helper that wraps a number of iovecs into an MemBuf chain. If count ==
+ * 0, then a zero length buf is returned. This function never returns
+ * nullptr.
+ */
+ static std::unique_ptr<MemBuf> wrapIov(const iovec* vec, size_t count);
+
+ /**
+ * A helper that takes ownerships a number of iovecs into an MemBuf chain. If
+ * count == 0, then a zero length buf is returned. This function never
+ * returns nullptr.
+ */
+ static std::unique_ptr<MemBuf> takeOwnershipIov(const iovec* vec,
+ size_t count,
+ FreeFunction freeFn = nullptr,
+ void* userData = nullptr,
+ bool freeOnError = true);
+
+ /*
+ * Overridden operator new and delete.
+ * These perform specialized memory management to help support
+ * createCombined(), which allocates MemBuf objects together with the buffer
+ * data.
+ */
+ void* operator new(size_t size);
+ void* operator new(size_t size, void* ptr);
+ void operator delete(void* ptr);
+ void operator delete(void* ptr, void* placement);
+
+ // /**
+ // * Iteration support: a chain of MemBufs may be iterated through using
+ // * STL-style iterators over const ByteRanges. Iterators are only
+ // invalidated
+ // * if the MemBuf that they currently point to is removed.
+ // */
+ // Iterator cbegin() const;
+ // Iterator cend() const;
+ // Iterator begin() const;
+ // Iterator end() const;
+
+ /**
+ * Allocate a new null buffer.
+ *
+ * This can be used to allocate an empty MemBuf on the stack. It will have no
+ * space allocated for it. This is generally useful only to later use move
+ * assignment to fill out the MemBuf.
+ */
+ MemBuf() noexcept;
+
+ /**
+ * Move constructor and assignment operator.
+ *
+ * In general, you should only ever move the head of an MemBuf chain.
+ * Internal nodes in an MemBuf chain are owned by the head of the chain, and
+ * should not be moved from. (Technically, nothing prevents you from moving
+ * a non-head node, but the moved-to node will replace the moved-from node in
+ * the chain. This has implications for ownership, since non-head nodes are
+ * owned by the chain head. You are then responsible for relinquishing
+ * ownership of the moved-to node, and manually deleting the moved-from
+ * node.)
+ *
+ * With the move assignment operator, the destination of the move should be
+ * the head of an MemBuf chain or a solitary MemBuf not part of a chain. If
+ * the move destination is part of a chain, all other MemBufs in the chain
+ * will be deleted.
+ */
+ MemBuf(MemBuf&& other) noexcept;
+ MemBuf& operator=(MemBuf&& other) noexcept;
+
+ MemBuf(const MemBuf& other);
+ MemBuf& operator=(const MemBuf& other);
+
+ private:
+ enum FlagsEnum : uintptr_t {
+ // Adding any more flags would not work on 32-bit architectures,
+ // as these flags are stashed in the least significant 2 bits of a
+ // max-align-aligned pointer.
+ flag_free_shared_info = 0x1,
+ flag_maybe_shared = 0x2,
+ flag_mask = flag_free_shared_info | flag_maybe_shared
+ };
+
+ struct SharedInfo {
+ SharedInfo();
+ SharedInfo(FreeFunction fn, void* arg);
+
+ // A pointer to a function to call to free the buffer when the refcount
+ // hits 0. If this is null, free() will be used instead.
+ FreeFunction freeFn;
+ void* userData;
+ std::atomic<uint32_t> refcount;
+ bool externallyShared{false};
+ };
+ // Helper structs for use by operator new and delete
+ struct HeapPrefix;
+ struct HeapStorage;
+ struct HeapFullStorage;
+
+ /**
+ * Create a new MemBuf pointing to an external buffer.
+ *
+ * The caller is responsible for holding a reference count for this new
+ * MemBuf. The MemBuf constructor does not automatically increment the
+ * reference count.
+ */
+ struct InternalConstructor {}; // avoid conflicts
+ MemBuf(InternalConstructor, uintptr_t flagsAndSharedInfo, uint8_t* buf,
+ std::size_t capacity, uint8_t* data, std::size_t length) noexcept;
+
+ void unshareOneSlow();
+ void unshareChained();
+ void makeManagedChained();
+ void coalesceSlow();
+ void coalesceSlow(size_t maxLength);
+ // newLength must be the entire length of the buffers between this and
+ // end (no truncation)
+ void coalesceAndReallocate(size_t newHeadroom, size_t newLength, MemBuf* end,
+ size_t newTailroom);
+ void coalesceAndReallocate(size_t newLength, MemBuf* end) {
+ coalesceAndReallocate(headroom(), newLength, end, end->prev_->tailroom());
+ }
+ void decrementRefcount();
+ void reserveSlow(std::size_t minHeadroom, std::size_t minTailroom);
+ void freeExtBuffer();
+
+ static size_t goodExtBufferSize(std::size_t minCapacity);
+ static void initExtBuffer(uint8_t* buf, size_t mallocSize,
+ SharedInfo** infoReturn,
+ std::size_t* capacityReturn);
+ static void allocExtBuffer(std::size_t minCapacity, uint8_t** bufReturn,
+ SharedInfo** infoReturn,
+ std::size_t* capacityReturn);
+ static void releaseStorage(HeapStorage* storage, uint16_t freeFlags);
+ static void freeInternalBuf(void* buf, void* userData);
+
+ /*
+ * Member variables
+ */
+
+ /*
+ * Links to the next and the previous MemBuf in this chain.
+ *
+ * The chain is circularly linked (the last element in the chain points back
+ * at the head), and next_ and prev_ can never be null. If this MemBuf is the
+ * only element in the chain, next_ and prev_ will both point to this.
+ */
+ MemBuf* next_{this};
+ MemBuf* prev_{this};
+
+ /*
+ * A pointer to the start of the data referenced by this MemBuf, and the
+ * length of the data.
+ *
+ * This may refer to any subsection of the actual buffer capacity.
+ */
+ uint8_t* data_{nullptr};
+ uint8_t* buf_{nullptr};
+ std::size_t length_{0};
+ std::size_t capacity_{0};
+
+ // Pack flags in least significant 2 bits, sharedInfo in the rest
+ mutable uintptr_t flags_and_shared_info_{0};
+
+ static inline uintptr_t packFlagsAndSharedInfo(uintptr_t flags,
+ SharedInfo* info) {
+ uintptr_t uinfo = reinterpret_cast<uintptr_t>(info);
+ return flags | uinfo;
+ }
+
+ inline SharedInfo* sharedInfo() const {
+ return reinterpret_cast<SharedInfo*>(flags_and_shared_info_ & ~flag_mask);
+ }
+
+ inline void setSharedInfo(SharedInfo* info) {
+ uintptr_t uinfo = reinterpret_cast<uintptr_t>(info);
+ flags_and_shared_info_ = (flags_and_shared_info_ & flag_mask) | uinfo;
+ }
+
+ inline uintptr_t flags() const { return flags_and_shared_info_ & flag_mask; }
+
+ // flags_ are changed from const methods
+ inline void setFlags(uintptr_t flags) const {
+ flags_and_shared_info_ |= flags;
+ }
+
+ inline void clearFlags(uintptr_t flags) const {
+ flags_and_shared_info_ &= ~flags;
+ }
+
+ inline void setFlagsAndSharedInfo(uintptr_t flags, SharedInfo* info) {
+ flags_and_shared_info_ = packFlagsAndSharedInfo(flags, info);
+ }
+
+ struct DeleterBase {
+ virtual ~DeleterBase() {}
+ virtual void dispose(void* p) = 0;
+ };
+
+ template <class UniquePtr>
+ struct UniquePtrDeleter : public DeleterBase {
+ typedef typename UniquePtr::pointer Pointer;
+ typedef typename UniquePtr::deleter_type Deleter;
+
+ explicit UniquePtrDeleter(Deleter deleter) : deleter_(std::move(deleter)) {}
+ void dispose(void* p) override {
+ try {
+ deleter_(static_cast<Pointer>(p));
+ delete this;
+ } catch (...) {
+ abort();
+ }
+ }
+
+ private:
+ Deleter deleter_;
+ };
+
+ static void freeUniquePtrBuffer(void* ptr, void* userData) {
+ static_cast<DeleterBase*>(userData)->dispose(ptr);
+ }
+};
+
+// template <class UniquePtr>
+// typename std::enable_if<
+// detail::IsUniquePtrToSL<UniquePtr>::value,
+// std::unique_ptr<MemBuf>>::type
+// MemBuf::takeOwnership(UniquePtr&& buf, size_t count) {
+// size_t size = count * sizeof(typename UniquePtr::element_type);
+// auto deleter = new UniquePtrDeleter<UniquePtr>(buf.get_deleter());
+// return takeOwnership(
+// buf.release(), size, &MemBuf::freeUniquePtrBuffer, deleter);
+// }
+
+inline std::unique_ptr<MemBuf> MemBuf::copyBuffer(const void* data,
+ std::size_t size,
+ std::size_t headroom,
+ std::size_t minTailroom) {
+ std::size_t capacity = headroom + size + minTailroom;
+ std::unique_ptr<MemBuf> buf = MemBuf::create(capacity);
+ buf->advance(headroom);
+ if (size != 0) {
+ memcpy(buf->writableData(), data, size);
+ }
+ buf->append(size);
+ return buf;
+}
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/object_pool.h b/libtransport/includes/hicn/transport/utils/object_pool.h
new file mode 100644
index 000000000..f78bd2aa2
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/object_pool.h
@@ -0,0 +1,90 @@
+/*
+ * 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
+
+// TODO
+#include <hicn/transport/utils/branch_prediction.h>
+#include <hicn/transport/utils/spinlock.h>
+
+#include <deque>
+#include <memory>
+#include <mutex>
+
+namespace utils {
+
+template <typename T>
+class ObjectPool {
+ class ObjectDeleter {
+ public:
+ ObjectDeleter(ObjectPool<T> *pool = nullptr) : pool_(pool) {}
+
+ void operator()(T *t) {
+ if (pool_) {
+ pool_->add(t);
+ } else {
+ delete t;
+ }
+ }
+
+ private:
+ ObjectPool<T> *pool_;
+ };
+
+ public:
+ using Ptr = std::unique_ptr<T, ObjectDeleter>;
+
+ ObjectPool() : destructor_(false) {}
+
+ ~ObjectPool() {
+ destructor_ = true;
+ for (auto &ptr : object_pool_) {
+ ptr.reset();
+ }
+ }
+
+ std::pair<bool, Ptr> get() {
+ if (object_pool_.empty()) {
+ return std::make_pair<bool, Ptr>(false, makePtr(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));
+ }
+
+ void add(T *object) {
+ utils::SpinLock::Acquire locked(object_pool_lock_);
+
+ if (TRANSPORT_EXPECT_TRUE(!destructor_)) {
+ object_pool_.emplace_back(makePtr(object));
+ } else {
+ delete object;
+ }
+ }
+
+ 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_;
+};
+
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/ring_buffer.h b/libtransport/includes/hicn/transport/utils/ring_buffer.h
new file mode 100644
index 000000000..9babe56bd
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/ring_buffer.h
@@ -0,0 +1,129 @@
+/*
+ * 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 <atomic>
+#include <cstddef>
+
+namespace utils {
+
+/**
+ * NOTE: Single consumer single producer ring buffer
+ */
+template <typename Element, std::size_t Size>
+class CircularFifo {
+ public:
+ enum { Capacity = Size + 1 };
+
+ CircularFifo() : tail_(0), head_(0), size_(0) {}
+ virtual ~CircularFifo() {}
+
+ bool push(const Element& item);
+ bool push(Element&& item);
+ bool pop(Element& item);
+
+ bool wasEmpty() const;
+ bool wasFull() const;
+ bool isLockFree() const;
+ std::size_t size() const;
+
+ private:
+ std::size_t increment(std::size_t idx) const;
+ std::atomic<std::size_t> tail_; // tail(input) index
+ Element array_[Capacity];
+ std::atomic<std::size_t> head_; // head(output) index
+ std::atomic<std::size_t> size_;
+};
+
+template <typename Element, std::size_t Size>
+bool CircularFifo<Element, Size>::push(const Element& item) {
+ const auto current_tail = tail_.load(std::memory_order_relaxed);
+ const auto next_tail = increment(current_tail);
+ if (next_tail != head_.load(std::memory_order_acquire)) {
+ array_[current_tail] = item;
+ tail_.store(next_tail, std::memory_order_release);
+ size_++;
+ return true;
+ }
+
+ // full queue
+ return false;
+}
+
+/**
+ * Push by move
+ */
+template <typename Element, std::size_t Size>
+bool CircularFifo<Element, Size>::push(Element&& item) {
+ const auto current_tail = tail_.load(std::memory_order_relaxed);
+ const auto next_tail = increment(current_tail);
+ if (next_tail != head_.load(std::memory_order_acquire)) {
+ array_[current_tail] = std::move(item);
+ tail_.store(next_tail, std::memory_order_release);
+ size_++;
+ return true;
+ }
+
+ // full queue
+ return false;
+}
+
+// Pop by Consumer can only update the head
+// (load with relaxed, store with release)
+// the tail must be accessed with at least acquire
+template <typename Element, std::size_t Size>
+bool CircularFifo<Element, Size>::pop(Element& item) {
+ const size_t current_head = head_.load(std::memory_order_relaxed);
+ if (current_head == tail_.load(std::memory_order_acquire)) {
+ return false; // empty queue
+ }
+
+ item = std::move(array_[current_head]);
+ head_.store(increment(current_head), std::memory_order_release);
+ size_--;
+ return true;
+}
+
+template <typename Element, std::size_t Size>
+bool CircularFifo<Element, Size>::wasEmpty() const {
+ // snapshot with acceptance of that this comparison operation is not atomic
+ return (head_.load() == tail_.load());
+}
+
+// snapshot with acceptance that this comparison is not atomic
+template <typename Element, std::size_t Size>
+bool CircularFifo<Element, Size>::wasFull() const {
+ const auto next_tail =
+ increment(tail_.load()); // acquire, we dont know who call
+ return (next_tail == head_.load());
+}
+
+template <typename Element, std::size_t Size>
+bool CircularFifo<Element, Size>::isLockFree() const {
+ return (tail_.is_lock_free() && head_.is_lock_free());
+}
+
+template <typename Element, std::size_t Size>
+std::size_t CircularFifo<Element, Size>::increment(std::size_t idx) const {
+ return (idx + 1) % Capacity;
+}
+
+template <typename Element, std::size_t Size>
+std::size_t CircularFifo<Element, Size>::size() const {
+ return size_.load(std::memory_order_relaxed);
+}
+
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/spinlock.h b/libtransport/includes/hicn/transport/utils/spinlock.h
new file mode 100644
index 000000000..009a94454
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/spinlock.h
@@ -0,0 +1,53 @@
+/*
+ * 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 <atomic>
+
+namespace utils {
+
+class SpinLock : private std::atomic_flag {
+ public:
+ class Acquire {
+ public:
+ Acquire(SpinLock& spin_lock) : spin_lock_(spin_lock) { spin_lock_.lock(); }
+
+ ~Acquire() { spin_lock_.unlock(); }
+
+ // No copies
+ Acquire& operator=(const Acquire&) = delete;
+ Acquire(const Acquire&) = delete;
+
+ private:
+ SpinLock& spin_lock_;
+ };
+
+ SpinLock() { clear(); }
+
+ void lock() {
+ // busy-wait
+ while (std::atomic_flag::test_and_set(std::memory_order_acquire))
+ ;
+ }
+
+ void unlock() { clear(std::memory_order_release); }
+
+ bool tryLock() {
+ return std::atomic_flag::test_and_set(std::memory_order_acquire);
+ }
+};
+
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/includes/hicn/transport/utils/string_tokenizer.h b/libtransport/includes/hicn/transport/utils/string_tokenizer.h
new file mode 100644
index 000000000..36630eb58
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/string_tokenizer.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
+
+#include <string>
+
+namespace utils {
+
+class StringTokenizer {
+ public:
+ StringTokenizer(const std::string &str);
+ StringTokenizer(const std::string &str, const std::string &delim);
+
+ bool hasMoreTokens();
+ std::string nextToken();
+
+ private:
+ std::string str_;
+ std::string delimiter_;
+};
+
+} // namespace utils
diff --git a/libtransport/includes/hicn/transport/utils/uri.h b/libtransport/includes/hicn/transport/utils/uri.h
new file mode 100644
index 000000000..7c28e8552
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/uri.h
@@ -0,0 +1,47 @@
+/*
+ * 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 <algorithm> // find
+#include <string>
+
+namespace utils {
+
+class Uri {
+ typedef std::string::const_iterator iterator_t;
+
+ public:
+ Uri();
+
+ Uri &parse(const std::string &uri);
+
+ Uri &parseProtocolAndLocator(const std::string &locator);
+
+ std::string getQueryString();
+
+ std::string getPath();
+
+ std::string getProtocol();
+
+ std::string getLocator();
+
+ std::string getPort();
+
+ private:
+ std::string query_string_, path_, protocol_, locator_, port_;
+}; // uri
+
+} // namespace utils