diff options
Diffstat (limited to 'libtransport/src/hicn/transport/utils')
44 files changed, 0 insertions, 7542 deletions
diff --git a/libtransport/src/hicn/transport/utils/CMakeLists.txt b/libtransport/src/hicn/transport/utils/CMakeLists.txt deleted file mode 100644 index 5a7dbe9cc..000000000 --- a/libtransport/src/hicn/transport/utils/CMakeLists.txt +++ /dev/null @@ -1,82 +0,0 @@ -# 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 SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/string_tokenizer.cc - ${CMAKE_CURRENT_SOURCE_DIR}/uri.cc - ${CMAKE_CURRENT_SOURCE_DIR}/signer.cc - ${CMAKE_CURRENT_SOURCE_DIR}/verifier.cc - ${CMAKE_CURRENT_SOURCE_DIR}/identity.cc - ${CMAKE_CURRENT_SOURCE_DIR}/log.cc - ${CMAKE_CURRENT_SOURCE_DIR}/membuf.cc - ${CMAKE_CURRENT_SOURCE_DIR}/content_store.cc -) - - -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}/event_reactor.h - ${CMAKE_CURRENT_SOURCE_DIR}/deadline_timer.h - ${CMAKE_CURRENT_SOURCE_DIR}/ring_buffer.h - ${CMAKE_CURRENT_SOURCE_DIR}/event_reactor.h - ${CMAKE_CURRENT_SOURCE_DIR}/min_filter.h - ${CMAKE_CURRENT_SOURCE_DIR}/stream_buffer.h - ${CMAKE_CURRENT_SOURCE_DIR}/literals.h - ${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}/suffix_strategy.h - ${CMAKE_CURRENT_SOURCE_DIR}/conversions.h - ${CMAKE_CURRENT_SOURCE_DIR}/linux.h - ${CMAKE_CURRENT_SOURCE_DIR}/log.h - ${CMAKE_CURRENT_SOURCE_DIR}/event_thread.h - ${CMAKE_CURRENT_SOURCE_DIR}/object_pool.h - ${CMAKE_CURRENT_SOURCE_DIR}/membuf.h - ${CMAKE_CURRENT_SOURCE_DIR}/spinlock.h - ${CMAKE_CURRENT_SOURCE_DIR}/content_store.h - ${CMAKE_CURRENT_SOURCE_DIR}/key_id.h -) - -if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") - list(APPEND HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/epoll_event_reactor.h - ${CMAKE_CURRENT_SOURCE_DIR}/fd_deadline_timer.h - ) - - list(APPEND SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/epoll_event_reactor.cc - ) -endif() - -if(NOT WIN32) - list(APPEND HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/daemonizator.h - ) - list(APPEND SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/daemonizator.cc - ) -endif() - -set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE) -set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) diff --git a/libtransport/src/hicn/transport/utils/array.h b/libtransport/src/hicn/transport/utils/array.h deleted file mode 100644 index 7c0ed65d8..000000000 --- a/libtransport/src/hicn/transport/utils/array.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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/src/hicn/transport/utils/branch_prediction.h b/libtransport/src/hicn/transport/utils/branch_prediction.h deleted file mode 100644 index 8cbfaca76..000000000 --- a/libtransport/src/hicn/transport/utils/branch_prediction.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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/src/hicn/transport/utils/chrono_typedefs.h b/libtransport/src/hicn/transport/utils/chrono_typedefs.h deleted file mode 100644 index 8f28e763c..000000000 --- a/libtransport/src/hicn/transport/utils/chrono_typedefs.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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/src/hicn/transport/utils/content_store.cc b/libtransport/src/hicn/transport/utils/content_store.cc deleted file mode 100644 index ba13bef41..000000000 --- a/libtransport/src/hicn/transport/utils/content_store.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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. - */ - -#include <hicn/transport/core/content_object.h> -#include <hicn/transport/core/interest.h> -#include <hicn/transport/core/name.h> -#include <hicn/transport/utils/content_store.h> - -namespace utils { - -ContentStore::ContentStore(std::size_t max_packets) - : max_content_store_size_(max_packets) {} - -ContentStore::~ContentStore() {} - -void ContentStore::insert( - const std::shared_ptr<ContentObject> &content_object) { - if (max_content_store_size_ == 0) { - return; - } - - utils::SpinLock::Acquire locked(cs_mutex_); - - if (TRANSPORT_EXPECT_FALSE(content_store_hash_table_.size() != - fifo_list_.size())) { - TRANSPORT_LOGW("Inconsistent size!!!!"); - TRANSPORT_LOGW("Hash Table: %zu |||| FIFO List: %zu", - content_store_hash_table_.size(), fifo_list_.size()); - } - - if (content_store_hash_table_.size() >= max_content_store_size_) { - content_store_hash_table_.erase(fifo_list_.back()); - fifo_list_.pop_back(); - } - - // Insert new item - auto it = content_store_hash_table_.find(content_object->getName()); - if (it != content_store_hash_table_.end()) { - fifo_list_.erase(it->second.second); - content_store_hash_table_.erase(content_object->getName()); - } - - fifo_list_.push_front(std::cref(content_object->getName())); - auto pos = fifo_list_.begin(); - content_store_hash_table_[content_object->getName()] = ContentStoreEntry( - ObjectTimeEntry(content_object, std::chrono::steady_clock::now()), pos); -} - -const std::shared_ptr<ContentObject> ContentStore::find( - const Interest &interest) { - utils::SpinLock::Acquire locked(cs_mutex_); - - std::shared_ptr<ContentObject> ret = empty_reference_; - auto it = content_store_hash_table_.find(interest.getName()); - if (it != content_store_hash_table_.end()) { - - auto content_lifetime = it->second.first.first->getLifetime(); - auto time_passed_since_creation = - std::chrono::duration_cast<std::chrono::milliseconds>( - std::chrono::steady_clock::now() - it->second.first.second) - .count(); - - if (time_passed_since_creation > content_lifetime) { - fifo_list_.erase(it->second.second); - content_store_hash_table_.erase(it); - } - else { - ret = it->second.first.first; - } - } - - return ret; -} - -void ContentStore::erase(const Name &exact_name) { - utils::SpinLock::Acquire locked(cs_mutex_); - auto it = content_store_hash_table_.find(exact_name); - fifo_list_.erase(it->second.second); - content_store_hash_table_.erase(exact_name); -} - -void ContentStore::setLimit(size_t max_packets) { - utils::SpinLock::Acquire locked(cs_mutex_); - max_content_store_size_ = max_packets; -} - -std::size_t ContentStore::getLimit() const { - utils::SpinLock::Acquire locked(cs_mutex_); - return max_content_store_size_; -} - -std::size_t ContentStore::size() const { - utils::SpinLock::Acquire locked(cs_mutex_); - return content_store_hash_table_.size(); -} - -void ContentStore::printContent() { - for (auto &item : content_store_hash_table_) { - if (item.second.first.first->getPayloadType() == - transport::core::PayloadType::MANIFEST) { - TRANSPORT_LOGI("Manifest: %s", - item.second.first.first->getName().toString().c_str()); - } else { - TRANSPORT_LOGI("Data Packet: %s", - item.second.first.first->getName().toString().c_str()); - } - } -} - -} // end namespace utils
\ No newline at end of file diff --git a/libtransport/src/hicn/transport/utils/content_store.h b/libtransport/src/hicn/transport/utils/content_store.h deleted file mode 100644 index 613ffcbc2..000000000 --- a/libtransport/src/hicn/transport/utils/content_store.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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/socket.h> -#include <hicn/transport/utils/spinlock.h> - -#include <mutex> - -namespace transport { - -namespace core { -class Name; -class ContentObject; -class Interest; -} // namespace core - -} // namespace transport - -namespace utils { - -using Name = transport::core::Name; -using ContentObject = transport::core::ContentObject; -using Interest = transport::core::Interest; - -typedef std::pair<std::shared_ptr<ContentObject>, - std::chrono::steady_clock::time_point> - ObjectTimeEntry; -typedef std::pair<ObjectTimeEntry, - std::list<std::reference_wrapper<const Name>>::iterator> - ContentStoreEntry; -typedef std::list<std::reference_wrapper<const Name>> FIFOList; -typedef std::unordered_map<Name, ContentStoreEntry> ContentStoreHashTable; - -class ContentStore { - public: - explicit ContentStore(std::size_t max_packets = (1 << 16)); - - ~ContentStore(); - - void insert(const std::shared_ptr<ContentObject> &content_object); - - const std::shared_ptr<ContentObject> find(const Interest &interest); - - void erase(const Name &exact_name); - - void setLimit(size_t max_packets); - - size_t getLimit() const; - - size_t size() const; - - void printContent(); - - private: - ContentStoreHashTable content_store_hash_table_; - FIFOList fifo_list_; - std::shared_ptr<ContentObject> empty_reference_; - // Must be atomic - std::atomic_size_t max_content_store_size_; - mutable utils::SpinLock cs_mutex_; -}; - -} // end namespace utils
\ No newline at end of file diff --git a/libtransport/src/hicn/transport/utils/conversions.h b/libtransport/src/hicn/transport/utils/conversions.h deleted file mode 100644 index 24b529206..000000000 --- a/libtransport/src/hicn/transport/utils/conversions.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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/src/hicn/transport/utils/crypto_hash.h b/libtransport/src/hicn/transport/utils/crypto_hash.h deleted file mode 100644 index 945909d14..000000000 --- a/libtransport/src/hicn/transport/utils/crypto_hash.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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/utils/array.h> -#include <hicn/transport/utils/crypto_hash_type.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/src/hicn/transport/utils/crypto_hash_type.h b/libtransport/src/hicn/transport/utils/crypto_hash_type.h deleted file mode 100644 index b7597e208..000000000 --- a/libtransport/src/hicn/transport/utils/crypto_hash_type.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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/src/hicn/transport/utils/crypto_hasher.h b/libtransport/src/hicn/transport/utils/crypto_hasher.h deleted file mode 100644 index c34a26fac..000000000 --- a/libtransport/src/hicn/transport/utils/crypto_hasher.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <hicn/transport/utils/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/src/hicn/transport/utils/crypto_suite.h b/libtransport/src/hicn/transport/utils/crypto_suite.h deleted file mode 100644 index 8ae32b846..000000000 --- a/libtransport/src/hicn/transport/utils/crypto_suite.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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> -}; - -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/src/hicn/transport/utils/daemonizator.cc b/libtransport/src/hicn/transport/utils/daemonizator.cc deleted file mode 100644 index c51a68d14..000000000 --- a/libtransport/src/hicn/transport/utils/daemonizator.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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. - */ - -#ifndef _WIN32 -#include <hicn/transport/errors/runtime_exception.h> -#include <hicn/transport/utils/daemonizator.h> -#include <hicn/transport/utils/log.h> - -#include <sys/stat.h> -#include <unistd.h> - -namespace utils { - -void Daemonizator::daemonize(bool close_fds) { - pid_t process_id = 0; - pid_t sid = 0; - - // Create child process - process_id = fork(); - - // Indication of fork() failure - if (process_id < 0) { - throw errors::RuntimeException("Fork failed."); - } - - // PARENT PROCESS. Need to kill it. - if (process_id > 0) { - TRANSPORT_LOGE("Process id of child process %d", process_id); - // return success in exit status - exit(EXIT_SUCCESS); - } - - // unmask the file mode - umask(0); - - // set new session - sid = setsid(); - if (sid < 0) { - // Return failure - exit(EXIT_FAILURE); - } - - // Change the current working directory to root. - int ret = chdir("/"); - - if (ret < 0) { - throw errors::RuntimeException("Error changing working directory to root"); - } - - // Close stdin. Redirect stdout and stderr to file if possible - - if (close_fds) { - close(STDOUT_FILENO); - close(STDERR_FILENO); - } - - close(STDIN_FILENO); - - // Really start application -} - -} // namespace utils - -#endif diff --git a/libtransport/src/hicn/transport/utils/daemonizator.h b/libtransport/src/hicn/transport/utils/daemonizator.h deleted file mode 100644 index 028d74865..000000000 --- a/libtransport/src/hicn/transport/utils/daemonizator.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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/src/hicn/transport/utils/deadline_timer.h b/libtransport/src/hicn/transport/utils/deadline_timer.h deleted file mode 100644 index 61f906141..000000000 --- a/libtransport/src/hicn/transport/utils/deadline_timer.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <hicn/transport/utils/event_reactor.h> - -#include <chrono> -#include <cstddef> -#include <cstring> -#include <utility> - -namespace std { -namespace chrono { -namespace detail { - -template <typename From, typename To> -struct posix_duration_cast; - -// chrono -> timespec caster -template <typename Rep, typename Period> -struct posix_duration_cast<std::chrono::duration<Rep, Period>, - struct timespec> { - static struct timespec cast(std::chrono::duration<Rep, Period> const &d) { - struct timespec tv; - - std::chrono::seconds const sec = - std::chrono::duration_cast<std::chrono::seconds>(d); - - tv.tv_sec = sec.count(); - tv.tv_nsec = - std::chrono::duration_cast<std::chrono::nanoseconds>(d - sec).count(); - - return tv; - } -}; - -// timespec -> chrono caster -template <typename Rep, typename Period> -struct posix_duration_cast<struct timespec, - std::chrono::duration<Rep, Period>> { - static std::chrono::duration<Rep, Period> cast(struct timespec const &tv) { - return std::chrono::duration_cast<std::chrono::duration<Rep, Period>>( - std::chrono::seconds(tv.tv_sec) + std::chrono::nanoseconds(tv.tv_nsec)); - } -}; - -} // namespace detail - -// chrono -> timespec -template <typename T, typename Rep, typename Period> -auto duration_cast(std::chrono::duration<Rep, Period> const &d) -> - typename std::enable_if<std::is_same<T, struct timespec>::value, - struct timespec>::type { - return detail::posix_duration_cast<std::chrono::duration<Rep, Period>, - timespec>::cast(d); -} - -// timespec -> chrono -template <typename Duration> -Duration duration_cast(struct timespec const &tv) { - return detail::posix_duration_cast<struct timespec, Duration>::cast(tv); -} - -} // namespace chrono -} // namespace std - -namespace utils { - -template <typename Implementation> -class DeadlineTimer { - public: - virtual ~DeadlineTimer() = default; - - template <typename WaitHandler> - void asyncWait(WaitHandler &&callback) { - static_cast<Implementation *>(this)->asyncWaitImpl( - std::forward<WaitHandler>(callback)); - } - - void wait() { static_cast<Implementation *>(this)->waitImpl(); } - - template <typename T, typename R> - void expiresFromNow(std::chrono::duration<T, R> &&duration) { - static_cast<Implementation *>(this)->expiresFromNowImpl( - std::forward<std::chrono::duration<T, R>>(duration)); - } - - template <typename TimePoint, - typename = typename std::enable_if< - std::is_same<std::remove_reference_t<TimePoint>, - std::chrono::steady_clock::time_point>::value, - TimePoint>::type> - void expiresAt(TimePoint &&time_point) { - static_cast<Implementation *>(this)->expiresAtImpl( - std::forward<TimePoint>(time_point)); - } - - void cancel() { static_cast<Implementation *>(this)->cancelImpl(); } -}; - -} // namespace utils diff --git a/libtransport/src/hicn/transport/utils/epoll_event_reactor.cc b/libtransport/src/hicn/transport/utils/epoll_event_reactor.cc deleted file mode 100644 index a97e89500..000000000 --- a/libtransport/src/hicn/transport/utils/epoll_event_reactor.cc +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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. - */ - -#include <hicn/transport/utils/branch_prediction.h> -#include <hicn/transport/utils/epoll_event_reactor.h> -#include <hicn/transport/utils/fd_deadline_timer.h> - -#include <signal.h> -#include <unistd.h> -#include <iostream> - -namespace utils { - -EpollEventReactor::EpollEventReactor() - : epoll_fd_(epoll_create(20000)), run_event_loop_(true) {} - -EpollEventReactor::~EpollEventReactor() { close(epoll_fd_); } - -int EpollEventReactor::addFileDescriptor(int fd, uint32_t events) { - if (TRANSPORT_EXPECT_FALSE(fd < 0)) { - TRANSPORT_LOGE("invalid fd %d", fd); - return -1; - } - - struct epoll_event evt; - std::memset(&evt, 0, sizeof(evt)); - evt.events = events; - evt.data.fd = fd; - - if (TRANSPORT_EXPECT_FALSE(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &evt) < - 0)) { - TRANSPORT_LOGE("epoll_ctl: %s fd %d", strerror(errno), fd); - return -1; - } - - return 0; -} - -int EpollEventReactor::modFileDescriptor(int fd, uint32_t events) { - if (TRANSPORT_EXPECT_FALSE(fd < 0)) { - TRANSPORT_LOGE("invalid fd %d", fd); - return -1; - } - - struct epoll_event evt; - memset(&evt, 0, sizeof(evt)); - evt.events = events; - evt.data.fd = fd; - - if (TRANSPORT_EXPECT_FALSE(epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &evt) < - 0)) { - TRANSPORT_LOGE("epoll_ctl: %s fd %d", strerror(errno), fd); - return -1; - } - - return 0; -} - -std::size_t EpollEventReactor::mapSize() { return event_callback_map_.size(); } - -int EpollEventReactor::delFileDescriptor(int fd) { - if (TRANSPORT_EXPECT_FALSE(fd < 0)) { - TRANSPORT_LOGE("invalid fd %d", fd); - return -1; - } - - struct epoll_event evt; - memset(&evt, 0, sizeof(evt)); - - if (TRANSPORT_EXPECT_FALSE(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &evt) < - 0)) { - TRANSPORT_LOGE("epoll_ctl: %s fd %d", strerror(errno), fd); - return -1; - } - - utils::SpinLock::Acquire locked(event_callback_map_lock_); - event_callback_map_.erase(fd); - - return 0; -} - -void EpollEventReactor::runEventLoop(int timeout) { - Event evt[128]; - int en = 0; - EventCallbackMap::iterator it; - EventCallback callback; - - // evt.events = EPOLLIN | EPOLLOUT; - sigset_t sigset; - sigemptyset(&sigset); - - while (run_event_loop_) { - memset(&evt, 0, sizeof(evt)); - - en = epoll_pwait(epoll_fd_, evt, 128, timeout, &sigset); - - if (TRANSPORT_EXPECT_FALSE(en < 0)) { - TRANSPORT_LOGE("epoll_pwait: %s", strerror(errno)); - return; - } - - for (int i = 0; i < en; i++) { - if (evt[i].data.fd > 0) { - { - utils::SpinLock::Acquire locked(event_callback_map_lock_); - it = event_callback_map_.find(evt[i].data.fd); - } - - if (TRANSPORT_EXPECT_FALSE(it == event_callback_map_.end())) { - TRANSPORT_LOGE("unexpected event. fd %d", evt[i].data.fd); - } else { - { - utils::SpinLock::Acquire locked(event_callback_map_lock_); - callback = event_callback_map_[evt[i].data.fd]; - } - - callback(evt[i]); - - // In the callback the epoll event reactor could have been stopped, - // then we need to check whether the event loop is still running. - if (TRANSPORT_EXPECT_FALSE(!run_event_loop_)) { - return; - } - } - } else { - TRANSPORT_LOGE("unexpected event. fd %d", evt[i].data.fd); - } - } - } -} - -void EpollEventReactor::runOneEvent() { - Event evt; - int en = 0; - EventCallbackMap::iterator it; - EventCallback callback; - - // evt.events = EPOLLIN | EPOLLOUT; - sigset_t sigset; - sigemptyset(&sigset); - - memset(&evt, 0, sizeof(evt)); - - en = epoll_pwait(epoll_fd_, &evt, 1, -1, &sigset); - - if (TRANSPORT_EXPECT_FALSE(en < 0)) { - TRANSPORT_LOGE("epoll_pwait: %s", strerror(errno)); - return; - } - - if (TRANSPORT_EXPECT_TRUE(evt.data.fd > 0)) { - { - utils::SpinLock::Acquire locked(event_callback_map_lock_); - it = event_callback_map_.find(evt.data.fd); - } - - if (TRANSPORT_EXPECT_FALSE(it == event_callback_map_.end())) { - TRANSPORT_LOGE("unexpected event. fd %d", evt.data.fd); - } else { - { - utils::SpinLock::Acquire locked(event_callback_map_lock_); - callback = event_callback_map_[evt.data.fd]; - } - - callback(evt); - } - } else { - TRANSPORT_LOGE("unexpected event. fd %d", evt.data.fd); - } -} - -void EpollEventReactor::stop() { run_event_loop_ = false; } - -} // namespace utils
\ No newline at end of file diff --git a/libtransport/src/hicn/transport/utils/epoll_event_reactor.h b/libtransport/src/hicn/transport/utils/epoll_event_reactor.h deleted file mode 100644 index 04c10fc7e..000000000 --- a/libtransport/src/hicn/transport/utils/epoll_event_reactor.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <hicn/transport/utils/event_reactor.h> -#include <hicn/transport/utils/spinlock.h> - -#include <sys/epoll.h> -#include <atomic> -#include <cstddef> -#include <functional> -#include <mutex> -#include <unordered_map> - -#define FD_NUMBER 20000 - -namespace utils { - -typedef struct epoll_event Event; -typedef std::function<int(const Event &)> EventCallback; -typedef std::unordered_map<int, EventCallback> EventCallbackMap; - -class EpollEventReactor : public EventReactor { - public: - explicit EpollEventReactor(); - - ~EpollEventReactor(); - - template <typename EventHandler> - int addFileDescriptor(int fd, uint32_t events, EventHandler &&callback) { - auto it = event_callback_map_.find(fd); - int ret = 0; - - if (it == event_callback_map_.end()) { - { - utils::SpinLock::Acquire locked(event_callback_map_lock_); - event_callback_map_[fd] = std::forward<EventHandler &&>(callback); - } - - ret = addFileDescriptor(fd, events); - } - - return ret; - } - - int delFileDescriptor(int fd); - - int modFileDescriptor(int fd, uint32_t events); - - void runEventLoop(int timeout = -1) override; - - void runOneEvent() override; - - void stop() override; - - std::size_t mapSize(); - - private: - int addFileDescriptor(int fd, uint32_t events); - - int epoll_fd_; - std::atomic_bool run_event_loop_; - EventCallbackMap event_callback_map_; - utils::SpinLock event_callback_map_lock_; -}; - -} // namespace utils diff --git a/libtransport/src/hicn/transport/utils/event_reactor.h b/libtransport/src/hicn/transport/utils/event_reactor.h deleted file mode 100644 index 4f8b58296..000000000 --- a/libtransport/src/hicn/transport/utils/event_reactor.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 <cstddef> -#include <functional> -#include <system_error> - -namespace utils { - -typedef std::function<void(const std::error_code &ec)> UserCallback; - -class EventReactor { - public: - virtual ~EventReactor() = default; - - virtual void runEventLoop(int timeout = -1) = 0; - - virtual void runOneEvent() = 0; - - virtual void stop() = 0; -}; - -} // namespace utils diff --git a/libtransport/src/hicn/transport/utils/event_thread.h b/libtransport/src/hicn/transport/utils/event_thread.h deleted file mode 100644 index e50ae9648..000000000 --- a/libtransport/src/hicn/transport/utils/event_thread.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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 <memory> - -#include <asio.hpp> - -namespace utils { - -class EventThread { - private: - // No copies - EventThread(const EventThread&) = delete; // non construction-copyable - EventThread& operator=(const EventThread&) = delete; // non copyable - - public: - explicit EventThread(asio::io_service& io_service) - : internal_io_service_(nullptr), - io_service_(io_service), - work_(io_service_), - thread_(nullptr) { - run(); - } - - explicit EventThread() - : internal_io_service_(std::make_unique<asio::io_service>()), - io_service_(*internal_io_service_), - work_(io_service_), - thread_(nullptr) { - run(); - } - - ~EventThread() { stop(); } - - void run() { - if (stopped()) { - io_service_.reset(); - } - - thread_ = std::make_unique<std::thread>([this]() { io_service_.run(); }); - } - - std::thread::id getThreadId() const { - if (thread_) { - return thread_->get_id(); - } else { - throw errors::RuntimeException("Event thread is not running."); - } - } - - template <typename Func> - void add(Func&& f) { - // If the function f - // TODO USe post in mac os, asio->post in xenial - io_service_.post(std::forward<Func&&>(f)); - } - - template <typename Func> - void tryRunHandlerNow(Func&& f) { - io_service_.dispatch(std::forward<Func&&>(f)); - } - - void stop() { - io_service_.stop(); - - if (thread_ && thread_->joinable()) { - thread_->join(); - } - - thread_.reset(); - } - - bool stopped() { return io_service_.stopped(); } - - asio::io_service& getIoService() { return io_service_; } - - private: - std::unique_ptr<asio::io_service> internal_io_service_; - asio::io_service& io_service_; - asio::io_service::work work_; - std::unique_ptr<std::thread> thread_; -}; - -} // namespace utils
\ No newline at end of file diff --git a/libtransport/src/hicn/transport/utils/fd_deadline_timer.h b/libtransport/src/hicn/transport/utils/fd_deadline_timer.h deleted file mode 100644 index 1c14513c9..000000000 --- a/libtransport/src/hicn/transport/utils/fd_deadline_timer.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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/utils/deadline_timer.h> -#include <hicn/transport/utils/epoll_event_reactor.h> -#include <hicn/transport/utils/log.h> - -#include <chrono> -#include <cstddef> - -#include <sys/timerfd.h> -#include <unistd.h> - -namespace utils { - -class FdDeadlineTimer : public DeadlineTimer<FdDeadlineTimer> { - public: - explicit FdDeadlineTimer(EpollEventReactor &reactor) - : reactor_(reactor), - timer_fd_(timerfd_create(CLOCK_MONOTONIC, 0)), - flags_(0) { - if (timer_fd_ == -1) { - throw errors::RuntimeException("Impossible to create the timer!"); - } - } - - ~FdDeadlineTimer() { close(timer_fd_); } - - template <typename WaitHandler> - void asyncWaitImpl(WaitHandler &&callback) { - // ASIO_WAIT_HANDLER_CHECK(WaitHandler, callback) type_check; - - if (timerfd_settime(timer_fd_, flags_, &new_value_, NULL) == -1) { - throw errors::RuntimeException("Impossible to set the timer!"); - } - - uint32_t events = EPOLLIN; - - reactor_.addFileDescriptor( - timer_fd_, events, - [callback = std::forward<WaitHandler &&>(callback)]( - const Event &event) -> int { - uint64_t s = 0; - std::error_code ec; - - if (read(event.data.fd, &s, sizeof(s)) == -1) { - TRANSPORT_LOGE("Read error!!"); - } - - if (!(event.events & EPOLLIN)) { - ec = std::make_error_code(std::errc::operation_canceled); - } - - callback(ec); - - return 0; - }); - } - - void waitImpl() { - if (timerfd_settime(timer_fd_, flags_, &new_value_, NULL) == -1) { - throw errors::RuntimeException("Impossible to set the timer!"); - } - - uint64_t ret; - - if (read(timer_fd_, &ret, sizeof(ret)) == -1) { - throw errors::RuntimeException( - "Error while waiting for the timer expiration."); - } - } - - template <typename T, typename R> - void expiresFromNowImpl(std::chrono::duration<T, R> &&duration) { - std::memset(&new_value_, 0, sizeof(new_value_)); - new_value_.it_value = std::chrono::duration_cast<struct timespec>( - std::forward<std::chrono::duration<T, R>>(duration)); - } - - template <typename TimePoint, - typename = std::enable_if_t< - std::is_same<std::remove_reference_t<TimePoint>, - std::chrono::steady_clock::time_point>::value, - TimePoint>> - void expiresAtImpl(TimePoint &&time_point) { - std::memset(&new_value_, 0, sizeof(new_value_)); - - new_value_.it_value = std::chrono::duration_cast<struct timespec>( - time_point.time_since_epoch()); - flags_ |= TFD_TIMER_ABSTIME; - } - - void cancelImpl() { - std::memset(&new_value_, 0, sizeof(new_value_)); - - if (timerfd_settime(timer_fd_, 0, &new_value_, NULL) == -1) { - throw errors::RuntimeException("Impossible to cancel the timer!"); - } - - // reactor_.delFileDescriptor(timer_fd_); - } - - EventReactor &getEventReactor() { return reactor_; } - - private: - EpollEventReactor &reactor_; - int timer_fd_; - EventCallback callback_; - struct itimerspec new_value_; - int flags_; -}; - -} // namespace utils diff --git a/libtransport/src/hicn/transport/utils/hash.h b/libtransport/src/hicn/transport/utils/hash.h deleted file mode 100644 index 6815ca4bf..000000000 --- a/libtransport/src/hicn/transport/utils/hash.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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/src/hicn/transport/utils/identity.cc b/libtransport/src/hicn/transport/utils/identity.cc deleted file mode 100644 index c5ab03e44..000000000 --- a/libtransport/src/hicn/transport/utils/identity.cc +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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. - */ - -#include <hicn/transport/utils/identity.h> - -extern "C" { -#include <parc/security/parc_PublicKeySigner.h> -#include <parc/security/parc_Security.h> -} - -namespace utils { - -Identity::Identity(const std::string &keystore_name, - const std::string &keystore_password, CryptoSuite suite, - unsigned int key_length, unsigned int validity_days, - const std::string &subject_name) { - parcSecurity_Init(); - - bool success = parcPkcs12KeyStore_CreateFile( - keystore_name.c_str(), keystore_password.c_str(), subject_name.c_str(), - parcCryptoSuite_GetSigningAlgorithm(static_cast<PARCCryptoSuite>(suite)), - key_length, validity_days); - - parcAssertTrue( - success, - "parcPkcs12KeyStore_CreateFile('%s', '%s', '%s', %d, %d) failed.", - keystore_name.c_str(), keystore_password.c_str(), subject_name.c_str(), - static_cast<int>(key_length), validity_days); - - PARCIdentityFile *identity_file = - parcIdentityFile_Create(keystore_name.c_str(), keystore_password.c_str()); - - identity_ = - parcIdentity_Create(identity_file, PARCIdentityFileAsPARCIdentity); - - PARCSigner *signer = parcIdentity_CreateSigner( - identity_, - parcCryptoSuite_GetCryptoHash(static_cast<PARCCryptoSuite>(suite))); - - signer_ = std::make_shared<Signer>(signer, suite); - - parcSigner_Release(&signer); - parcIdentityFile_Release(&identity_file); -} - -Identity::Identity(const Identity &other) - : signer_(other.signer_), hash_algorithm_(other.hash_algorithm_) { - parcSecurity_Init(); - identity_ = parcIdentity_Acquire(other.identity_); -} - -Identity Identity::generateIdentity(const std::string &subject_name) { - std::string keystore_name = "keystore"; - std::string keystore_password = "password"; - std::size_t key_length = 1024; - unsigned int validity_days = 30; - CryptoSuite suite = CryptoSuite::RSA_SHA256; - - return utils::Identity(keystore_name, keystore_password, suite, - (unsigned int)key_length, validity_days, subject_name); -} - -Identity::Identity(std::string &file_name, std::string &password, - transport::core::HashAlgorithm hash_algorithm) - : hash_algorithm_(hash_algorithm) { - parcSecurity_Init(); - - PARCIdentityFile *identity_file = - parcIdentityFile_Create(file_name.c_str(), password.c_str()); - - identity_ = - parcIdentity_Create(identity_file, PARCIdentityFileAsPARCIdentity); - - PARCSigner *signer = parcIdentity_CreateSigner( - identity_, static_cast<PARCCryptoHashType>(hash_algorithm)); - - signer_ = std::make_shared<Signer>( - signer, CryptoSuite(parcSigner_GetCryptoSuite(signer))); - - parcSigner_Release(&signer); - parcIdentityFile_Release(&identity_file); -} - -Identity::~Identity() { - parcIdentity_Release(&identity_); - parcSecurity_Fini(); -} - -std::string Identity::getFileName() { - return std::string(parcIdentity_GetFileName(identity_)); -} - -std::string Identity::getPassword() { - return std::string(parcIdentity_GetPassWord(identity_)); -} - -std::shared_ptr<Signer> Identity::getSigner() { return signer_; } - -size_t Identity::getSignatureLength() const { - return signer_->getSignatureLength(); -} - -} // namespace utils diff --git a/libtransport/src/hicn/transport/utils/identity.h b/libtransport/src/hicn/transport/utils/identity.h deleted file mode 100644 index e9801a005..000000000 --- a/libtransport/src/hicn/transport/utils/identity.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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/manifest_format.h> -#include <hicn/transport/utils/crypto_suite.h> -#include <hicn/transport/utils/signer.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/src/hicn/transport/utils/key_id.h b/libtransport/src/hicn/transport/utils/key_id.h deleted file mode 100644 index d67b73d7a..000000000 --- a/libtransport/src/hicn/transport/utils/key_id.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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/src/hicn/transport/utils/linux.h b/libtransport/src/hicn/transport/utils/linux.h deleted file mode 100644 index 5820528e1..000000000 --- a/libtransport/src/hicn/transport/utils/linux.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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/src/hicn/transport/utils/literals.h b/libtransport/src/hicn/transport/utils/literals.h deleted file mode 100644 index bd00e0a58..000000000 --- a/libtransport/src/hicn/transport/utils/literals.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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/src/hicn/transport/utils/log.cc b/libtransport/src/hicn/transport/utils/log.cc deleted file mode 100644 index 27dd3f541..000000000 --- a/libtransport/src/hicn/transport/utils/log.cc +++ /dev/null @@ -1,1403 +0,0 @@ -/* - * 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. - */ - -/* When defined, Android log (android/log.h) will be used by default instead of - * stderr (ignored on non-Android platforms). Date, time, pid and tid (context) - * will be provided by Android log. Android log features will be used to output - * log level and tag. - */ - -#if defined(__ANDROID__) -#define TRANSPORT_LOG_USE_ANDROID_LOG 1 -#define ANDROID_TAG "HicnTransport" -#else -#define TRANSPORT_LOG_USE_ANDROID_LOG 0 -#endif - -/* When defined, NSLog (uses Apple System Log) will be used instead of stderr - * (ignored on non-Apple platforms). Date, time, pid and tid (context) will be - * provided by NSLog. Curiously, doesn't use NSLog() directly, but piggybacks on - * non-public CFLog() function. Both use Apple System Log internally, but it's - * easier to call CFLog() from C than NSLog(). Current implementation doesn't - * support "%@" format specifier. - */ -#ifdef TRANSPORT_LOG_USE_NSLOG -#undef TRANSPORT_LOG_USE_NSLOG -#if defined(__APPLE__) && defined(__MACH__) -#define TRANSPORT_LOG_USE_NSLOG 1 -#else -#define TRANSPORT_LOG_USE_NSLOG 0 -#endif -#else -#define TRANSPORT_LOG_USE_NSLOG 0 -#endif -/* When defined, OutputDebugString() will be used instead of stderr (ignored on - * non-Windows platforms). Uses OutputDebugStringA() variant and feeds it with - * UTF-8 data. - */ -#ifdef TRANSPORT_LOG_USE_DEBUGSTRING -#undef TRANSPORT_LOG_USE_DEBUGSTRING -#if defined(_WIN32) || defined(_WIN64) -#define TRANSPORT_LOG_USE_DEBUGSTRING 1 -#else -#define TRANSPORT_LOG_USE_DEBUGSTRING 0 -#endif -#else -#define TRANSPORT_LOG_USE_DEBUGSTRING 0 -#endif -/* When defined, TRANSPORT_LOG library will not contain definition of tag prefix - * variable. In that case it must be defined elsewhere using - * TRANSPORT_LOG_DEFINE_TAG_PREFIX macro, for example: - * - * TRANSPORT_LOG_DEFINE_TAG_PREFIX = "ProcessName"; - * - * This allows to specify custom value for static initialization and avoid - * overhead of setting this value in runtime. - */ -#ifdef TRANSPORT_LOG_EXTERN_TAG_PREFIX -#undef TRANSPORT_LOG_EXTERN_TAG_PREFIX -#define TRANSPORT_LOG_EXTERN_TAG_PREFIX 1 -#else -#define TRANSPORT_LOG_EXTERN_TAG_PREFIX 0 -#endif -/* When defined, TRANSPORT_LOG library will not contain definition of global - * format variable. In that case it must be defined elsewhere using - * TRANSPORT_LOG_DEFINE_GLOBAL_FORMAT macro, for example: - * - * TRANSPORT_LOG_DEFINE_GLOBAL_FORMAT = {MEM_WIDTH}; - * - * This allows to specify custom value for static initialization and avoid - * overhead of setting this value in runtime. - */ -#ifdef TRANSPORT_LOG_EXTERN_GLOBAL_FORMAT -#undef TRANSPORT_LOG_EXTERN_GLOBAL_FORMAT -#define TRANSPORT_LOG_EXTERN_GLOBAL_FORMAT 1 -#else -#define TRANSPORT_LOG_EXTERN_GLOBAL_FORMAT 0 -#endif -/* When defined, transport_log library will not contain definition of global - * output variable. In that case it must be defined elsewhere using - * TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT macro, for example: - * - * TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT = {TRANSPORT_LOG_PUT_STD, - * custom_output_callback}; - * - * This allows to specify custom value for static initialization and avoid - * overhead of setting this value in runtime. - */ -#ifdef TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT -#undef TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT -#define TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT 1 -#else -#define TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT 0 -#endif -/* When defined, transport_log library will not contain definition of global - * output level variable. In that case it must be defined elsewhere using - * TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL macro, for example: - * - * TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL = TRANSPORT_LOG_WARN; - * - * This allows to specify custom value for static initialization and avoid - * overhead of setting this value in runtime. - */ -#ifdef TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL -#undef TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL -#define TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL 1 -#else -#define TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL 0 -#endif -/* When defined, implementation will prefer smaller code size over speed. - * Very rough estimate is that code will be up to 2x smaller and up to 2x - * slower. Disabled by default. - */ -#ifdef TRANSPORT_LOG_OPTIMIZE_SIZE -#undef TRANSPORT_LOG_OPTIMIZE_SIZE -#define TRANSPORT_LOG_OPTIMIZE_SIZE 1 -#else -#define TRANSPORT_LOG_OPTIMIZE_SIZE 0 -#endif -/* Size of the log line buffer. The buffer is allocated on stack. It limits - * maximum length of a log line. - */ -#ifndef TRANSPORT_LOG_BUF_SZ -#define TRANSPORT_LOG_BUF_SZ 512 -#endif -/* Default number of bytes in one line of memory output. For large values - * TRANSPORT_LOG_BUF_SZ also must be increased. - */ -#ifndef TRANSPORT_LOG_MEM_WIDTH -#define TRANSPORT_LOG_MEM_WIDTH 32 -#endif -/* String to put in the end of each log line (can be empty). Its value used by - * stderr output callback. Its size used as a default value for - * TRANSPORT_LOG_EOL_SZ. - */ -#ifndef TRANSPORT_LOG_EOL -#define TRANSPORT_LOG_EOL "\n" -#endif -/* Default delimiter that separates parts of log message. Can NOT contain '%' - * or '\0'. - * - * Log message format specifications can override (or ignore) this value. For - * more details see TRANSPORT_LOG_MESSAGE_CTX_FORMAT, - * TRANSPORT_LOG_MESSAGE_SRC_FORMAT and TRANSPORT_LOG_MESSAGE_TAG_FORMAT. - */ -#ifndef TRANSPORT_LOG_DEF_DELIMITER -#define TRANSPORT_LOG_DEF_DELIMITER " " -#endif -/* Specifies log message context format. Log message context includes date, - * time, process id, thread id and message's log level. Custom information can - * be added as well. Supported fields: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, - * MILLISECOND, PID, TID, LEVEL, S(str), F_INIT(statements), - * F_UINT(width, value). - * - * Must be defined as a tuple, for example: - * - * #define TRANSPORT_LOG_MESSAGE_CTX_FORMAT (YEAR, S("."), MONTH, S("."), DAY, - * S(" > ")) - * - * In that case, resulting log message will be: - * - * 2016.12.22 > TAG function@filename.c:line Message text - * - * Note, that tag, source location and message text are not impacted by - * this setting. See TRANSPORT_LOG_MESSAGE_TAG_FORMAT and - * TRANSPORT_LOG_MESSAGE_SRC_FORMAT. - * - * If message context must be visually separated from the rest of the message, - * it must be reflected in context format (notice trailing S(" > ") in the - * example above). - * - * S(str) adds constant string str. String can NOT contain '%' or '\0'. - * - * F_INIT(statements) adds initialization statement(s) that will be evaluated - * once for each log message. All statements are evaluated in specified order. - * Several F_INIT() fields can be used in every log message format - * specification. Fields, like F_UINT(width, value), are allowed to use results - * of initialization statements. If statement introduces variables (or other - * names, like structures) they must be prefixed with "f_". Statements must be - * enclosed into additional "()". Example: - * - * #define TRANSPORT_LOG_MESSAGE_CTX_FORMAT \ - * (F_INIT(( struct rusage f_ru; getrusage(RUSAGE_SELF, &f_ru); )), \ - * YEAR, S("."), MONTH, S("."), DAY, S(" "), \ - * F_UINT(5, f_ru.ru_nsignals), \ - * S(" ")) - * - * F_UINT(width, value) adds unsigned integer value extended with up to width - * spaces (for alignment purposes). Value can be any expression that evaluates - * to unsigned integer. If expression contains non-standard functions, they - * must be declared with F_INIT(). Example: - * - * #define TRANSPORT_LOG_MESSAGE_CTX_FORMAT \ - * (YEAR, S("."), MONTH, S("."), DAY, S(" "), \ - * F_INIT(( unsigned tickcount(); )), \ - * F_UINT(5, tickcount()), \ - * S(" ")) - * - * Other log message format specifications follow same rules, but have a - * different set of supported fields. - */ -#ifndef TRANSPORT_LOG_MESSAGE_CTX_FORMAT -#define TRANSPORT_LOG_MESSAGE_CTX_FORMAT \ - (MONTH, S("-"), DAY, S(TRANSPORT_LOG_DEF_DELIMITER), HOUR, S(":"), MINUTE, \ - S(":"), SECOND, S("."), MILLISECOND, S(TRANSPORT_LOG_DEF_DELIMITER), PID, \ - S(TRANSPORT_LOG_DEF_DELIMITER), TID, S(TRANSPORT_LOG_DEF_DELIMITER), LEVEL, \ - S(TRANSPORT_LOG_DEF_DELIMITER)) -#endif -/* Example: - */ -/* Specifies log message tag format. It includes tag prefix and tag. Custom - * information can be added as well. Supported fields: - * TAG(prefix_delimiter, tag_delimiter), S(str), F_INIT(statements), - * F_UINT(width, value). - * - * TAG(prefix_delimiter, tag_delimiter) adds following string to log message: - * - * PREFIX<prefix_delimiter>TAG<tag_delimiter> - * - * Prefix delimiter will be used only when prefix is not empty. Tag delimiter - * will be used only when prefixed tag is not empty. Example: - * - * #define TRANSPORT_LOG_TAG_FORMAT (S("["), TAG(".", ""), S("] ")) - * - * See TRANSPORT_LOG_MESSAGE_CTX_FORMAT for details. - */ -#ifndef TRANSPORT_LOG_MESSAGE_TAG_FORMAT -#define TRANSPORT_LOG_MESSAGE_TAG_FORMAT (TAG(".", TRANSPORT_LOG_DEF_DELIMITER)) -#endif -/* Specifies log message source location format. It includes function name, - * file name and file line. Custom information can be added as well. Supported - * fields: FUNCTION, FILENAME, FILELINE, S(str), F_INIT(statements), - * F_UINT(width, value). - * - * See TRANSPORT_LOG_MESSAGE_CTX_FORMAT for details. - */ -#ifndef TRANSPORT_LOG_MESSAGE_SRC_FORMAT -#define TRANSPORT_LOG_MESSAGE_SRC_FORMAT \ - (FUNCTION, S("@"), FILENAME, S(":"), FILELINE, S(TRANSPORT_LOG_DEF_DELIMITER)) -#endif -/* Fields that can be used in log message format specifications (see above). - * Mentioning them here explicitly, so we know that nobody else defined them - * before us. See TRANSPORT_LOG_MESSAGE_CTX_FORMAT for details. - */ -#define YEAR YEAR -#define MONTH MONTH -#define DAY DAY -#define MINUTE MINUTE -#define SECOND SECOND -#define MILLISECOND MILLISECOND -#define PID PID -#define TID TID -#define LEVEL LEVEL -#define TAG(prefix_delim, tag_delim) TAG(prefix_delim, tag_delim) -#define FUNCTION FUNCTION -#define FILENAME FILENAME -#define FILELINE FILELINE -#define S(str) S(str) -#define F_INIT(statements) F_INIT(statements) -#define F_UINT(width, value) F_UINT(width, value) -/* Number of bytes to reserve for EOL in the log line buffer (must be >0). - * Must be larger than or equal to length of TRANSPORT_LOG_EOL with terminating - * null. - */ -#ifndef TRANSPORT_LOG_EOL_SZ -#define TRANSPORT_LOG_EOL_SZ sizeof(TRANSPORT_LOG_EOL) -#endif -/* Compile instrumented version of the library to facilitate unit testing. - */ -#ifndef TRANSPORT_LOG_INSTRUMENTED -#define TRANSPORT_LOG_INSTRUMENTED 0 -#endif - -#if defined(__linux__) -#if !defined(__ANDROID__) && !defined(_GNU_SOURCE) -#define _GNU_SOURCE -#endif -#endif -#if defined(__MINGW32__) -#ifdef __STRICT_ANSI__ -#undef __STRICT_ANSI__ -#endif -#endif - -#include <assert.h> -#include <ctype.h> -#include <hicn/transport/utils/log.h> -#include <stdarg.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#if defined(_WIN32) || defined(_WIN64) -#include <windows.h> -#else -#include <sys/time.h> -#include <unistd.h> -#if defined(__linux__) -#include <linux/limits.h> -#else -#include <sys/syslimits.h> -#endif -#endif - -#if defined(__linux__) -#include <sys/prctl.h> -#include <sys/types.h> -#if !defined(__ANDROID__) -#include <sys/syscall.h> -#endif -#endif -#if defined(__MACH__) -#include <pthread.h> -#endif - -#define INLINE _TRANSPORT_LOG_INLINE -#define VAR_UNUSED(var) (void)var -#define RETVAL_UNUSED(expr) \ - do { \ - while (expr) break; \ - } while (0) -#define STATIC_ASSERT(name, cond) typedef char assert_##name[(cond) ? 1 : -1] -#define ASSERT_UNREACHABLE(why) assert(!sizeof(why)) -#ifndef _countof -#define _countof(xs) (sizeof(xs) / sizeof((xs)[0])) -#endif - -#if TRANSPORT_LOG_INSTRUMENTED -#define INSTRUMENTED_CONST -#else -#define INSTRUMENTED_CONST const -#endif - -#define _PP_PASTE_2(a, b) a##b -#define _PP_CONCAT_2(a, b) _PP_PASTE_2(a, b) - -#define _PP_PASTE_3(a, b, c) a##b##c -#define _PP_CONCAT_3(a, b, c) _PP_PASTE_3(a, b, c) - -/* Microsoft C preprocessor is a piece of shit. This moron treats __VA_ARGS__ - * as a single token and requires additional expansion to realize that it's - * actually a list. If not for it, there would be no need in this extra - * expansion. - */ -#define _PP_ID(x) x -#define _PP_NARGS_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \ - _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, \ - _24, ...) \ - _24 -#define _PP_NARGS(...) \ - _PP_ID(_PP_NARGS_N(__VA_ARGS__, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, \ - 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) - -/* There is a more efficient way to implement this, but it requires - * working C preprocessor. Unfortunately, Microsoft Visual Studio doesn't - * have one. - */ -#define _PP_HEAD__(x, ...) x -#define _PP_HEAD_(...) _PP_ID(_PP_HEAD__(__VA_ARGS__, ~)) -#define _PP_HEAD(xs) _PP_HEAD_ xs -#define _PP_TAIL_(x, ...) (__VA_ARGS__) -#define _PP_TAIL(xs) _PP_TAIL_ xs -#define _PP_UNTUPLE_(...) __VA_ARGS__ -#define _PP_UNTUPLE(xs) _PP_UNTUPLE_ xs - -/* Apply function macro to each element in tuple. Output is not - * enforced to be a tuple. - */ -#define _PP_MAP_1(f, xs) f(_PP_HEAD(xs)) -#define _PP_MAP_2(f, xs) f(_PP_HEAD(xs)) _PP_MAP_1(f, _PP_TAIL(xs)) -#define _PP_MAP_3(f, xs) f(_PP_HEAD(xs)) _PP_MAP_2(f, _PP_TAIL(xs)) -#define _PP_MAP_4(f, xs) f(_PP_HEAD(xs)) _PP_MAP_3(f, _PP_TAIL(xs)) -#define _PP_MAP_5(f, xs) f(_PP_HEAD(xs)) _PP_MAP_4(f, _PP_TAIL(xs)) -#define _PP_MAP_6(f, xs) f(_PP_HEAD(xs)) _PP_MAP_5(f, _PP_TAIL(xs)) -#define _PP_MAP_7(f, xs) f(_PP_HEAD(xs)) _PP_MAP_6(f, _PP_TAIL(xs)) -#define _PP_MAP_8(f, xs) f(_PP_HEAD(xs)) _PP_MAP_7(f, _PP_TAIL(xs)) -#define _PP_MAP_9(f, xs) f(_PP_HEAD(xs)) _PP_MAP_8(f, _PP_TAIL(xs)) -#define _PP_MAP_10(f, xs) f(_PP_HEAD(xs)) _PP_MAP_9(f, _PP_TAIL(xs)) -#define _PP_MAP_11(f, xs) f(_PP_HEAD(xs)) _PP_MAP_10(f, _PP_TAIL(xs)) -#define _PP_MAP_12(f, xs) f(_PP_HEAD(xs)) _PP_MAP_11(f, _PP_TAIL(xs)) -#define _PP_MAP_13(f, xs) f(_PP_HEAD(xs)) _PP_MAP_12(f, _PP_TAIL(xs)) -#define _PP_MAP_14(f, xs) f(_PP_HEAD(xs)) _PP_MAP_13(f, _PP_TAIL(xs)) -#define _PP_MAP_15(f, xs) f(_PP_HEAD(xs)) _PP_MAP_14(f, _PP_TAIL(xs)) -#define _PP_MAP_16(f, xs) f(_PP_HEAD(xs)) _PP_MAP_15(f, _PP_TAIL(xs)) -#define _PP_MAP_17(f, xs) f(_PP_HEAD(xs)) _PP_MAP_16(f, _PP_TAIL(xs)) -#define _PP_MAP_18(f, xs) f(_PP_HEAD(xs)) _PP_MAP_17(f, _PP_TAIL(xs)) -#define _PP_MAP_19(f, xs) f(_PP_HEAD(xs)) _PP_MAP_18(f, _PP_TAIL(xs)) -#define _PP_MAP_20(f, xs) f(_PP_HEAD(xs)) _PP_MAP_19(f, _PP_TAIL(xs)) -#define _PP_MAP_21(f, xs) f(_PP_HEAD(xs)) _PP_MAP_20(f, _PP_TAIL(xs)) -#define _PP_MAP_22(f, xs) f(_PP_HEAD(xs)) _PP_MAP_21(f, _PP_TAIL(xs)) -#define _PP_MAP_23(f, xs) f(_PP_HEAD(xs)) _PP_MAP_22(f, _PP_TAIL(xs)) -#define _PP_MAP_24(f, xs) f(_PP_HEAD(xs)) _PP_MAP_23(f, _PP_TAIL(xs)) -#define _PP_MAP(f, xs) _PP_CONCAT_2(_PP_MAP_, _PP_NARGS xs)(f, xs) - -/* Apply function macro to each element in tuple in reverse order. - * Output is not enforced to be a tuple. - */ -#define _PP_RMAP_1(f, xs) f(_PP_HEAD(xs)) -#define _PP_RMAP_2(f, xs) _PP_RMAP_1(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_3(f, xs) _PP_RMAP_2(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_4(f, xs) _PP_RMAP_3(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_5(f, xs) _PP_RMAP_4(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_6(f, xs) _PP_RMAP_5(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_7(f, xs) _PP_RMAP_6(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_8(f, xs) _PP_RMAP_7(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_9(f, xs) _PP_RMAP_8(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_10(f, xs) _PP_RMAP_9(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_11(f, xs) _PP_RMAP_10(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_12(f, xs) _PP_RMAP_11(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_13(f, xs) _PP_RMAP_12(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_14(f, xs) _PP_RMAP_13(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_15(f, xs) _PP_RMAP_14(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_16(f, xs) _PP_RMAP_15(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_17(f, xs) _PP_RMAP_16(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_18(f, xs) _PP_RMAP_17(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_19(f, xs) _PP_RMAP_18(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_20(f, xs) _PP_RMAP_19(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_21(f, xs) _PP_RMAP_20(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_22(f, xs) _PP_RMAP_21(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_23(f, xs) _PP_RMAP_22(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP_24(f, xs) _PP_RMAP_23(f, _PP_TAIL(xs)) f(_PP_HEAD(xs)) -#define _PP_RMAP(f, xs) _PP_CONCAT_2(_PP_RMAP_, _PP_NARGS xs)(f, xs) - -/* Used to implement _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS() macro. All - * possible fields must be mentioned here. Not counting F_INIT() here because - * it's somewhat special and is handled spearatly (at least for now). - */ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__ (0 << 0) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__YEAR (1 << 1) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__MONTH (1 << 2) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__DAY (1 << 3) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__HOUR (1 << 4) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__MINUTE (1 << 5) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__SECOND (1 << 6) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__MILLISECOND (1 << 7) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__PID (1 << 8) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__TID (1 << 9) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__LEVEL (1 << 10) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__TAG(ps, ts) (1 << 11) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__FUNCTION (1 << 12) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__FILENAME (1 << 13) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__FILELINE (1 << 14) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__S(s) (1 << 15) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__F_INIT(expr) (0 << 16) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK__F_UINT(w, v) (1 << 17) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_MASK(field) \ - _PP_CONCAT_3(_TRANSPORT_LOG_MESSAGE_FORMAT_MASK_, _, field) - -/* Logical "or" of masks of fields used in specified format specification. - */ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_FIELDS(format) \ - (0 _PP_MAP(| _TRANSPORT_LOG_MESSAGE_FORMAT_MASK, format)) - -/* Expands to expressions that evaluates to true if field is used in - * specified format specification. Example: - * - * #if _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(F_UINT, - * TRANSPORT_LOG_MESSAGE_CTX_FORMAT) - * ... - * #endif - */ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(field, format) \ - (_TRANSPORT_LOG_MESSAGE_FORMAT_MASK(field) & \ - _TRANSPORT_LOG_MESSAGE_FORMAT_FIELDS(format)) - -/* Same, but checks all supported format specifications. - */ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_FIELD_USED(field) \ - (_TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(field, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) || \ - _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(field, \ - TRANSPORT_LOG_MESSAGE_TAG_FORMAT) || \ - _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(field, \ - TRANSPORT_LOG_MESSAGE_SRC_FORMAT)) - -#define _TRANSPORT_LOG_MESSAGE_FORMAT_DATETIME_USED \ - (_TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(YEAR, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) || \ - _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(MONTH, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) || \ - _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(DAY, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) || \ - _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(HOUR, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) || \ - _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(MINUTE, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) || \ - _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(SECOND, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) || \ - _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(MILLISECOND, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT)) - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) -#pragma warning(disable : 4204) /* nonstandard extension used: non-constant \ - aggregate initializer */ -#define memccpy _memccpy -#endif - -#if (defined(_MSC_VER) && !defined(__INTEL_COMPILER)) || defined(__MINGW64__) -#define vsnprintf(s, sz, fmt, va) fake_vsnprintf(s, sz, fmt, va) -static int fake_vsnprintf(char *s, size_t sz, const char *fmt, va_list ap) { - const int n = vsnprintf_s(s, sz, _TRUNCATE, fmt, ap); - return 0 < n ? n : (int)sz + 1; /* no need in _vscprintf() for now */ -} -#if TRANSPORT_LOG_OPTIMIZE_SIZE -#define snprintf(s, sz, ...) fake_snprintf(s, sz, __VA_ARGS__) -static int fake_snprintf(char *s, size_t sz, const char *fmt, ...) { - va_list va; - va_start(va, fmt); - const int n = fake_vsnprintf(s, sz, fmt, va); - va_end(va); - return n; -} -#endif -#endif - -typedef void (*time_cb)(struct tm *const tm, unsigned *const usec); -typedef void (*pid_cb)(int *const pid, int *const tid); -typedef void (*buffer_cb)(transport_log_message *msg, char *buf); - -typedef struct src_location { - const char *const func; - const char *const file; - const unsigned line; -} src_location; - -typedef struct mem_block { - const void *const d; - const unsigned d_sz; -} mem_block; - -static void time_callback(struct tm *const tm, unsigned *const usec); -static void pid_callback(int *const pid, int *const tid); -static void buffer_callback(transport_log_message *msg, char *buf); - -STATIC_ASSERT(eol_fits_eol_sz, - sizeof(TRANSPORT_LOG_EOL) <= TRANSPORT_LOG_EOL_SZ); -STATIC_ASSERT(eol_sz_greater_than_zero, 0 < TRANSPORT_LOG_EOL_SZ); -STATIC_ASSERT(eol_sz_less_than_buf_sz, - TRANSPORT_LOG_EOL_SZ < TRANSPORT_LOG_BUF_SZ); -#if !defined(_WIN32) && !defined(_WIN64) -STATIC_ASSERT(buf_sz_less_than_pipe_buf, TRANSPORT_LOG_BUF_SZ <= PIPE_BUF); -#endif -static const char c_hex[] = "0123456789abcdef"; - -static INSTRUMENTED_CONST unsigned g_buf_sz = - TRANSPORT_LOG_BUF_SZ - TRANSPORT_LOG_EOL_SZ; -static INSTRUMENTED_CONST time_cb g_time_cb = time_callback; -static INSTRUMENTED_CONST pid_cb g_pid_cb = pid_callback; -static INSTRUMENTED_CONST buffer_cb g_buffer_cb = buffer_callback; - -#if TRANSPORT_LOG_USE_ANDROID_LOG -#include <android/log.h> - -static INLINE int android_lvl(const int lvl) { - switch (lvl) { - case TRANSPORT_LOG_VERBOSE: - return ANDROID_LOG_VERBOSE; - case TRANSPORT_LOG_DEBUG: - return ANDROID_LOG_DEBUG; - case TRANSPORT_LOG_INFO: - return ANDROID_LOG_INFO; - case TRANSPORT_LOG_WARN: - return ANDROID_LOG_WARN; - case TRANSPORT_LOG_ERROR: - return ANDROID_LOG_ERROR; - case TRANSPORT_LOG_FATAL: - return ANDROID_LOG_FATAL; - default: - ASSERT_UNREACHABLE("Bad log level"); - return ANDROID_LOG_UNKNOWN; - } -} - -static void out_android_callback(const transport_log_message *const msg, - void *arg) { - VAR_UNUSED(arg); - *msg->p = 0; - const char *tag = msg->p; - if (msg->tag_e != msg->tag_b) { - tag = msg->tag_b; - *msg->tag_e = 0; - } - __android_log_print(android_lvl(msg->lvl), ANDROID_TAG, "%s", msg->msg_b); -} - -enum { OUT_ANDROID_MASK = TRANSPORT_LOG_PUT_STD & ~TRANSPORT_LOG_PUT_CTX }; -#define OUT_ANDROID OUT_ANDROID_MASK, 0, out_android_callback -#endif - -#if TRANSPORT_LOG_USE_NSLOG -#include <CoreFoundation/CoreFoundation.h> -CF_EXPORT void CFLog(int32_t level, CFStringRef format, ...); - -static INLINE int apple_lvl(const int lvl) { - switch (lvl) { - case TRANSPORT_LOG_VERBOSE: - return 7; /* ASL_LEVEL_DEBUG / kCFLogLevelDebug */ - ; - case TRANSPORT_LOG_DEBUG: - return 7; /* ASL_LEVEL_DEBUG / kCFLogLevelDebug */ - ; - case TRANSPORT_LOG_INFO: - return 6; /* ASL_LEVEL_INFO / kCFLogLevelInfo */ - ; - case TRANSPORT_LOG_WARN: - return 4; /* ASL_LEVEL_WARNING / kCFLogLevelWarning */ - ; - case TRANSPORT_LOG_ERROR: - return 3; /* ASL_LEVEL_ERR / kCFLogLevelError */ - ; - case TRANSPORT_LOG_FATAL: - return 0; /* ASL_LEVEL_EMERG / kCFLogLevelEmergency */ - ; - default: - ASSERT_UNREACHABLE("Bad log level"); - return 0; /* ASL_LEVEL_EMERG / kCFLogLevelEmergency */ - ; - } -} - -static void out_nslog_callback(const transport_log_message *const msg, - void *arg) { - VAR_UNUSED(arg); - *msg->p = 0; - CFLog(apple_lvl(msg->lvl), CFSTR("%s"), msg->tag_b); -} - -enum { OUT_NSLOG_MASK = TRANSPORT_LOG_PUT_STD & ~TRANSPORT_LOG_PUT_CTX }; -#define OUT_NSLOG OUT_NSLOG_MASK, 0, out_nslog_callback -#endif - -#if TRANSPORT_LOG_USE_DEBUGSTRING -#include <windows.h> - -static void out_debugstring_callback(const transport_log_message *const msg, - void *arg) { - VAR_UNUSED(arg); - msg->p[0] = '\n'; - msg->p[1] = '\0'; - OutputDebugStringA(msg->buf); -} - -enum { OUT_DEBUGSTRING_MASK = TRANSPORT_LOG_PUT_STD }; -#define OUT_DEBUGSTRING OUT_DEBUGSTRING_MASK, 0, out_debugstring_callback -#endif - -void transport_log_out_stderr_callback(const transport_log_message *const msg, - void *arg) { - VAR_UNUSED(arg); - const size_t eol_len = sizeof(TRANSPORT_LOG_EOL) - 1; - memcpy(msg->p, TRANSPORT_LOG_EOL, eol_len); -#if defined(_WIN32) || defined(_WIN64) - /* WriteFile() is atomic for local files opened with FILE_APPEND_DATA and - without FILE_WRITE_DATA */ - DWORD written; - WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg->buf, - (DWORD)(msg->p - msg->buf + eol_len), &written, 0); -#else - /* write() is atomic for buffers less than or equal to PIPE_BUF. */ - RETVAL_UNUSED( - write(STDERR_FILENO, msg->buf, (size_t)(msg->p - msg->buf) + eol_len)); -#endif -} - -static const transport_log_output out_stderr = {TRANSPORT_LOG_OUT_STDERR}; - -#if !TRANSPORT_LOG_EXTERN_TAG_PREFIX -TRANSPORT_LOG_DEFINE_TAG_PREFIX = 0; -#endif - -#if !TRANSPORT_LOG_EXTERN_GLOBAL_FORMAT -TRANSPORT_LOG_DEFINE_GLOBAL_FORMAT = {TRANSPORT_LOG_MEM_WIDTH}; -#endif - -#if !TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT -#if TRANSPORT_LOG_USE_ANDROID_LOG -TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT = {OUT_ANDROID}; -#elif TRANSPORT_LOG_USE_NSLOG -TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT = {OUT_NSLOG}; -#elif TRANSPORT_LOG_USE_DEBUGSTRING -TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT = {OUT_DEBUGSTRING}; -#else -TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT = {TRANSPORT_LOG_OUT_STDERR}; -#endif -#endif - -#if !TRANSPORT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL -TRANSPORT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL = 0; -#endif - -const transport_log_spec _transport_log_stderr_spec = { - TRANSPORT_LOG_GLOBAL_FORMAT, - &out_stderr, -}; - -static const transport_log_spec global_spec = { - TRANSPORT_LOG_GLOBAL_FORMAT, - TRANSPORT_LOG_GLOBAL_OUTPUT, -}; - -#if _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(LEVEL, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) -static char lvl_char(const int lvl) { - switch (lvl) { - case TRANSPORT_LOG_VERBOSE: - return 'V'; - case TRANSPORT_LOG_DEBUG: - return 'D'; - case TRANSPORT_LOG_INFO: - return 'I'; - case TRANSPORT_LOG_WARN: - return 'W'; - case TRANSPORT_LOG_ERROR: - return 'E'; - case TRANSPORT_LOG_FATAL: - return 'F'; - default: - ASSERT_UNREACHABLE("Bad log level"); - return '?'; - } -} -#endif - -#define GCCVER_LESS(MAJOR, MINOR, PATCH) \ - (__GNUC__ < MAJOR || (__GNUC__ == MAJOR && (__GNUC_MINOR__ < MINOR || \ - (__GNUC_MINOR__ == MINOR && \ - __GNUC_PATCHLEVEL__ < PATCH)))) - -#if !defined(__clang__) && defined(__GNUC__) && GCCVER_LESS(4, 7, 0) -#define __atomic_load_n(vp, model) __sync_fetch_and_add(vp, 0) -#define __atomic_fetch_add(vp, n, model) __sync_fetch_and_add(vp, n) -#define __atomic_sub_fetch(vp, n, model) __sync_sub_and_fetch(vp, n) -#define __atomic_or_fetch(vp, n, model) __sync_or_and_fetch(vp, n) -#define __atomic_and_fetch(vp, n, model) __sync_and_and_fetch(vp, n) -/* Note: will not store old value of *vp in *ep (non-standard behaviour) */ -#define __atomic_compare_exchange_n(vp, ep, d, weak, smodel, fmodel) \ - __sync_bool_compare_and_swap(vp, *(ep), d) -#endif - -#if !TRANSPORT_LOG_OPTIMIZE_SIZE && !defined(_WIN32) && !defined(_WIN64) -#define TCACHE -#define TCACHE_STALE (0x40000000) -#define TCACHE_FLUID (0x40000000 | 0x80000000) -static unsigned g_tcache_mode = TCACHE_STALE; -static struct timeval g_tcache_tv = {0, 0}; -static struct tm g_tcache_tm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -static INLINE int tcache_get(const struct timeval *const tv, - struct tm *const tm) { - unsigned mode; - mode = __atomic_load_n(&g_tcache_mode, __ATOMIC_RELAXED); - if (0 == (mode & TCACHE_FLUID)) { - mode = __atomic_fetch_add(&g_tcache_mode, 1, __ATOMIC_ACQUIRE); - if (0 == (mode & TCACHE_FLUID)) { - if (g_tcache_tv.tv_sec == tv->tv_sec) { - *tm = g_tcache_tm; - __atomic_sub_fetch(&g_tcache_mode, 1, __ATOMIC_RELEASE); - return !0; - } - __atomic_or_fetch(&g_tcache_mode, TCACHE_STALE, __ATOMIC_RELAXED); - } - __atomic_sub_fetch(&g_tcache_mode, 1, __ATOMIC_RELEASE); - } - return 0; -} - -static INLINE void tcache_set(const struct timeval *const tv, - struct tm *const tm) { - unsigned stale = TCACHE_STALE; - if (__atomic_compare_exchange_n(&g_tcache_mode, &stale, TCACHE_FLUID, 0, - __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { - g_tcache_tv = *tv; - g_tcache_tm = *tm; - __atomic_and_fetch(&g_tcache_mode, ~TCACHE_FLUID, __ATOMIC_RELEASE); - } -} -#endif - -static void time_callback(struct tm *const tm, unsigned *const msec) { -#if !_TRANSPORT_LOG_MESSAGE_FORMAT_DATETIME_USED - VAR_UNUSED(tm); - VAR_UNUSED(msec); -#else -#if defined(_WIN32) || defined(_WIN64) - SYSTEMTIME st; - GetLocalTime(&st); - tm->tm_year = st.wYear; - tm->tm_mon = st.wMonth - 1; - tm->tm_mday = st.wDay; - tm->tm_wday = st.wDayOfWeek; - tm->tm_hour = st.wHour; - tm->tm_min = st.wMinute; - tm->tm_sec = st.wSecond; - *msec = st.wMilliseconds; -#else - struct timeval tv; - gettimeofday(&tv, 0); -#ifndef TCACHE - localtime_r(&tv.tv_sec, tm); -#else - if (!tcache_get(&tv, tm)) { - localtime_r(&tv.tv_sec, tm); - tcache_set(&tv, tm); - } -#endif - *msec = (unsigned)tv.tv_usec / 1000; -#endif -#endif -} - -static void pid_callback(int *const pid, int *const tid) { -#if !_TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(PID, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) - VAR_UNUSED(pid); -#else -#if defined(_WIN32) || defined(_WIN64) - *pid = GetCurrentProcessId(); -#else - *pid = getpid(); -#endif -#endif - -#if !_TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(TID, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) - VAR_UNUSED(tid); -#else -#if defined(_WIN32) || defined(_WIN64) - *tid = GetCurrentThreadId(); -#elif defined(__ANDROID__) - *tid = gettid(); -#elif defined(__linux__) - *tid = syscall(SYS_gettid); -#elif defined(__MACH__) - *tid = (int)pthread_mach_thread_np(pthread_self()); -#else -#define Platform not supported -#endif -#endif -} - -static void buffer_callback(transport_log_message *msg, char *buf) { - msg->e = (msg->p = msg->buf = buf) + g_buf_sz; -} - -#if _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(FUNCTION, \ - TRANSPORT_LOG_MESSAGE_SRC_FORMAT) -static const char *funcname(const char *func) { return func ? func : ""; } -#endif - -#if _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(FILENAME, \ - TRANSPORT_LOG_MESSAGE_SRC_FORMAT) -static const char *filename(const char *file) { - const char *f = file; - for (const char *p = file; 0 != *p; ++p) { - if ('/' == *p || '\\' == *p) { - f = p + 1; - } - } - return f; -} -#endif - -static INLINE size_t nprintf_size(transport_log_message *const msg) { - // *nprintf() always puts 0 in the end when input buffer is not empty. This - // 0 is not desired because its presence sets (ctx->p) to (ctx->e - 1) which - // leaves space for one more character. Some put_xxx() functions don't use - // *nprintf() and could use that last character. In that case log line will - // have multiple (two) half-written parts which is confusing. To workaround - // that we allow *nprintf() to write its 0 in the eol area (which is always - // not empty). - return (size_t)(msg->e - msg->p + 1); -} - -static INLINE void put_nprintf(transport_log_message *const msg, const int n) { - if (0 < n) { - msg->p = n < msg->e - msg->p ? msg->p + n : msg->e; - } -} - -static INLINE char *put_padding_r(const unsigned w, const char wc, char *p, - char *e) { - for (char *const b = e - w; b < p; *--p = wc) { - } - return p; -} - -static char *put_integer_r(unsigned v, const int sign, const unsigned w, - const char wc, char *const e) { - static const char _signs[] = {'-', '0', '+'}; - static const char *const signs = _signs + 1; - char *p = e; - do { - *--p = '0' + v % 10; - } while (0 != (v /= 10)); - if (0 == sign) return put_padding_r(w, wc, p, e); - if ('0' != wc) { - *--p = signs[sign]; - return put_padding_r(w, wc, p, e); - } - p = put_padding_r(w, wc, p, e + 1); - *--p = signs[sign]; - return p; -} - -static INLINE char *put_uint_r(const unsigned v, const unsigned w, - const char wc, char *const e) { - return put_integer_r(v, 0, w, wc, e); -} - -static INLINE char *put_int_r(const int v, const unsigned w, const char wc, - char *const e) { - return 0 <= v ? put_integer_r((unsigned)v, 0, w, wc, e) - : put_integer_r((unsigned)-v, -1, w, wc, e); -} - -static INLINE char *put_stringn(const char *const s_p, const char *const s_e, - char *const p, char *const e) { - const ptrdiff_t m = e - p; - ptrdiff_t n = s_e - s_p; - if (n > m) { - n = m; - } - memcpy(p, s_p, n); - return p + n; -} - -static INLINE char *put_string(const char *s, char *p, char *const e) { - const ptrdiff_t n = e - p; - char *const c = (char *)memccpy(p, s, '\0', n); - return 0 != c ? c - 1 : e; -} - -static INLINE char *put_uint(unsigned v, const unsigned w, const char wc, - char *const p, char *const e) { - char buf[16]; - char *const se = buf + _countof(buf); - char *sp = put_uint_r(v, w, wc, se); - return put_stringn(sp, se, p, e); -} - -#define PUT_CSTR_R(p, STR) \ - do { \ - for (unsigned i = sizeof(STR) - 1; 0 < i--;) { \ - *--(p) = (STR)[i]; \ - } \ - } \ - _TRANSPORT_LOG_ONCE - -#define PUT_CSTR_CHECKED(p, e, STR) \ - do { \ - for (unsigned i = 0; (e) > (p) && (sizeof(STR) - 1) > i; ++i) { \ - *(p)++ = (STR)[i]; \ - } \ - } \ - _TRANSPORT_LOG_ONCE - -/* F_INIT field support. - */ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__YEAR -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__MONTH -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__DAY -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__HOUR -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__MINUTE -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__SECOND -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__MILLISECOND -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__PID -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__TID -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__LEVEL -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__TAG(ps, ts) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__FUNCTION -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__FILENAME -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__FILELINE -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__S(s) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__F_INIT(expr) _PP_UNTUPLE(expr); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT__F_UINT(w, v) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_INIT(field) \ - _PP_CONCAT_3(_TRANSPORT_LOG_MESSAGE_FORMAT_INIT_, _, field) - -/* Implements generation of printf-like format string for log message - * format specification. - */ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__ "" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__YEAR "%04u" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__MONTH "%02u" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__DAY "%02u" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__HOUR "%02u" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__MINUTE "%02u" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__SECOND "%02u" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__MILLISECOND "%03u" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__PID "%5i" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__TID "%5i" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__LEVEL "%c" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__TAG UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__FUNCTION "%s" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__FILENAME "%s" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__FILELINE "%u" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__S(s) s -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__F_INIT(expr) "" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT__F_UINT(w, v) "%" #w "u" -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT(field) \ - _PP_CONCAT_3(_TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT_, _, field) - -/* Implements generation of printf-like format parameters for log message - * format specification. - */ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__YEAR \ - , (unsigned)(tm.tm_year + 1900) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__MONTH \ - , (unsigned)(tm.tm_mon + 1) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__DAY , (unsigned)tm.tm_mday -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__HOUR , (unsigned)tm.tm_hour -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__MINUTE , (unsigned)tm.tm_min -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__SECOND , (unsigned)tm.tm_sec -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__MILLISECOND , (unsigned)msec -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__PID , pid -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__TID , tid -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__LEVEL \ - , (char)lvl_char(msg->lvl) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__TAG UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__FUNCTION , funcname(src->func) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__FILENAME , filename(src->file) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__FILELINE , src->line -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__S(s) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__F_INIT(expr) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL__F_UINT(w, v) , v -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL(field) \ - _PP_CONCAT_3(_TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL_, _, field) - -/* Implements generation of put_xxx_t statements for log message specification. - */ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__YEAR \ - p = put_uint_r(tm.tm_year + 1900, 4, '0', p); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__MONTH \ - p = put_uint_r((unsigned)tm.tm_mon + 1, 2, '0', p); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__DAY \ - p = put_uint_r((unsigned)tm.tm_mday, 2, '0', p); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__HOUR \ - p = put_uint_r((unsigned)tm.tm_hour, 2, '0', p); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__MINUTE \ - p = put_uint_r((unsigned)tm.tm_min, 2, '0', p); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__SECOND \ - p = put_uint_r((unsigned)tm.tm_sec, 2, '0', p); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__MILLISECOND \ - p = put_uint_r(msec, 3, '0', p); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__PID p = put_int_r(pid, 5, ' ', p); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__TID p = put_int_r(tid, 5, ' ', p); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__LEVEL *--p = lvl_char(msg->lvl); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__TAG UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__FUNCTION UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__FILENAME UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__FILELINE UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__S(s) PUT_CSTR_R(p, s); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__F_INIT(expr) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R__F_UINT(w, v) \ - p = put_uint_r(v, w, ' ', p); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R(field) \ - _PP_CONCAT_3(_TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R_, _, field) - -static void put_ctx(transport_log_message *const msg) { - _PP_MAP(_TRANSPORT_LOG_MESSAGE_FORMAT_INIT, TRANSPORT_LOG_MESSAGE_CTX_FORMAT) -#if !_TRANSPORT_LOG_MESSAGE_FORMAT_FIELDS(TRANSPORT_LOG_MESSAGE_CTX_FORMAT) - VAR_UNUSED(msg); -#else -#if _TRANSPORT_LOG_MESSAGE_FORMAT_DATETIME_USED - struct tm tm; - unsigned msec; - g_time_cb(&tm, &msec); -#endif -#if _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS( \ - PID, TRANSPORT_LOG_MESSAGE_CTX_FORMAT) || \ - _TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(TID, \ - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) - int pid, tid; - g_pid_cb(&pid, &tid); -#endif - -#if TRANSPORT_LOG_OPTIMIZE_SIZE - int n; - n = snprintf(msg->p, nprintf_size(msg), - _PP_MAP(_TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT, - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) - _PP_MAP(_TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL, - TRANSPORT_LOG_MESSAGE_CTX_FORMAT)); - put_nprintf(msg, n); -#else - char buf[64]; - char *const e = buf + sizeof(buf); - char *p = e; - _PP_RMAP(_TRANSPORT_LOG_MESSAGE_FORMAT_PUT_R, - TRANSPORT_LOG_MESSAGE_CTX_FORMAT) - msg->p = put_stringn(p, e, msg->p, msg->e); -#endif -#endif -} - -#define PUT_TAG(msg, tag, prefix_delim, tag_delim) \ - do { \ - const char *ch; \ - msg->tag_b = msg->p; \ - if (0 != (ch = _transport_log_tag_prefix)) { \ - for (; msg->e != msg->p && 0 != (*msg->p = *ch); ++msg->p, ++ch) { \ - } \ - } \ - if (0 != (ch = tag) && 0 != tag[0]) { \ - if (msg->tag_b != msg->p) { \ - PUT_CSTR_CHECKED(msg->p, msg->e, prefix_delim); \ - } \ - for (; msg->e != msg->p && 0 != (*msg->p = *ch); ++msg->p, ++ch) { \ - } \ - } \ - msg->tag_e = msg->p; \ - if (msg->tag_b != msg->p) { \ - PUT_CSTR_CHECKED(msg->p, msg->e, tag_delim); \ - } \ - } \ - _TRANSPORT_LOG_ONCE - -/* Implements simple put statements for log message specification. - */ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__ -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__YEAR UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__MONTH UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__DAY UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__HOUR UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__MINUTE UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__SECOND UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__MILLISECOND UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__PID UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__TID UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__LEVEL UNDEFINED -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__TAG(pd, td) \ - PUT_TAG(msg, tag, pd, td); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__FUNCTION \ - msg->p = put_string(funcname(src->func), msg->p, msg->e); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__FILENAME \ - msg->p = put_string(filename(src->file), msg->p, msg->e); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__FILELINE \ - msg->p = put_uint(src->line, 0, '\0', msg->p, msg->e); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__S(s) \ - PUT_CSTR_CHECKED(msg->p, msg->e, s); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__F_INIT(expr) -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT__F_UINT(w, v) \ - msg->p = put_uint(v, w, ' ', msg->p, msg->e); -#define _TRANSPORT_LOG_MESSAGE_FORMAT_PUT(field) \ - _PP_CONCAT_3(_TRANSPORT_LOG_MESSAGE_FORMAT_PUT_, _, field) - -static void put_tag(transport_log_message *const msg, const char *const tag) { - _PP_MAP(_TRANSPORT_LOG_MESSAGE_FORMAT_INIT, TRANSPORT_LOG_MESSAGE_TAG_FORMAT) -#if !_TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(TAG, \ - TRANSPORT_LOG_MESSAGE_TAG_FORMAT) - VAR_UNUSED(tag); -#endif -#if !_TRANSPORT_LOG_MESSAGE_FORMAT_FIELDS(TRANSPORT_LOG_MESSAGE_TAG_FORMAT) - VAR_UNUSED(msg); -#else - _PP_MAP(_TRANSPORT_LOG_MESSAGE_FORMAT_PUT, TRANSPORT_LOG_MESSAGE_TAG_FORMAT) -#endif -} - -static void put_src(transport_log_message *const msg, - const src_location *const src) { - _PP_MAP(_TRANSPORT_LOG_MESSAGE_FORMAT_INIT, TRANSPORT_LOG_MESSAGE_SRC_FORMAT) -#if !_TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS( \ - FUNCTION, TRANSPORT_LOG_MESSAGE_SRC_FORMAT) && \ - !_TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS( \ - FILENAME, TRANSPORT_LOG_MESSAGE_SRC_FORMAT) && \ - !_TRANSPORT_LOG_MESSAGE_FORMAT_CONTAINS(FILELINE, \ - TRANSPORT_LOG_MESSAGE_SRC_FORMAT) - VAR_UNUSED(src); -#endif -#if !_TRANSPORT_LOG_MESSAGE_FORMAT_FIELDS(TRANSPORT_LOG_MESSAGE_SRC_FORMAT) - VAR_UNUSED(msg); -#else -#if TRANSPORT_LOG_OPTIMIZE_SIZE - int n; - n = snprintf(msg->p, nprintf_size(msg), - _PP_MAP(_TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_FMT, - TRANSPORT_LOG_MESSAGE_SRC_FORMAT) - _PP_MAP(_TRANSPORT_LOG_MESSAGE_FORMAT_PRINTF_VAL, - TRANSPORT_LOG_MESSAGE_SRC_FORMAT)); - put_nprintf(msg, n); -#else - _PP_MAP(_TRANSPORT_LOG_MESSAGE_FORMAT_PUT, TRANSPORT_LOG_MESSAGE_SRC_FORMAT) -#endif -#endif -} - -static void put_msg(transport_log_message *const msg, const char *const fmt, - va_list va) { - int n; - msg->msg_b = msg->p; - n = vsnprintf(msg->p, nprintf_size(msg), fmt, va); - put_nprintf(msg, n); -} - -static void output_mem(const transport_log_spec *log, - transport_log_message *const msg, - const mem_block *const mem) { - if (0 == mem->d || 0 == mem->d_sz) { - return; - } - const unsigned char *mem_p = (const unsigned char *)mem->d; - const unsigned char *const mem_e = mem_p + mem->d_sz; - const unsigned char *mem_cut; - const ptrdiff_t mem_width = (ptrdiff_t)log->format->mem_width; - char *const hex_b = msg->msg_b; - char *const ascii_b = hex_b + 2 * mem_width + 2; - char *const ascii_e = ascii_b + mem_width; - if (msg->e < ascii_e) { - return; - } - while (mem_p != mem_e) { - char *hex = hex_b; - char *ascii = ascii_b; - for (mem_cut = mem_width < mem_e - mem_p ? mem_p + mem_width : mem_e; - mem_cut != mem_p; ++mem_p) { - const unsigned char ch = *mem_p; - *hex++ = c_hex[(0xf0 & ch) >> 4]; - *hex++ = c_hex[(0x0f & ch)]; - *ascii++ = isprint(ch) ? (char)ch : '?'; - } - while (hex != ascii_b) { - *hex++ = ' '; - } - msg->p = ascii; - log->output->callback(msg, log->output->arg); - } -} - -void transport_log_set_tag_prefix(const char *const prefix) { - _transport_log_tag_prefix = prefix; -} - -void transport_log_set_mem_width(const unsigned w) { - _transport_log_global_format.mem_width = w; -} - -void transport_log_set_output_level(const int lvl) { - _transport_log_global_output_lvl = lvl; -} - -void transport_log_set_output_v(const unsigned mask, void *const arg, - const transport_log_output_cb callback) { - _transport_log_global_output.mask = mask; - _transport_log_global_output.arg = arg; - _transport_log_global_output.callback = callback; -} - -static void _transport_log_write_imp(const transport_log_spec *log, - const src_location *const src, - const mem_block *const mem, const int lvl, - const char *const tag, - const char *const fmt, va_list va) { - transport_log_message msg; - char buf[TRANSPORT_LOG_BUF_SZ]; - const unsigned mask = log->output->mask; - msg.lvl = lvl; - msg.tag = tag; - g_buffer_cb(&msg, buf); - if (TRANSPORT_LOG_PUT_CTX & mask) { - put_ctx(&msg); - } - if (TRANSPORT_LOG_PUT_TAG & mask) { - put_tag(&msg, tag); - } - if (0 != src && TRANSPORT_LOG_PUT_SRC & mask) { - put_src(&msg, src); - } - if (TRANSPORT_LOG_PUT_MSG & mask) { - put_msg(&msg, fmt, va); - } - log->output->callback(&msg, log->output->arg); - if (0 != mem && TRANSPORT_LOG_PUT_MSG & mask) { - output_mem(log, &msg, mem); - } -} - -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, ...) { - const src_location src = {func, file, line}; - va_list va; - va_start(va, fmt); - _transport_log_write_imp(&global_spec, &src, 0, lvl, tag, fmt, va); - va_end(va); -} - -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, ...) { - const src_location src = {func, file, line}; - va_list va; - va_start(va, fmt); - _transport_log_write_imp(log, &src, 0, lvl, tag, fmt, va); - va_end(va); -} - -void _transport_log_write(const int lvl, const char *const tag, - const char *const fmt, ...) { - va_list va; - va_start(va, fmt); - _transport_log_write_imp(&global_spec, 0, 0, lvl, tag, fmt, va); - va_end(va); -} - -void _transport_log_write_aux(const transport_log_spec *const log, - const int lvl, const char *const tag, - const char *const fmt, ...) { - va_list va; - va_start(va, fmt); - _transport_log_write_imp(log, 0, 0, lvl, tag, fmt, va); - va_end(va); -} - -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, - ...) { - const src_location src = {func, file, line}; - const mem_block mem = {d, d_sz}; - va_list va; - va_start(va, fmt); - _transport_log_write_imp(&global_spec, &src, &mem, lvl, tag, fmt, va); - va_end(va); -} - -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, ...) { - const src_location src = {func, file, line}; - const mem_block mem = {d, d_sz}; - va_list va; - va_start(va, fmt); - _transport_log_write_imp(log, &src, &mem, lvl, tag, fmt, va); - va_end(va); -} - -void _transport_log_write_mem(const int lvl, const char *const tag, - const void *const d, const unsigned d_sz, - const char *const fmt, ...) { - const mem_block mem = {d, d_sz}; - va_list va; - va_start(va, fmt); - _transport_log_write_imp(&global_spec, 0, &mem, lvl, tag, fmt, va); - va_end(va); -} - -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, ...) { - const mem_block mem = {d, d_sz}; - va_list va; - va_start(va, fmt); - _transport_log_write_imp(log, 0, &mem, lvl, tag, fmt, va); - va_end(va); -}
\ No newline at end of file diff --git a/libtransport/src/hicn/transport/utils/log.h b/libtransport/src/hicn/transport/utils/log.h deleted file mode 100644 index 3c4f1277a..000000000 --- a/libtransport/src/hicn/transport/utils/log.h +++ /dev/null @@ -1,1057 +0,0 @@ -/* - * 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/src/hicn/transport/utils/membuf.cc b/libtransport/src/hicn/transport/utils/membuf.cc deleted file mode 100644 index e75e85b35..000000000 --- a/libtransport/src/hicn/transport/utils/membuf.cc +++ /dev/null @@ -1,867 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * 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 - */ -#ifdef _WIN32 -#include <hicn/transport/portability/win_portability.h> -#endif - -#include <hicn/transport/utils/membuf.h> - -#include <cassert> -#include <cstddef> -#include <cstdint> -#include <cstdlib> -#include <stdexcept> -#include <vector> - -using std::unique_ptr; - -namespace { - -enum : uint16_t { - kHeapMagic = 0xa5a5, - // This memory segment contains an MemBuf that is still in use - kMemBufInUse = 0x01, - // This memory segment contains buffer data that is still in use - kDataInUse = 0x02, -}; - -enum : std::size_t { - // When create() is called for buffers less than kDefaultCombinedBufSize, - // we allocate a single combined memory segment for the MemBuf and the data - // together. See the comments for createCombined()/createSeparate() for more - // details. - // - // (The size of 1k is largely just a guess here. We could could probably do - // benchmarks of real applications to see if adjusting this number makes a - // difference. Callers that know their exact use case can also explicitly - // call createCombined() or createSeparate().) - kDefaultCombinedBufSize = 1024 -}; - -// Helper function for MemBuf::takeOwnership() -void takeOwnershipError(bool freeOnError, void* buf, - utils::MemBuf::FreeFunction freeFn, void* userData) { - if (!freeOnError) { - return; - } - if (!freeFn) { - free(buf); - return; - } - try { - freeFn(buf, userData); - } catch (...) { - // The user's free function is not allowed to throw. - // (We are already in the middle of throwing an exception, so - // we cannot let this exception go unhandled.) - abort(); - } -} - -} // namespace - -namespace utils { - -struct MemBuf::HeapPrefix { - explicit HeapPrefix(uint16_t flg) : magic(kHeapMagic), flags(flg) {} - ~HeapPrefix() { - // Reset magic to 0 on destruction. This is solely for debugging purposes - // to help catch bugs where someone tries to use HeapStorage after it has - // been deleted. - magic = 0; - } - - uint16_t magic; - std::atomic<uint16_t> flags; -}; - -struct MemBuf::HeapStorage { - HeapPrefix prefix; - // The MemBuf is last in the HeapStorage object. - // This way operator new will work even if allocating a subclass of MemBuf - // that requires more space. - utils::MemBuf buf; -}; - -struct MemBuf::HeapFullStorage { - // Make sure jemalloc allocates from the 64-byte class. Putting this here - // because HeapStorage is private so it can't be at namespace level. - static_assert(sizeof(HeapStorage) <= 64, - "MemBuf may not grow over 56 bytes!"); - - HeapStorage hs; - SharedInfo shared; - std::max_align_t align; -}; - -MemBuf::SharedInfo::SharedInfo() : freeFn(nullptr), userData(nullptr) { - // Use relaxed memory ordering here. Since we are creating a new SharedInfo, - // no other threads should be referring to it yet. - refcount.store(1, std::memory_order_relaxed); -} - -MemBuf::SharedInfo::SharedInfo(FreeFunction fn, void* arg) - : freeFn(fn), userData(arg) { - // Use relaxed memory ordering here. Since we are creating a new SharedInfo, - // no other threads should be referring to it yet. - refcount.store(1, std::memory_order_relaxed); -} - -void* MemBuf::operator new(size_t size) { - size_t fullSize = offsetof(HeapStorage, buf) + size; - auto* storage = static_cast<HeapStorage*>(malloc(fullSize)); - - new (&storage->prefix) HeapPrefix(kMemBufInUse); - return &(storage->buf); -} - -void* MemBuf::operator new(size_t /* size */, void* ptr) { return ptr; } - -void MemBuf::operator delete(void* ptr) { - auto* storageAddr = static_cast<uint8_t*>(ptr) - offsetof(HeapStorage, buf); - auto* storage = reinterpret_cast<HeapStorage*>(storageAddr); - releaseStorage(storage, kMemBufInUse); -} - -void MemBuf::operator delete(void* /* ptr */, void* /* placement */) { - // Provide matching operator for `MemBuf::new` to avoid MSVC compilation - // warning (C4291) about memory leak when exception is thrown in the - // constructor. -} - -void MemBuf::releaseStorage(HeapStorage* storage, uint16_t freeFlags) { - // Use relaxed memory order here. If we are unlucky and happen to get - // out-of-date data the compare_exchange_weak() call below will catch - // it and load new data with memory_order_acq_rel. - auto flags = storage->prefix.flags.load(std::memory_order_acquire); - - while (true) { - uint16_t newFlags = uint16_t(flags & ~freeFlags); - if (newFlags == 0) { - // The storage space is now unused. Free it. - storage->prefix.HeapPrefix::~HeapPrefix(); - free(storage); - return; - } - - // This storage segment still contains portions that are in use. - // Just clear the flags specified in freeFlags for now. - auto ret = storage->prefix.flags.compare_exchange_weak( - flags, newFlags, std::memory_order_acq_rel); - if (ret) { - // We successfully updated the flags. - return; - } - - // We failed to update the flags. Some other thread probably updated them - // and cleared some of the other bits. Continue around the loop to see if - // we are the last user now, or if we need to try updating the flags again. - } -} - -void MemBuf::freeInternalBuf(void* /* buf */, void* userData) { - auto* storage = static_cast<HeapStorage*>(userData); - releaseStorage(storage, kDataInUse); -} - -MemBuf::MemBuf(CreateOp, std::size_t capacity) - : next_(this), - prev_(this), - data_(nullptr), - length_(0), - flags_and_shared_info_(0) { - SharedInfo* info; - allocExtBuffer(capacity, &buf_, &info, &capacity_); - setSharedInfo(info); - data_ = buf_; -} - -MemBuf::MemBuf(CopyBufferOp /* op */, const void* buf, std::size_t size, - std::size_t headroom, std::size_t min_tailroom) - : MemBuf(CREATE, headroom + size + min_tailroom) { - advance(headroom); - if (size > 0) { - assert(buf != nullptr); - memcpy(writableData(), buf, size); - append(size); - } -} - -unique_ptr<MemBuf> MemBuf::create(std::size_t capacity) { - // For smaller-sized buffers, allocate the MemBuf, SharedInfo, and the buffer - // all with a single allocation. - // - // We don't do this for larger buffers since it can be wasteful if the user - // needs to reallocate the buffer but keeps using the same MemBuf object. - // In this case we can't free the data space until the MemBuf is also - // destroyed. Callers can explicitly call createCombined() or - // createSeparate() if they know their use case better, and know if they are - // likely to reallocate the buffer later. - if (capacity <= kDefaultCombinedBufSize) { - return createCombined(capacity); - } - return createSeparate(capacity); -} - -unique_ptr<MemBuf> MemBuf::createCombined(std::size_t capacity) { - // To save a memory allocation, allocate space for the MemBuf object, the - // SharedInfo struct, and the data itself all with a single call to malloc(). - size_t requiredStorage = offsetof(HeapFullStorage, align) + capacity; - size_t mallocSize = requiredStorage; - auto* storage = static_cast<HeapFullStorage*>(malloc(mallocSize)); - - new (&storage->hs.prefix) HeapPrefix(kMemBufInUse | kDataInUse); - new (&storage->shared) SharedInfo(freeInternalBuf, storage); - - uint8_t* bufAddr = reinterpret_cast<uint8_t*>(&storage->align); - uint8_t* storageEnd = reinterpret_cast<uint8_t*>(storage) + mallocSize; - size_t actualCapacity = size_t(storageEnd - bufAddr); - unique_ptr<MemBuf> ret(new (&storage->hs.buf) MemBuf( - InternalConstructor(), packFlagsAndSharedInfo(0, &storage->shared), - bufAddr, actualCapacity, bufAddr, 0)); - return ret; -} - -unique_ptr<MemBuf> MemBuf::createSeparate(std::size_t capacity) { - return std::make_unique<MemBuf>(CREATE, capacity); -} - -unique_ptr<MemBuf> MemBuf::createChain(size_t totalCapacity, - std::size_t maxBufCapacity) { - unique_ptr<MemBuf> out = - create(std::min(totalCapacity, size_t(maxBufCapacity))); - size_t allocatedCapacity = out->capacity(); - - while (allocatedCapacity < totalCapacity) { - unique_ptr<MemBuf> newBuf = create( - std::min(totalCapacity - allocatedCapacity, size_t(maxBufCapacity))); - allocatedCapacity += newBuf->capacity(); - out->prependChain(std::move(newBuf)); - } - - return out; -} - -MemBuf::MemBuf(TakeOwnershipOp, void* buf, std::size_t capacity, - std::size_t length, FreeFunction freeFn, void* userData, - bool freeOnError) - : next_(this), - prev_(this), - data_(static_cast<uint8_t*>(buf)), - buf_(static_cast<uint8_t*>(buf)), - length_(length), - capacity_(capacity), - flags_and_shared_info_( - packFlagsAndSharedInfo(flag_free_shared_info, nullptr)) { - try { - setSharedInfo(new SharedInfo(freeFn, userData)); - } catch (...) { - takeOwnershipError(freeOnError, buf, freeFn, userData); - throw; - } -} - -unique_ptr<MemBuf> MemBuf::takeOwnership(void* buf, std::size_t capacity, - std::size_t length, - FreeFunction freeFn, void* userData, - bool freeOnError) { - try { - // TODO: We could allocate the MemBuf object and SharedInfo all in a single - // memory allocation. We could use the existing HeapStorage class, and - // define a new kSharedInfoInUse flag. We could change our code to call - // releaseStorage(flag_free_shared_info) when this flag_free_shared_info, - // rather than directly calling delete. - // - // Note that we always pass freeOnError as false to the constructor. - // If the constructor throws we'll handle it below. (We have to handle - // allocation failures from std::make_unique too.) - return std::make_unique<MemBuf>(TAKE_OWNERSHIP, buf, capacity, length, - freeFn, userData, false); - } catch (...) { - takeOwnershipError(freeOnError, buf, freeFn, userData); - throw; - } -} - -MemBuf::MemBuf(WrapBufferOp, const void* buf, std::size_t capacity) noexcept - : MemBuf(InternalConstructor(), 0, - // We cast away the const-ness of the buffer here. - // This is okay since MemBuf users must use unshare() to create a - // copy of this buffer before writing to the buffer. - static_cast<uint8_t*>(const_cast<void*>(buf)), capacity, - static_cast<uint8_t*>(const_cast<void*>(buf)), capacity) {} - -unique_ptr<MemBuf> MemBuf::wrapBuffer(const void* buf, std::size_t capacity) { - return std::make_unique<MemBuf>(WRAP_BUFFER, buf, capacity); -} - -MemBuf MemBuf::wrapBufferAsValue(const void* buf, - std::size_t capacity) noexcept { - return MemBuf(WrapBufferOp::WRAP_BUFFER, buf, capacity); -} - -MemBuf::MemBuf() noexcept {} - -MemBuf::MemBuf(MemBuf&& other) noexcept - : data_(other.data_), - buf_(other.buf_), - length_(other.length_), - capacity_(other.capacity_), - flags_and_shared_info_(other.flags_and_shared_info_) { - // Reset other so it is a clean state to be destroyed. - other.data_ = nullptr; - other.buf_ = nullptr; - other.length_ = 0; - other.capacity_ = 0; - other.flags_and_shared_info_ = 0; - - // If other was part of the chain, assume ownership of the rest of its chain. - // (It's only valid to perform move assignment on the head of a chain.) - if (other.next_ != &other) { - next_ = other.next_; - next_->prev_ = this; - other.next_ = &other; - - prev_ = other.prev_; - prev_->next_ = this; - other.prev_ = &other; - } -} - -MemBuf::MemBuf(const MemBuf& other) { *this = other.cloneAsValue(); } - -MemBuf::MemBuf(InternalConstructor, uintptr_t flagsAndSharedInfo, uint8_t* buf, - std::size_t capacity, uint8_t* data, std::size_t length) noexcept - : next_(this), - prev_(this), - data_(data), - buf_(buf), - length_(length), - capacity_(capacity), - flags_and_shared_info_(flagsAndSharedInfo) { - assert(data >= buf); - assert(data + length <= buf + capacity); -} - -MemBuf::~MemBuf() { - // Destroying an MemBuf destroys the entire chain. - // Users of MemBuf should only explicitly delete the head of any chain. - // The other elements in the chain will be automatically destroyed. - while (next_ != this) { - // Since unlink() returns unique_ptr() and we don't store it, - // it will automatically delete the unlinked element. - (void)next_->unlink(); - } - - decrementRefcount(); -} - -MemBuf& MemBuf::operator=(MemBuf&& other) noexcept { - if (this == &other) { - return *this; - } - - // If we are part of a chain, delete the rest of the chain. - while (next_ != this) { - // Since unlink() returns unique_ptr() and we don't store it, - // it will automatically delete the unlinked element. - (void)next_->unlink(); - } - - // Decrement our refcount on the current buffer - decrementRefcount(); - - // Take ownership of the other buffer's data - data_ = other.data_; - buf_ = other.buf_; - length_ = other.length_; - capacity_ = other.capacity_; - flags_and_shared_info_ = other.flags_and_shared_info_; - // Reset other so it is a clean state to be destroyed. - other.data_ = nullptr; - other.buf_ = nullptr; - other.length_ = 0; - other.capacity_ = 0; - other.flags_and_shared_info_ = 0; - - // If other was part of the chain, assume ownership of the rest of its chain. - // (It's only valid to perform move assignment on the head of a chain.) - if (other.next_ != &other) { - next_ = other.next_; - next_->prev_ = this; - other.next_ = &other; - - prev_ = other.prev_; - prev_->next_ = this; - other.prev_ = &other; - } - - return *this; -} - -MemBuf& MemBuf::operator=(const MemBuf& other) { - if (this != &other) { - *this = MemBuf(other); - } - return *this; -} - -bool MemBuf::empty() const { - const MemBuf* current = this; - do { - if (current->length() != 0) { - return false; - } - current = current->next_; - } while (current != this); - return true; -} - -size_t MemBuf::countChainElements() const { - size_t numElements = 1; - for (MemBuf* current = next_; current != this; current = current->next_) { - ++numElements; - } - return numElements; -} - -std::size_t MemBuf::computeChainDataLength() const { - std::size_t fullLength = length_; - for (MemBuf* current = next_; current != this; current = current->next_) { - fullLength += current->length_; - } - return fullLength; -} - -void MemBuf::prependChain(unique_ptr<MemBuf>&& iobuf) { - // Take ownership of the specified MemBuf - MemBuf* other = iobuf.release(); - - // Remember the pointer to the tail of the other chain - MemBuf* otherTail = other->prev_; - - // Hook up prev_->next_ to point at the start of the other chain, - // and other->prev_ to point at prev_ - prev_->next_ = other; - other->prev_ = prev_; - - // Hook up otherTail->next_ to point at us, - // and prev_ to point back at otherTail, - otherTail->next_ = this; - prev_ = otherTail; -} - -unique_ptr<MemBuf> MemBuf::clone() const { - return std::make_unique<MemBuf>(cloneAsValue()); -} - -unique_ptr<MemBuf> MemBuf::cloneOne() const { - return std::make_unique<MemBuf>(cloneOneAsValue()); -} - -unique_ptr<MemBuf> MemBuf::cloneCoalesced() const { - return std::make_unique<MemBuf>(cloneCoalescedAsValue()); -} - -unique_ptr<MemBuf> MemBuf::cloneCoalescedWithHeadroomTailroom( - std::size_t new_headroom, std::size_t new_tailroom) const { - return std::make_unique<MemBuf>( - cloneCoalescedAsValueWithHeadroomTailroom(new_headroom, new_tailroom)); -} - -MemBuf MemBuf::cloneAsValue() const { - auto tmp = cloneOneAsValue(); - - for (MemBuf* current = next_; current != this; current = current->next_) { - tmp.prependChain(current->cloneOne()); - } - - return tmp; -} - -MemBuf MemBuf::cloneOneAsValue() const { - if (SharedInfo* info = sharedInfo()) { - setFlags(flag_maybe_shared); - info->refcount.fetch_add(1, std::memory_order_acq_rel); - } - return MemBuf(InternalConstructor(), flags_and_shared_info_, buf_, capacity_, - data_, length_); -} - -MemBuf MemBuf::cloneCoalescedAsValue() const { - const std::size_t new_headroom = headroom(); - const std::size_t new_tailroom = prev()->tailroom(); - return cloneCoalescedAsValueWithHeadroomTailroom(new_headroom, new_tailroom); -} - -MemBuf MemBuf::cloneCoalescedAsValueWithHeadroomTailroom( - std::size_t new_headroom, std::size_t new_tailroom) const { - if (!isChained()) { - return cloneOneAsValue(); - } - // Coalesce into newBuf - const std::size_t new_length = computeChainDataLength(); - const std::size_t new_capacity = new_length + new_headroom + new_tailroom; - MemBuf newBuf{CREATE, new_capacity}; - newBuf.advance(new_headroom); - - auto current = this; - do { - if (current->length() > 0) { - memcpy(newBuf.writableTail(), current->data(), current->length()); - newBuf.append(current->length()); - } - current = current->next(); - } while (current != this); - - return newBuf; -} - -void MemBuf::unshareOneSlow() { - // Allocate a new buffer for the data - uint8_t* buf; - SharedInfo* sharedInfo; - std::size_t actualCapacity; - allocExtBuffer(capacity_, &buf, &sharedInfo, &actualCapacity); - - // Copy the data - // Maintain the same amount of headroom. Since we maintained the same - // minimum capacity we also maintain at least the same amount of tailroom. - std::size_t headlen = headroom(); - if (length_ > 0) { - assert(data_ != nullptr); - memcpy(buf + headlen, data_, length_); - } - - // Release our reference on the old buffer - decrementRefcount(); - // Make sure flag_maybe_shared and flag_free_shared_info are all cleared. - setFlagsAndSharedInfo(0, sharedInfo); - - // Update the buffer pointers to point to the new buffer - data_ = buf + headlen; - buf_ = buf; -} - -void MemBuf::unshareChained() { - // unshareChained() should only be called if we are part of a chain of - // multiple MemBufs. The caller should have already verified this. - assert(isChained()); - - MemBuf* current = this; - while (true) { - if (current->isSharedOne()) { - // we have to unshare - break; - } - - current = current->next_; - if (current == this) { - // None of the MemBufs in the chain are shared, - // so return without doing anything - return; - } - } - - // We have to unshare. Let coalesceSlow() do the work. - coalesceSlow(); -} - -void MemBuf::markExternallyShared() { - MemBuf* current = this; - do { - current->markExternallySharedOne(); - current = current->next_; - } while (current != this); -} - -void MemBuf::makeManagedChained() { - assert(isChained()); - - MemBuf* current = this; - while (true) { - current->makeManagedOne(); - current = current->next_; - if (current == this) { - break; - } - } -} - -void MemBuf::coalesceSlow() { - // coalesceSlow() should only be called if we are part of a chain of multiple - // MemBufs. The caller should have already verified this. - - // Compute the length of the entire chain - std::size_t new_length = 0; - MemBuf* end = this; - do { - new_length += end->length_; - end = end->next_; - } while (end != this); - - coalesceAndReallocate(new_length, end); - // We should be only element left in the chain now -} - -void MemBuf::coalesceSlow(size_t max_length) { - // coalesceSlow() should only be called if we are part of a chain of multiple - // MemBufs. The caller should have already verified this. - - // Compute the length of the entire chain - std::size_t new_length = 0; - MemBuf* end = this; - while (true) { - new_length += end->length_; - end = end->next_; - if (new_length >= max_length) { - break; - } - if (end == this) { - throw std::overflow_error( - "attempted to coalesce more data than " - "available"); - } - } - - coalesceAndReallocate(new_length, end); - // We should have the requested length now -} - -void MemBuf::coalesceAndReallocate(size_t new_headroom, size_t new_length, - MemBuf* end, size_t new_tailroom) { - std::size_t new_capacity = new_length + new_headroom + new_tailroom; - - // Allocate space for the coalesced buffer. - // We always convert to an external buffer, even if we happened to be an - // internal buffer before. - uint8_t* newBuf; - SharedInfo* newInfo; - std::size_t actualCapacity; - allocExtBuffer(new_capacity, &newBuf, &newInfo, &actualCapacity); - - // Copy the data into the new buffer - uint8_t* new_data = newBuf + new_headroom; - uint8_t* p = new_data; - MemBuf* current = this; - size_t remaining = new_length; - do { - if (current->length_ > 0) { - assert(current->length_ <= remaining); - assert(current->data_ != nullptr); - remaining -= current->length_; - memcpy(p, current->data_, current->length_); - p += current->length_; - } - current = current->next_; - } while (current != end); - assert(remaining == 0); - - // Point at the new buffer - decrementRefcount(); - - // Make sure flag_maybe_shared and flag_free_shared_info are all cleared. - setFlagsAndSharedInfo(0, newInfo); - - capacity_ = actualCapacity; - buf_ = newBuf; - data_ = new_data; - length_ = new_length; - - // Separate from the rest of our chain. - // Since we don't store the unique_ptr returned by separateChain(), - // this will immediately delete the returned subchain. - if (isChained()) { - (void)separateChain(next_, current->prev_); - } -} - -void MemBuf::decrementRefcount() { - // Externally owned buffers don't have a SharedInfo object and aren't managed - // by the reference count - SharedInfo* info = sharedInfo(); - if (!info) { - return; - } - - // Decrement the refcount - uint32_t newcnt = info->refcount.fetch_sub(1, std::memory_order_acq_rel); - // Note that fetch_sub() returns the value before we decremented. - // If it is 1, we were the only remaining user; if it is greater there are - // still other users. - if (newcnt > 1) { - return; - } - - // We were the last user. Free the buffer - freeExtBuffer(); - - // Free the SharedInfo if it was allocated separately. - // - // This is only used by takeOwnership(). - // - // To avoid this special case handling in decrementRefcount(), we could have - // takeOwnership() set a custom freeFn() that calls the user's free function - // then frees the SharedInfo object. (This would require that - // takeOwnership() store the user's free function with its allocated - // SharedInfo object.) However, handling this specially with a flag seems - // like it shouldn't be problematic. - if (flags() & flag_free_shared_info) { - delete sharedInfo(); - } -} - -void MemBuf::reserveSlow(std::size_t min_headroom, std::size_t min_tailroom) { - size_t new_capacity = (size_t)length_ + min_headroom + min_tailroom; - - // // reserveSlow() is dangerous if anyone else is sharing the buffer, as we - // may - // // reallocate and free the original buffer. It should only ever be called - // if - // // we are the only user of the buffer. - - // We'll need to reallocate the buffer. - // There are a few options. - // - If we have enough total room, move the data around in the buffer - // and adjust the data_ pointer. - // - If we're using an internal buffer, we'll switch to an external - // buffer with enough headroom and tailroom. - // - If we have enough headroom (headroom() >= min_headroom) but not too much - // (so we don't waste memory), we can try: - // - If we don't have too much to copy, we'll use realloc() (note that - // realloc might have to copy - // headroom + data + tailroom) - // - Otherwise, bite the bullet and reallocate. - if (headroom() + tailroom() >= min_headroom + min_tailroom) { - uint8_t* new_data = writableBuffer() + min_headroom; - std::memmove(new_data, data_, length_); - data_ = new_data; - return; - } - - size_t new_allocated_capacity = 0; - uint8_t* new_buffer = nullptr; - std::size_t new_headroom = 0; - std::size_t old_headroom = headroom(); - - // If we have a buffer allocated with malloc and we just need more tailroom, - // try to use realloc()/xallocx() to grow the buffer in place. - SharedInfo* info = sharedInfo(); - if (info && (info->freeFn == nullptr) && length_ != 0 && - old_headroom >= min_headroom) { - size_t head_slack = old_headroom - min_headroom; - new_allocated_capacity = goodExtBufferSize(new_capacity + head_slack); - - size_t copySlack = capacity() - length_; - if (copySlack * 2 <= length_) { - void* p = realloc(buf_, new_allocated_capacity); - if (TRANSPORT_EXPECT_FALSE(p == nullptr)) { - throw std::bad_alloc(); - } - new_buffer = static_cast<uint8_t*>(p); - new_headroom = old_headroom; - } - } - - // None of the previous reallocation strategies worked (or we're using - // an internal buffer). malloc/copy/free. - if (new_buffer == nullptr) { - new_allocated_capacity = goodExtBufferSize(new_capacity); - new_buffer = static_cast<uint8_t*>(malloc(new_allocated_capacity)); - if (length_ > 0) { - assert(data_ != nullptr); - memcpy(new_buffer + min_headroom, data_, length_); - } - if (sharedInfo()) { - freeExtBuffer(); - } - new_headroom = min_headroom; - } - - std::size_t cap; - initExtBuffer(new_buffer, new_allocated_capacity, &info, &cap); - - if (flags() & flag_free_shared_info) { - delete sharedInfo(); - } - - setFlagsAndSharedInfo(0, info); - capacity_ = cap; - buf_ = new_buffer; - data_ = new_buffer + new_headroom; - // length_ is unchanged -} - -void MemBuf::freeExtBuffer() { - SharedInfo* info = sharedInfo(); - - if (info->freeFn) { - try { - info->freeFn(buf_, info->userData); - } catch (...) { - // The user's free function should never throw. Otherwise we might - // throw from the MemBuf destructor. Other code paths like coalesce() - // also assume that decrementRefcount() cannot throw. - abort(); - } - } else { - free(buf_); - } -} - -void MemBuf::allocExtBuffer(std::size_t minCapacity, uint8_t** bufReturn, - SharedInfo** infoReturn, - std::size_t* capacityReturn) { - size_t mallocSize = goodExtBufferSize(minCapacity); - uint8_t* buf = static_cast<uint8_t*>(malloc(mallocSize)); - initExtBuffer(buf, mallocSize, infoReturn, capacityReturn); - *bufReturn = buf; -} - -size_t MemBuf::goodExtBufferSize(std::size_t minCapacity) { - // Determine how much space we should allocate. We'll store the SharedInfo - // for the external buffer just after the buffer itself. (We store it just - // after the buffer rather than just before so that the code can still just - // use free(buf_) to free the buffer.) - size_t minSize = static_cast<size_t>(minCapacity) + sizeof(SharedInfo); - // Add room for padding so that the SharedInfo will be aligned on an 8-byte - // boundary. - minSize = (minSize + 7) & ~7; - - // Use goodMallocSize() to bump up the capacity to a decent size to request - // from malloc, so we can use all of the space that malloc will probably give - // us anyway. - return minSize; -} - -void MemBuf::initExtBuffer(uint8_t* buf, size_t mallocSize, - SharedInfo** infoReturn, - std::size_t* capacityReturn) { - // Find the SharedInfo storage at the end of the buffer - // and construct the SharedInfo. - uint8_t* infoStart = (buf + mallocSize) - sizeof(SharedInfo); - SharedInfo* sharedInfo = new (infoStart) SharedInfo; - - *capacityReturn = std::size_t(infoStart - buf); - *infoReturn = sharedInfo; -} - -} // namespace utils
\ No newline at end of file diff --git a/libtransport/src/hicn/transport/utils/membuf.h b/libtransport/src/hicn/transport/utils/membuf.h deleted file mode 100644 index 9fc37dd25..000000000 --- a/libtransport/src/hicn/transport/utils/membuf.h +++ /dev/null @@ -1,921 +0,0 @@ -/* - * 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/src/hicn/transport/utils/min_filter.h b/libtransport/src/hicn/transport/utils/min_filter.h deleted file mode 100644 index dcfd5652d..000000000 --- a/libtransport/src/hicn/transport/utils/min_filter.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.sudo make instamake install - */ - -#pragma once - -#include <hicn/transport/portability/portability.h> -#include <hicn/transport/utils/log.h> - -#include <deque> -#include <iostream> -#include <set> -#include <type_traits> -#include <vector> - -namespace utils { - -template <typename T> -class MinFilter { - public: - MinFilter(std::size_t size) : size_(size) {} - - std::size_t size() { return by_arrival_.size(); } - - template <typename R> - TRANSPORT_ALWAYS_INLINE void pushBack(R&& value) { - if (by_arrival_.size() >= size_) { - by_order_.erase(by_arrival_.back()); - by_arrival_.pop_back(); - } - - by_arrival_.push_front(by_order_.insert(std::forward<R>(value))); - } - - TRANSPORT_ALWAYS_INLINE const T& begin() { return *by_order_.cbegin(); } - - TRANSPORT_ALWAYS_INLINE const T& rBegin() { return *by_order_.crbegin(); } - - private: - std::multiset<T> by_order_; - std::deque<typename std::multiset<T>::const_iterator> by_arrival_; - std::size_t size_; -}; - -} // namespace utils diff --git a/libtransport/src/hicn/transport/utils/object_pool.h b/libtransport/src/hicn/transport/utils/object_pool.h deleted file mode 100644 index e8f837753..000000000 --- a/libtransport/src/hicn/transport/utils/object_pool.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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/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/src/hicn/transport/utils/ring_buffer.h b/libtransport/src/hicn/transport/utils/ring_buffer.h deleted file mode 100644 index 9babe56bd..000000000 --- a/libtransport/src/hicn/transport/utils/ring_buffer.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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/src/hicn/transport/utils/signer.cc b/libtransport/src/hicn/transport/utils/signer.cc deleted file mode 100644 index 9ac9a2c45..000000000 --- a/libtransport/src/hicn/transport/utils/signer.cc +++ /dev/null @@ -1,187 +0,0 @@ -/* - * 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. - */ - -#include <hicn/transport/errors/malformed_ahpacket_exception.h> -#include <hicn/transport/utils/key_id.h> -#include <hicn/transport/utils/membuf.h> -#include <hicn/transport/utils/signer.h> - -extern "C" { -#ifndef _WIN32 -TRANSPORT_CLANG_DISABLE_WARNING("-Wextern-c-compat") -#endif -#include <hicn/hicn.h> -#include <parc/security/parc_PublicKeySigner.h> -#include <parc/security/parc_Security.h> -#include <parc/security/parc_SymmetricKeySigner.h> -} - -#include <chrono> - -#define ALLOW_UNALIGNED_READS 1 - -namespace utils { - -uint8_t Signer::zeros[200] = {0}; - -/*One signer_ per Private Key*/ -Signer::Signer(PARCKeyStore *keyStore, CryptoSuite suite) { - parcSecurity_Init(); - - switch (suite) { - case CryptoSuite::DSA_SHA256: - case CryptoSuite::RSA_SHA256: - case CryptoSuite::RSA_SHA512: - case CryptoSuite::ECDSA_256K1: { - this->signer_ = - parcSigner_Create(parcPublicKeySigner_Create( - keyStore, static_cast<PARCCryptoSuite>(suite)), - PARCPublicKeySignerAsSigner); - break; - } - case CryptoSuite::HMAC_SHA256: - case CryptoSuite::HMAC_SHA512: { - this->signer_ = - parcSigner_Create(parcSymmetricKeySigner_Create( - (PARCSymmetricKeyStore *)keyStore, - parcCryptoSuite_GetCryptoHash( - static_cast<PARCCryptoSuite>(suite))), - PARCSymmetricKeySignerAsSigner); - break; - } - default: { return; } - } - - suite_ = suite; - key_id_ = parcSigner_CreateKeyId(this->signer_); - signature_length_ = parcSigner_GetSignatureSize(this->signer_); -} - -Signer::Signer(const std::string &passphrase, CryptoSuite suite) { - parcSecurity_Init(); - - switch (suite) { - case CryptoSuite::HMAC_SHA256: - case CryptoSuite::HMAC_SHA512: { - composer_ = parcBufferComposer_Create(); - parcBufferComposer_PutString(composer_, passphrase.c_str()); - key_buffer_ = parcBufferComposer_ProduceBuffer(composer_); - symmetricKeyStore_ = parcSymmetricKeyStore_Create(key_buffer_); - this->signer_ = parcSigner_Create( - parcSymmetricKeySigner_Create( - symmetricKeyStore_, parcCryptoSuite_GetCryptoHash( - static_cast<PARCCryptoSuite>(suite))), - PARCSymmetricKeySignerAsSigner); - break; - } - default: { return; } - } - - suite_ = suite; - key_id_ = parcSigner_CreateKeyId(this->signer_); - signature_length_ = parcSigner_GetSignatureSize(this->signer_); -} - -Signer::Signer(const PARCSigner *signer, CryptoSuite suite) - : signer_(parcSigner_Acquire(signer)), - key_id_(parcSigner_CreateKeyId(this->signer_)), - suite_(suite), - signature_length_(parcSigner_GetSignatureSize(this->signer_)) { - parcSecurity_Init(); -} - -Signer::Signer(const PARCSigner *signer) - : Signer(signer, CryptoSuite::UNKNOWN) {} - -Signer::~Signer() { - if (signature_) parcSignature_Release(&signature_); - if (symmetricKeyStore_) parcSymmetricKeyStore_Release(&symmetricKeyStore_); - if (key_buffer_) parcBuffer_Release(&key_buffer_); - if (composer_) parcBufferComposer_Release(&composer_); - if (signer_) parcSigner_Release(&signer_); - if (key_id_) parcKeyId_Release(&key_id_); - parcSecurity_Fini(); -} - -void Signer::sign(Packet &packet) { - // header chain points to the IP + TCP hicn header + AH Header - MemBuf *header_chain = packet.header_head_; - MemBuf *payload_chain = packet.payload_head_; - uint8_t *hicn_packet = (uint8_t *)header_chain->writableData(); - Packet::Format format = packet.getFormat(); - - if (!(format & HFO_AH)) { - throw errors::MalformedAHPacketException(); - } - - packet.setSignatureSize(signature_length_); - - // Copy IP+TCP/ICMP header before zeroing them - hicn_header_t header_copy; - hicn_packet_copy_header(format, (const hicn_header_t *)packet.packet_start_, - &header_copy, false); - - std::size_t header_len = Packet::getHeaderSizeFromFormat(format); - - packet.resetForHash(); - - /* Fill the hicn_ah header */ - using namespace std::chrono; - auto now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()) - .count(); - packet.setSignatureTimestamp(now); - packet.setValidationAlgorithm(suite_); - - KeyId key_id; - key_id.first = (uint8_t *)parcBuffer_Overlay( - (PARCBuffer *)parcKeyId_GetKeyId(this->key_id_), 0); - packet.setKeyId(key_id); - - // Calculate hash - CryptoHasher hasher(parcSigner_GetCryptoHasher(signer_)); - hasher.init(); - hasher.updateBytes(hicn_packet, header_len + signature_length_); - - for (MemBuf *current = payload_chain; current != header_chain; - current = current->next()) { - hasher.updateBytes(current->data(), current->length()); - } - - CryptoHash hash = hasher.finalize(); - - signature_ = parcSigner_SignDigestNoAlloc(this->signer_, hash.hash_, - packet.getSignature(), - (uint32_t)signature_length_); - PARCBuffer *buffer = parcSignature_GetSignature(signature_); - - size_t bytes_len = parcBuffer_Remaining(buffer); - - if (bytes_len > signature_length_) { - throw errors::MalformedAHPacketException(); - } - - hicn_packet_copy_header(format, &header_copy, - (hicn_header_t *)packet.packet_start_, false); -} - -size_t Signer::getSignatureLength() { return signature_length_; } - -PARCKeyStore *Signer::getKeyStore() { - return parcSigner_GetKeyStore(this->signer_); -} - -} // namespace utils diff --git a/libtransport/src/hicn/transport/utils/signer.h b/libtransport/src/hicn/transport/utils/signer.h deleted file mode 100644 index 31b21462b..000000000 --- a/libtransport/src/hicn/transport/utils/signer.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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/src/hicn/transport/utils/spinlock.h b/libtransport/src/hicn/transport/utils/spinlock.h deleted file mode 100644 index 009a94454..000000000 --- a/libtransport/src/hicn/transport/utils/spinlock.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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/src/hicn/transport/utils/stream_buffer.h b/libtransport/src/hicn/transport/utils/stream_buffer.h deleted file mode 100644 index adfb696f2..000000000 --- a/libtransport/src/hicn/transport/utils/stream_buffer.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 <streambuf> - -namespace utils { - -template <typename char_type> -struct ostreambuf - : public std::basic_streambuf<char_type, std::char_traits<char_type> > { - ostreambuf(char_type* buffer, std::streamsize buffer_length) { - // set the "put" pointer the start of the buffer and record it's length. - setp(buffer, buffer + buffer_length); - } -}; - -} // namespace utils
\ No newline at end of file diff --git a/libtransport/src/hicn/transport/utils/string_tokenizer.cc b/libtransport/src/hicn/transport/utils/string_tokenizer.cc deleted file mode 100644 index a280a3c43..000000000 --- a/libtransport/src/hicn/transport/utils/string_tokenizer.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - */ - -#include <hicn/transport/errors/errors.h> -#include <hicn/transport/utils/string_tokenizer.h> - -namespace utils { - -StringTokenizer::StringTokenizer(const std::string &str) - : str_(str), delimiter_(" ") {} - -StringTokenizer::StringTokenizer(const std::string &str, - const std::string &delim) - : str_(str), delimiter_(delim) {} - -bool StringTokenizer::hasMoreTokens() { - return str_.find(delimiter_) != std::string::npos || !str_.empty(); -} - -std::string StringTokenizer::nextToken() { - unsigned long pos = (unsigned long)str_.find(delimiter_); - - bool token_found = std::string::npos != pos; - - if (!token_found && str_.empty()) { - throw errors::TokenizerException(); - } - - std::string token = str_.substr(0, pos); - str_.erase(0, token_found ? pos + delimiter_.length() : pos); - - return token; -} - -} // namespace utils
\ No newline at end of file diff --git a/libtransport/src/hicn/transport/utils/string_tokenizer.h b/libtransport/src/hicn/transport/utils/string_tokenizer.h deleted file mode 100644 index 36630eb58..000000000 --- a/libtransport/src/hicn/transport/utils/string_tokenizer.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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/src/hicn/transport/utils/suffix_strategy.h b/libtransport/src/hicn/transport/utils/suffix_strategy.h deleted file mode 100644 index ab9b1eff6..000000000 --- a/libtransport/src/hicn/transport/utils/suffix_strategy.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * 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/manifest_format.h> -#include <limits> - -namespace utils { - -using transport::core::NextSegmentCalculationStrategy; - -class SuffixStrategy { - public: - static constexpr uint32_t INVALID_SUFFIX = - std::numeric_limits<uint32_t>::max(); - - SuffixStrategy(NextSegmentCalculationStrategy strategy) - : suffix_stragegy_(strategy), - total_count_(0), - final_suffix_(INVALID_SUFFIX) {} - - virtual ~SuffixStrategy() = default; - - virtual uint32_t getNextSuffix() = 0; - - virtual uint32_t getFinalSuffix() { return final_suffix_; } - - virtual void setFinalSuffix(std::uint32_t final_suffix) { - if (final_suffix != INVALID_SUFFIX) { - final_suffix_ = final_suffix; - } - } - - virtual uint32_t getNextManifestSuffix() = 0; - - virtual uint32_t getNextContentSuffix() = 0; - - virtual void reset(uint32_t offset = 0) = 0; - - virtual uint32_t getManifestCapacity() = 0; - - virtual void setManifestCapacity(uint32_t capacity) = 0; - - virtual uint32_t getTotalCount() { return total_count_; }; - - NextSegmentCalculationStrategy getSuffixStrategy() { - return suffix_stragegy_; - } - - protected: - inline void incrementTotalCount() { total_count_++; }; - - protected: - NextSegmentCalculationStrategy suffix_stragegy_; - std::uint32_t total_count_; - std::uint32_t final_suffix_; -}; - -class IncrementalSuffixStrategy : public SuffixStrategy { - public: - IncrementalSuffixStrategy(std::uint32_t start_offset) - : SuffixStrategy(NextSegmentCalculationStrategy::INCREMENTAL), - next_suffix_(start_offset) {} - - TRANSPORT_ALWAYS_INLINE std::uint32_t getNextSuffix() override { - incrementTotalCount(); - return next_suffix_++; - } - - TRANSPORT_ALWAYS_INLINE std::uint32_t getNextContentSuffix() override { - return getNextSuffix(); - } - - TRANSPORT_ALWAYS_INLINE std::uint32_t getNextManifestSuffix() override { - return getNextSuffix(); - } - - uint32_t getManifestCapacity() override { - throw errors::RuntimeException( - "No manifest capacity in IncrementalSuffixStrategy."); - } - - void setManifestCapacity(uint32_t capacity) override { - throw errors::RuntimeException( - "No manifest capacity in IncrementalSuffixStrategy."); - } - - void reset(std::uint32_t offset = 0) override { next_suffix_ = offset; } - - protected: - std::uint32_t next_suffix_; -}; - -class CapacityBasedSuffixStrategy : public SuffixStrategy { - public: - CapacityBasedSuffixStrategy(std::uint32_t start_offset, - std::uint32_t manifest_capacity) - : SuffixStrategy(NextSegmentCalculationStrategy::INCREMENTAL), - next_suffix_(start_offset), - segments_in_manifest_(manifest_capacity), - current_manifest_iteration_(0) {} - - TRANSPORT_ALWAYS_INLINE std::uint32_t getNextSuffix() override { - incrementTotalCount(); - return next_suffix_++; - } - - TRANSPORT_ALWAYS_INLINE std::uint32_t getNextContentSuffix() override { - incrementTotalCount(); - return next_suffix_ % segments_in_manifest_ == 0 ? next_suffix_++ - : ++next_suffix_; - } - - TRANSPORT_ALWAYS_INLINE std::uint32_t getNextManifestSuffix() override { - incrementTotalCount(); - return (current_manifest_iteration_++) * (segments_in_manifest_ + 1); - } - - TRANSPORT_ALWAYS_INLINE uint32_t getManifestCapacity() override { - return segments_in_manifest_; - } - - TRANSPORT_ALWAYS_INLINE void setManifestCapacity(uint32_t capacity) override { - segments_in_manifest_ = capacity; - } - - void reset(std::uint32_t offset = 0) override { next_suffix_ = offset; } - - protected: - std::uint32_t next_suffix_; - std::uint32_t segments_in_manifest_; - std::uint32_t current_manifest_iteration_; -}; - -class SuffixStrategyFactory { - public: - static std::unique_ptr<SuffixStrategy> getSuffixStrategy( - NextSegmentCalculationStrategy strategy, uint32_t start_offset, - uint32_t manifest_capacity = 0) { - switch (strategy) { - case NextSegmentCalculationStrategy::INCREMENTAL: - return std::make_unique<IncrementalSuffixStrategy>(start_offset); - case NextSegmentCalculationStrategy::MANIFEST_CAPACITY_BASED: - return std::make_unique<CapacityBasedSuffixStrategy>(start_offset, - manifest_capacity); - default: - throw errors::RuntimeException( - "No valid NextSegmentCalculationStrategy specified."); - } - } -}; - -} // namespace utils diff --git a/libtransport/src/hicn/transport/utils/test.h b/libtransport/src/hicn/transport/utils/test.h deleted file mode 100644 index e3dd619ac..000000000 --- a/libtransport/src/hicn/transport/utils/test.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 <sstream> - -namespace testing { - -namespace internal { - -enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW }; - -extern void ColoredPrintf(GTestColor color, const char *fmt, ...); - -} // namespace internal - -} // namespace testing - -#define PRINTF(...) \ - do { \ - testing::internal::ColoredPrintf(testing::internal::COLOR_GREEN, \ - "[ ] "); \ - testing::internal::ColoredPrintf(testing::internal::COLOR_YELLOW, \ - __VA_ARGS__); \ - } while (0) - -// C++ stream interface -class TestCout : public std::stringstream { - public: - ~TestCout() {} -}; - -#define TEST_COUT TestCout()
\ No newline at end of file diff --git a/libtransport/src/hicn/transport/utils/uri.cc b/libtransport/src/hicn/transport/utils/uri.cc deleted file mode 100644 index 33eb8b45b..000000000 --- a/libtransport/src/hicn/transport/utils/uri.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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. - */ - -#include <hicn/transport/errors/runtime_exception.h> -#include <hicn/transport/utils/uri.h> - -namespace utils { - -Uri::Uri() {} - -Uri &Uri::parse(const std::string &uri) { - if (uri.length() == 0) { - throw errors::RuntimeException("Malformed URI."); - } - - iterator_t uri_end = uri.end(); - - // get query start - iterator_t query_start = std::find(uri.begin(), uri_end, '?'); - - // protocol - iterator_t protocol_start = uri.begin(); - iterator_t protocol_end = std::find(protocol_start, uri_end, ':'); //"://"); - - if (protocol_end != uri_end) { - std::string prot = &*(protocol_end); - if ((prot.length() > 3) && (prot.substr(0, 3) == "://")) { - protocol_ = std::string(protocol_start, protocol_end); - protocol_end += 3; // :// - } else { - protocol_end = uri.begin(); // no protocol - } - } else { - protocol_end = uri.begin(); // no protocol - } - // host - iterator_t host_start = protocol_end; - iterator_t path_start = - std::find(host_start, uri_end, '/'); // get path_start - - iterator_t host_end = std::find( - protocol_end, (path_start != uri_end) ? path_start : query_start, - ':'); // check for port - - locator_ = std::string(host_start, host_end); - - // port - if ((host_end != uri_end) && ((&*(host_end))[0] == ':')) { - host_end++; - iterator_t port_end = (path_start != uri_end) ? path_start : query_start; - port_ = std::string(host_end, port_end); - } - - // path - if (path_start != uri_end) { - path_ = std::string(path_start, query_start); - } - // query - if (query_start != uri_end) { - query_string_ = std::string(query_start, uri.end()); - } - - return *this; -} - -Uri &Uri::parseProtocolAndLocator(const std::string &locator) { - iterator_t total_end = locator.end(); - - // protocol - iterator_t protocol_start = locator.begin(); - iterator_t protocol_end = - std::find(protocol_start, total_end, ':'); //"://"); - - if (protocol_end != total_end) { - std::string prot = &*(protocol_end); - if ((prot.length() > 3) && (prot.substr(0, 3) == "://")) { - protocol_ = std::string(protocol_start, protocol_end); - protocol_end += 3; // :// - } else { - throw errors::RuntimeException("Malformed locator. (Missing \"://\")"); - } - } else { - throw errors::RuntimeException("Malformed locator. No protocol specified."); - } - - // locator - iterator_t host_start = protocol_end; - iterator_t host_end = std::find(protocol_end, total_end, '/'); - - if (host_start == host_end) { - throw errors::RuntimeException( - "Malformed locator. Locator name is missing"); - } - - locator_ = std::string(host_start, host_end); - - return *this; -} - -std::string Uri::getLocator() { return locator_; } - -std::string Uri::getPath() { return path_; } - -std::string Uri::getPort() { return port_; } - -std::string Uri::getProtocol() { return protocol_; } - -std::string Uri::getQueryString() { return query_string_; } - -} // end namespace utils diff --git a/libtransport/src/hicn/transport/utils/uri.h b/libtransport/src/hicn/transport/utils/uri.h deleted file mode 100644 index 7c28e8552..000000000 --- a/libtransport/src/hicn/transport/utils/uri.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 diff --git a/libtransport/src/hicn/transport/utils/verifier.cc b/libtransport/src/hicn/transport/utils/verifier.cc deleted file mode 100644 index 281ee21dc..000000000 --- a/libtransport/src/hicn/transport/utils/verifier.cc +++ /dev/null @@ -1,234 +0,0 @@ -/* - * 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. - */ - -#include <hicn/transport/core/packet.h> -#include <hicn/transport/errors/malformed_ahpacket_exception.h> -#include <hicn/transport/portability/portability.h> -#include <hicn/transport/utils/key_id.h> -#include <hicn/transport/utils/log.h> -#include <hicn/transport/utils/verifier.h> - -extern "C" { -#ifndef _WIN32 -TRANSPORT_CLANG_DISABLE_WARNING("-Wextern-c-compat") -#endif -#include <hicn/hicn.h> -} - -#include <sys/stat.h> - -namespace utils { - -TRANSPORT_ALWAYS_INLINE bool file_exists(const std::string &name) { - struct stat buffer; - return (stat(name.c_str(), &buffer) == 0); -} - -uint8_t Verifier::zeros[200] = {0}; - -Verifier::Verifier() { - parcSecurity_Init(); - PARCInMemoryVerifier *in_memory_verifier = parcInMemoryVerifier_Create(); - this->verifier_ = - parcVerifier_Create(in_memory_verifier, PARCInMemoryVerifierAsVerifier); -} - -Verifier::~Verifier() { - if (key_) parcKey_Release(&key_); - if (keyId_) parcKeyId_Release(&keyId_); - if (signer_) parcSigner_Release(&signer_); - if (symmetricKeyStore_) parcSymmetricKeyStore_Release(&symmetricKeyStore_); - if (key_buffer_) parcBuffer_Release(&key_buffer_); - if (composer_) parcBufferComposer_Release(&composer_); - if (certificate_) parcCertificate_Release(&certificate_); - if (factory_) parcCertificateFactory_Release(&factory_); - if (verifier_) parcVerifier_Release(&verifier_); - parcSecurity_Fini(); -} - -/* - * TODO: Unsupported in libparc - */ -bool Verifier::hasKey(PARCKeyId *keyId) { return false; } - -/* - * TODO: signal errors without trap. - */ -bool Verifier::addKey(PARCKey *key) { - parcVerifier_AddKey(this->verifier_, key); - return true; -} - -PARCKeyId *Verifier::addKeyFromPassphrase(const std::string &passphrase, - CryptoSuite suite) { - composer_ = parcBufferComposer_Create(); - parcBufferComposer_PutString(composer_, passphrase.c_str()); - key_buffer_ = parcBufferComposer_ProduceBuffer(composer_); - - symmetricKeyStore_ = parcSymmetricKeyStore_Create(key_buffer_); - signer_ = parcSigner_Create( - parcSymmetricKeySigner_Create( - symmetricKeyStore_, - parcCryptoSuite_GetCryptoHash(static_cast<PARCCryptoSuite>(suite))), - PARCSymmetricKeySignerAsSigner); - keyId_ = parcSigner_CreateKeyId(signer_); - key_ = parcKey_CreateFromSymmetricKey( - keyId_, parcSigner_GetSigningAlgorithm(signer_), key_buffer_); - - addKey(key_); - return keyId_; -} - -PARCKeyId *Verifier::addKeyFromCertificate(const std::string &file_name) { - factory_ = parcCertificateFactory_Create(PARCCertificateType_X509, - PARCContainerEncoding_PEM); - parcAssertNotNull(factory_, "Expected non-NULL factory"); - - if (!file_exists(file_name)) { - TRANSPORT_LOGW("Warning! The certificate %s file does not exist", - file_name.c_str()); - return nullptr; - } - - certificate_ = parcCertificateFactory_CreateCertificateFromFile( - factory_, (char *)file_name.c_str(), NULL); - PARCBuffer *derEncodedVersion = - parcCertificate_GetDEREncodedPublicKey(certificate_); - PARCCryptoHash *keyDigest = parcCertificate_GetPublicKeyDigest(certificate_); - keyId_ = parcKeyId_Create(parcCryptoHash_GetDigest(keyDigest)); - key_ = parcKey_CreateFromDerEncodedPublicKey(keyId_, PARCSigningAlgorithm_RSA, - derEncodedVersion); - - addKey(key_); - return keyId_; -} - -int Verifier::verify(const Packet &packet) { - // to initialize packet.payload_head_ - const_cast<Packet *>(&packet)->separateHeaderPayload(); - bool valid = false; - Packet::Format format = packet.getFormat(); - - if (!(packet.format_ & HFO_AH)) { - throw errors::MalformedAHPacketException(); - } - - // Copy IP+TCP/ICMP header before zeroing them - hicn_header_t header_copy; - hicn_packet_copy_header(format, (const hicn_header_t *)packet.packet_start_, - &header_copy, false); - - PARCCryptoSuite suite = - static_cast<PARCCryptoSuite>(packet.getValidationAlgorithm()); - PARCCryptoHashType hashtype = parcCryptoSuite_GetCryptoHash(suite); - KeyId _key_id = packet.getKeyId(); - PARCBuffer *buffer = - parcBuffer_Wrap(_key_id.first, _key_id.second, 0, _key_id.second); - PARCKeyId *key_id = parcKeyId_Create(buffer); - parcBuffer_Release(&buffer); - - int ah_payload_len = (int)packet.getSignatureSize(); - uint8_t *_signature = packet.getSignature(); - uint8_t *signature = new uint8_t[ah_payload_len]; - // TODO Remove signature copy at this point, by not setting to zero - // the validation payload. - std::memcpy(signature, _signature, ah_payload_len); - - std::shared_ptr<CryptoHasher> hasher; - switch (CryptoSuite(suite)) { - case CryptoSuite::DSA_SHA256: - case CryptoSuite::RSA_SHA256: - case CryptoSuite::RSA_SHA512: - case CryptoSuite::ECDSA_256K1: { - hasher = std::make_shared<CryptoHasher>( - parcVerifier_GetCryptoHasher(verifier_, key_id, hashtype)); - break; - } - case CryptoSuite::HMAC_SHA256: - case CryptoSuite::HMAC_SHA512: { - if (!signer_) return false; - hasher = - std::make_shared<CryptoHasher>(parcSigner_GetCryptoHasher(signer_)); - break; - } - default: { return false; } - } - CryptoHash hash_computed_locally = getPacketHash(packet, hasher); - - PARCBuffer *bits = - parcBuffer_Wrap(signature, ah_payload_len, 0, ah_payload_len); - parcBuffer_Rewind(bits); - - /* IF the signature algo is ECDSA, the signature might be shorter than the - * signature field */ - PARCSigningAlgorithm algo = parcCryptoSuite_GetSigningAlgorithm(suite); - while (algo == PARCSigningAlgorithm_ECDSA && parcBuffer_HasRemaining(bits) && - parcBuffer_GetUint8(bits) == 0) - ; - - if (algo == PARCSigningAlgorithm_ECDSA) { - parcBuffer_SetPosition(bits, parcBuffer_Position(bits) - 1); - } - - if (!parcBuffer_HasRemaining(bits)) { - parcKeyId_Release(&key_id); - parcBuffer_Release(&bits); - return valid; - } - - PARCSignature *signatureToVerify = parcSignature_Create( - parcCryptoSuite_GetSigningAlgorithm(suite), hashtype, bits); - - if (algo == PARCSigningAlgorithm_RSA) { - parcBuffer_SetPosition(bits, 0); - } - - valid = parcVerifier_VerifyDigestSignature( - verifier_, key_id, hash_computed_locally.hash_, suite, signatureToVerify); - - /* Restore the resetted fields */ - hicn_packet_copy_header(format, &header_copy, - (hicn_header_t *)packet.packet_start_, false); - - delete[] signature; - parcKeyId_Release(&key_id); - parcBuffer_Release(&bits); - parcSignature_Release(&signatureToVerify); - - return valid; -} - -CryptoHash Verifier::getPacketHash(const Packet &packet, - std::shared_ptr<CryptoHasher> hasher) { - MemBuf *header_chain = packet.header_head_; - MemBuf *payload_chain = packet.payload_head_; - Packet::Format format = packet.getFormat(); - int ah_payload_len = (int)packet.getSignatureSize(); - uint8_t *hicn_packet = header_chain->writableData(); - std::size_t header_len = Packet::getHeaderSizeFromFormat(format); - - // Reset fields that should not appear in the signature - const_cast<Packet &>(packet).resetForHash(); - hasher->init().updateBytes(hicn_packet, header_len + ah_payload_len); - - for (MemBuf *current = payload_chain; current != header_chain; - current = current->next()) { - hasher->updateBytes(current->data(), current->length()); - } - - return hasher->finalize(); -} - -} // namespace utils diff --git a/libtransport/src/hicn/transport/utils/verifier.h b/libtransport/src/hicn/transport/utils/verifier.h deleted file mode 100644 index 7ec6e7eda..000000000 --- a/libtransport/src/hicn/transport/utils/verifier.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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 |