From 6b94663b2455e212009a544ae23bb6a8c55407f8 Mon Sep 17 00:00:00 2001 From: Luca Muscariello Date: Thu, 9 Jun 2022 21:34:09 +0200 Subject: refactor(lib, hicn-light, vpp, hiperf): HICN-723 - move infra data structure into the shared lib - new packet cache using double hashing and lookup on prefix suffix - testing updates - authenticated requests using interest manifests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mauro Sardara Co-authored-by: Jordan Augé Co-authored-by: Michele Papalini Co-authored-by: Olivier Roques Co-authored-by: Enrico Loparco Change-Id: Iaddebfe6aa5279ea8553433b0f519578f6b9ccd9 Signed-off-by: Luca Muscariello --- .../includes/hicn/transport/core/asio_wrapper.h | 3 + .../includes/hicn/transport/core/connector.h | 20 ++++- .../includes/hicn/transport/core/content_object.h | 12 +-- .../includes/hicn/transport/core/interest.h | 18 ++-- .../includes/hicn/transport/core/io_module.h | 10 +-- libtransport/includes/hicn/transport/core/name.h | 7 +- libtransport/includes/hicn/transport/core/prefix.h | 28 +++---- .../hicn/transport/interfaces/CMakeLists.txt | 7 -- .../transport/interfaces/global_conf_interface.h | 16 +++- .../interfaces/p2psecure_socket_consumer.h | 32 -------- .../interfaces/p2psecure_socket_producer.h | 34 -------- .../includes/hicn/transport/interfaces/portal.h | 2 +- .../hicn/transport/interfaces/socket_consumer.h | 6 ++ .../interfaces/socket_options_default_values.h | 6 +- .../transport/interfaces/socket_options_keys.h | 39 +++++---- .../hicn/transport/interfaces/socket_producer.h | 7 ++ .../hicn/transport/interfaces/statistics.h | 8 +- .../hicn/transport/portability/CMakeLists.txt | 2 + .../includes/hicn/transport/portability/cache.h | 87 ++++++++++++++++++++ .../hicn/transport/portability/endianess.h | 86 ++++++++++++++++++++ .../hicn/transport/portability/portability.h | 2 + .../hicn/transport/utils/chrono_typedefs.h | 2 +- libtransport/includes/hicn/transport/utils/color.h | 95 ++++++++++++++++++++++ .../includes/hicn/transport/utils/event_thread.h | 34 +++----- libtransport/includes/hicn/transport/utils/linux.h | 2 +- .../includes/hicn/transport/utils/thread_pool.h | 3 + 26 files changed, 398 insertions(+), 170 deletions(-) delete mode 100644 libtransport/includes/hicn/transport/interfaces/p2psecure_socket_consumer.h delete mode 100644 libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h create mode 100644 libtransport/includes/hicn/transport/portability/cache.h create mode 100644 libtransport/includes/hicn/transport/portability/endianess.h create mode 100644 libtransport/includes/hicn/transport/utils/color.h (limited to 'libtransport/includes/hicn/transport') diff --git a/libtransport/includes/hicn/transport/core/asio_wrapper.h b/libtransport/includes/hicn/transport/core/asio_wrapper.h index 78cad35dc..41b660587 100644 --- a/libtransport/includes/hicn/transport/core/asio_wrapper.h +++ b/libtransport/includes/hicn/transport/core/asio_wrapper.h @@ -23,6 +23,9 @@ TRANSPORT_CLANG_DISABLE_WARNING("-Wdeprecated-declarations") #ifndef ASIO_STANDALONE #define ASIO_STANDALONE #endif +#ifdef __APPLE__ +TRANSPORT_CLANG_DISABLE_WARNING("-Wshorten-64-to-32") +#endif #include TRANSPORT_POP_WARNING diff --git a/libtransport/includes/hicn/transport/core/connector.h b/libtransport/includes/hicn/transport/core/connector.h index b671a7d89..ad0d4f09d 100644 --- a/libtransport/includes/hicn/transport/core/connector.h +++ b/libtransport/includes/hicn/transport/core/connector.h @@ -30,6 +30,7 @@ #include #include +#include namespace transport { @@ -57,10 +58,10 @@ class Connector : public std::enable_shared_from_this { static constexpr std::uint16_t max_burst = 256; using Ptr = std::shared_ptr; + using ReceptionBuffer = std::vector; using PacketQueue = std::deque; - using PacketReceivedCallback = - std::function &, - const std::error_code &)>; + using PacketReceivedCallback = std::function; using PacketSentCallback = std::function; using OnCloseCallback = std::function; @@ -118,6 +119,14 @@ class Connector : public std::enable_shared_from_this { virtual void send(const utils::MemBuf::Ptr &buffer) = 0; + virtual void receive(const std::vector &buffers) { + receive_callback_(this, buffers, std::make_error_code(std::errc())); + } + + virtual void reconnect() { + on_reconnect_callback_(this, std::make_error_code(std::errc())); + } + virtual void close() = 0; virtual State state() { return state_; }; @@ -134,6 +143,11 @@ class Connector : public std::enable_shared_from_this { std::string getConnectorName() { return connector_name_; } + template + void setLocalEndpoint(EP &&endpoint) { + local_endpoint_ = std::forward(endpoint); + } + Endpoint getLocalEndpoint() { return local_endpoint_; } Endpoint getRemoteEndpoint() { return remote_endpoint_; } diff --git a/libtransport/includes/hicn/transport/core/content_object.h b/libtransport/includes/hicn/transport/core/content_object.h index a8df1e8e3..f8d95846e 100644 --- a/libtransport/includes/hicn/transport/core/content_object.h +++ b/libtransport/includes/hicn/transport/core/content_object.h @@ -43,8 +43,8 @@ class ContentObject : public Packet { template ContentObject(CopyBufferOp op, Args &&...args) : Packet(op, std::forward(args)...) { - if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) < - 0) { + if (hicn_data_get_name(format_, packet_start_, + &name_.getStructReference()) < 0) { throw errors::MalformedPacketException(); } } @@ -52,8 +52,8 @@ class ContentObject : public Packet { template ContentObject(WrapBufferOp op, Args &&...args) : Packet(op, std::forward(args)...) { - if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) < - 0) { + if (hicn_data_get_name(format_, packet_start_, + &name_.getStructReference()) < 0) { throw errors::MalformedPacketException(); } } @@ -65,8 +65,8 @@ class ContentObject : public Packet { throw errors::MalformedPacketException(); } - if (hicn_data_get_name(format_, packet_start_, name_.getStructReference()) < - 0) { + if (hicn_data_get_name(format_, packet_start_, + &name_.getStructReference()) < 0) { throw errors::MalformedPacketException(); } } diff --git a/libtransport/includes/hicn/transport/core/interest.h b/libtransport/includes/hicn/transport/core/interest.h index b7ce3c3a0..9e6cdccb9 100644 --- a/libtransport/includes/hicn/transport/core/interest.h +++ b/libtransport/includes/hicn/transport/core/interest.h @@ -29,14 +29,6 @@ const uint32_t MAX_AGGREGATED_INTEREST = 128; class Interest : public Packet /*, public std::enable_shared_from_this*/ { - private: - struct InterestManifestHeader { - /* This can be 16 bits, but we use 32 bits for alignment */ - uint32_t n_suffixes; - /* Followed by the list of prefixes to ask */ - /* ... */ - }; - public: using Ptr = std::shared_ptr; @@ -51,7 +43,7 @@ class Interest Interest(CopyBufferOp op, Args &&...args) : Packet(op, std::forward(args)...) { if (hicn_interest_get_name(format_, packet_start_, - name_.getStructReference()) < 0) { + &name_.getStructReference()) < 0) { throw errors::MalformedPacketException(); } } @@ -60,7 +52,7 @@ class Interest Interest(WrapBufferOp op, Args &&...args) : Packet(op, std::forward(args)...) { if (hicn_interest_get_name(format_, packet_start_, - name_.getStructReference()) < 0) { + &name_.getStructReference()) < 0) { throw errors::MalformedPacketException(); } } @@ -108,6 +100,12 @@ class Interest uint32_t numberOfSuffixes(); + uint32_t *getRequestBitmap(); + + void setRequestBitmap(const uint32_t *request_bitmap); + + bool isValid(); + auto shared_from_this() { return utils::shared_from(this); } private: diff --git a/libtransport/includes/hicn/transport/core/io_module.h b/libtransport/includes/hicn/transport/core/io_module.h index 817d96d00..31da0b882 100644 --- a/libtransport/includes/hicn/transport/core/io_module.h +++ b/libtransport/includes/hicn/transport/core/io_module.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -48,13 +49,12 @@ class IoModule : utils::NonCopyable { mtu_(1500), output_interface_(""), content_store_reserved_(5000) { - inet_address_.v4.as_u32 = htonl(0x7f00001); + inet_address_.v4.as_u32 = portability::host_to_net(0x7f00001); inet6_address_.v6.as_u8[15] = 0x01; } public: static IoModule *load(const char *); - static bool unload(IoModule *); public: virtual ~IoModule(); @@ -65,6 +65,7 @@ class IoModule : utils::NonCopyable { virtual void init(Connector::PacketReceivedCallback &&receive_callback, Connector::PacketSentCallback &&sent_callback, + Connector::OnCloseCallback &&close_callback, Connector::OnReconnectCallback &&reconnect_callback, asio::io_service &io_service, const std::string &app_name = "Libtransport") = 0; @@ -108,11 +109,6 @@ class IoModule : utils::NonCopyable { const std::string &getOutputInterface() { return output_interface_; } -#ifndef ANDROID - private: - void *handle_; -#endif - protected: ip_address_t inet_address_; ip_address_t inet6_address_; diff --git a/libtransport/includes/hicn/transport/core/name.h b/libtransport/includes/hicn/transport/core/name.h index 5cb4efd10..cf6d3097c 100644 --- a/libtransport/includes/hicn/transport/core/name.h +++ b/libtransport/includes/hicn/transport/core/name.h @@ -46,6 +46,7 @@ class Name { friend class Packet; friend class ContentObject; friend class Interest; + friend class Prefix; static const uint32_t standard_name_string_length = 100; @@ -102,11 +103,11 @@ class Name { int getAddressFamily() const; private: - TRANSPORT_ALWAYS_INLINE const NameStruct *getConstStructReference() const { - return &name_; + TRANSPORT_ALWAYS_INLINE const NameStruct &getConstStructReference() const { + return name_; } - TRANSPORT_ALWAYS_INLINE NameStruct *getStructReference() { return &name_; } + TRANSPORT_ALWAYS_INLINE NameStruct &getStructReference() { return name_; } NameStruct name_; }; diff --git a/libtransport/includes/hicn/transport/core/prefix.h b/libtransport/includes/hicn/transport/core/prefix.h index 13401e1a8..778491a31 100644 --- a/libtransport/includes/hicn/transport/core/prefix.h +++ b/libtransport/includes/hicn/transport/core/prefix.h @@ -25,13 +25,9 @@ class Prefix { public: Prefix(); - Prefix(const char *prefix); - Prefix(const std::string &prefix); - Prefix(std::string &&prefix); - - Prefix(std::string &prefix, uint16_t prefix_length); + Prefix(const std::string &prefix, uint16_t prefix_length); Prefix(const core::Name &content_name, uint16_t prefix_length); @@ -39,6 +35,8 @@ class Prefix { bool operator==(const Prefix &prefix) const; + bool operator!=(const Prefix &prefix) const { return !operator==(prefix); } + std::unique_ptr toSockaddr() const; uint16_t getPrefixLength() const; @@ -47,26 +45,22 @@ class Prefix { std::string getNetwork() const; - int contains(const ip_address_t &content_name) const; + Prefix &setNetwork(const std::string &network); - int contains(const core::Name &content_name) const; + int getAddressFamily() const; - Name getName() const; + bool contains(const ip_address_t &content_name) const; - Name getRandomName() const; + bool contains(const core::Name &content_name) const; Name getName(const core::Name &mask, const core::Name &components, const core::Name &content_name) const; Name mapName(const core::Name &content_name) const; - Prefix &setNetwork(std::string &network); - - int getAddressFamily() const; - - Prefix &setAddressFamily(int address_family); - + Name makeName() const; Name makeRandomName() const; + Name makeNameWithIndex(std::uint64_t index) const; const ip_prefix_t &toIpPrefixStruct() const; @@ -74,8 +68,10 @@ class Prefix { static bool checkPrefixLengthAndAddressFamily(uint16_t prefix_length, int family); - void buildPrefix(std::string &prefix, uint16_t prefix_length, int family); + void buildPrefix(const std::string &prefix, uint16_t prefix_length, + int family); + private: ip_prefix_t ip_prefix_; }; diff --git a/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt b/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt index 1acaadcf0..43f95a466 100644 --- a/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt +++ b/libtransport/includes/hicn/transport/interfaces/CMakeLists.txt @@ -24,11 +24,4 @@ list(APPEND HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/notification.h ) -if (${OPENSSL_VERSION} VERSION_EQUAL "1.1.1a" OR ${OPENSSL_VERSION} VERSION_GREATER "1.1.1a") - list(APPEND HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/p2psecure_socket_producer.h - ${CMAKE_CURRENT_SOURCE_DIR}/p2psecure_socket_consumer.h - ) -endif() - set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) diff --git a/libtransport/includes/hicn/transport/interfaces/global_conf_interface.h b/libtransport/includes/hicn/transport/interfaces/global_conf_interface.h index a9fe6fac6..e1465d375 100644 --- a/libtransport/includes/hicn/transport/interfaces/global_conf_interface.h +++ b/libtransport/includes/hicn/transport/interfaces/global_conf_interface.h @@ -26,8 +26,16 @@ namespace transport { namespace interface { namespace global_config { -static const constexpr char io_module_section[] = "io_module"; -void parseConfigurationFile(const std::string& path = ""); +class GlobalConfigInterface { + public: + GlobalConfigInterface(); + ~GlobalConfigInterface(); + void parseConfigurationFile(const std::string& path = "") const; + + private: + void libtransportConfigInit() const; + void libtransportConfigTerminate() const; +}; class ConfigurationObject { public: @@ -49,7 +57,9 @@ class ConfigurationObject { class IoModuleConfiguration : public ConfigurationObject { public: - std::string getKey() const override { return io_module_section; } + static inline char section[] = "io_module"; + + std::string getKey() const override { return section; } std::string name; std::vector search_path; diff --git a/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_consumer.h b/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_consumer.h deleted file mode 100644 index a67634c1e..000000000 --- a/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_consumer.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -namespace transport { - -namespace interface { - -class P2PSecureConsumerSocket : public ConsumerSocket { - public: - P2PSecureConsumerSocket(int handshake_protocol, int transport_protocol); - ~P2PSecureConsumerSocket() = default; - void registerPrefix(const Prefix &producer_namespace); -}; - -} // namespace interface -} // end namespace transport diff --git a/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h b/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h deleted file mode 100644 index e197a3658..000000000 --- a/libtransport/includes/hicn/transport/interfaces/p2psecure_socket_producer.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2021 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -namespace transport { - -namespace interface { - -class P2PSecureProducerSocket : public ProducerSocket { - public: - P2PSecureProducerSocket(); - P2PSecureProducerSocket(bool rtc, std::string &keystore_path, - std::string &keystore_pwd); - ~P2PSecureProducerSocket() = default; -}; - -} // namespace interface - -} // end namespace transport diff --git a/libtransport/includes/hicn/transport/interfaces/portal.h b/libtransport/includes/hicn/transport/interfaces/portal.h index 1a22b1f1d..bca78cb3b 100644 --- a/libtransport/includes/hicn/transport/interfaces/portal.h +++ b/libtransport/includes/hicn/transport/interfaces/portal.h @@ -95,7 +95,7 @@ class Portal : private utils::NonCopyable { * parameter. Otherwise ConsumerCallback::onTimeout will be used. */ void sendInterest( - core::Interest::Ptr &&interest, + core::Interest::Ptr &interest, uint32_t lifetime, OnContentObjectCallback &&on_content_object_callback = UNSET_CALLBACK, OnInterestTimeoutCallback &&on_interest_timeout_callback = UNSET_CALLBACK); diff --git a/libtransport/includes/hicn/transport/interfaces/socket_consumer.h b/libtransport/includes/hicn/transport/interfaces/socket_consumer.h index e26fe5a85..d997634da 100644 --- a/libtransport/includes/hicn/transport/interfaces/socket_consumer.h +++ b/libtransport/includes/hicn/transport/interfaces/socket_consumer.h @@ -250,6 +250,9 @@ class ConsumerSocket : private utils::NonCopyable { int setSocketOption(int socket_option_key, interface::IcnObserver *socket_option_value); + int setSocketOption(int socket_option_key, + const std::shared_ptr &socket_option_value); + int setSocketOption( int socket_option_key, const std::shared_ptr &socket_option_value); @@ -282,6 +285,9 @@ class ConsumerSocket : private utils::NonCopyable { int getSocketOption(int socket_option_key, IcnObserver **socket_option_value); + int getSocketOption(int socket_option_key, + std::shared_ptr &socket_option_value); + int getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value); diff --git a/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h b/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h index 0e19ae629..da8eafcd9 100644 --- a/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h +++ b/libtransport/includes/hicn/transport/interfaces/socket_options_default_values.h @@ -53,9 +53,9 @@ static constexpr uint32_t key_locator_size = 60; // bytes static constexpr uint32_t limit_guard = 80; // bytes static constexpr uint32_t digest_size = 34; // bytes static constexpr uint32_t max_out_of_order_segments = 3; // content object -static constexpr uint32_t unverified_interval = 60000; // milliseconds -static constexpr double unverified_ratio = 0.2; -static constexpr uint32_t manifest_capacity = 20; +static constexpr uint32_t manifest_max_capacity = 30; +static constexpr uint32_t manifest_factor_relevant = 100; +static constexpr uint32_t manifest_factor_alert = 20; // RAAQM static constexpr int sample_number = 30; diff --git a/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h b/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h index 6cba50d8b..a14c8414c 100644 --- a/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h +++ b/libtransport/includes/hicn/transport/interfaces/socket_options_keys.h @@ -46,6 +46,9 @@ typedef enum { LOW_RATE_AND_BESTPATH = 25, LOW_RATE_AND_REPLICATION = 26, LOW_RATE_AND_ALL_FWD_STRATEGIES = 27, + FEC_ONLY_LOW_RES_LOSSES = 28, + DELAY_AND_BESTPATH = 29, + DELAY_AND_REPLICATION = 30, } RtcTransportRecoveryStrategies; typedef enum { @@ -58,23 +61,23 @@ typedef enum { INTEREST_LIFETIME = 107, CONTENT_OBJECT_EXPIRY_TIME = 108, MAX_SEGMENT_SIZE = 109, - MIN_WINDOW_SIZE = 111, - MAX_WINDOW_SIZE = 112, - CURRENT_WINDOW_SIZE = 113, - ASYNC_MODE = 114, - MAKE_MANIFEST = 115, - PORTAL = 116, - RUNNING = 117, - APPLICATION_BUFFER = 118, - HASH_ALGORITHM = 119, - SIGNER = 121, - VERIFIER = 122, - UNVERIFIED_INTERVAL = 123, - UNVERIFIED_RATIO = 124, - STATS_INTERVAL = 125, - SUFFIX_STRATEGY = 126, - PACKET_FORMAT = 127, - FEC_TYPE = 128, + MIN_WINDOW_SIZE = 110, + MAX_WINDOW_SIZE = 111, + CURRENT_WINDOW_SIZE = 112, + ASYNC_MODE = 113, + PORTAL = 114, + RUNNING = 115, + APPLICATION_BUFFER = 116, + HASH_ALGORITHM = 117, + SIGNER = 118, + VERIFIER = 119, + MANIFEST_MAX_CAPACITY = 120, + MANIFEST_FACTOR_RELEVANT = 121, + MANIFEST_FACTOR_ALERT = 122, + STATS_INTERVAL = 123, + SUFFIX_STRATEGY = 124, + PACKET_FORMAT = 125, + FEC_TYPE = 126, } GeneralTransportOptions; typedef enum { @@ -139,6 +142,8 @@ typedef enum { typedef enum { RECOVERY_STRATEGY = 901, AGGREGATED_DATA = 902, + CONTENT_SHARING_MODE = 903, + AGGREGATED_INTERESTS = 904, } RtcTransportOptions; } // namespace interface diff --git a/libtransport/includes/hicn/transport/interfaces/socket_producer.h b/libtransport/includes/hicn/transport/interfaces/socket_producer.h index 77b89742a..be08c9a0b 100644 --- a/libtransport/includes/hicn/transport/interfaces/socket_producer.h +++ b/libtransport/includes/hicn/transport/interfaces/socket_producer.h @@ -123,6 +123,10 @@ class ProducerSocket : private utils::NonCopyable { int setSocketOption(int socket_option_key, const std::shared_ptr &socket_option_value); + int setSocketOption( + int socket_option_key, + const std::shared_ptr &socket_option_value); + int setSocketOption(int socket_option_key, const std::string &socket_option_value); @@ -154,6 +158,9 @@ class ProducerSocket : private utils::NonCopyable { int getSocketOption(int socket_option_key, std::shared_ptr &socket_option_value); + int getSocketOption(int socket_option_key, + std::shared_ptr &socket_option_value); + int getSocketOption(int socket_option_key, std::string &socket_option_value); int getSocketOption(int socket_option_key, diff --git a/libtransport/includes/hicn/transport/interfaces/statistics.h b/libtransport/includes/hicn/transport/interfaces/statistics.h index 4d9e1bfe2..e83aa9a27 100644 --- a/libtransport/includes/hicn/transport/interfaces/statistics.h +++ b/libtransport/includes/hicn/transport/interfaces/statistics.h @@ -73,10 +73,10 @@ class TransportStatistics { } TRANSPORT_ALWAYS_INLINE void updateAverageRtt( - const utils::SteadyTime::Milliseconds &rtt) { - auto rtt_milliseconds = rtt.count(); - average_rtt_ = - (alpha_ * average_rtt_) + ((1. - alpha_) * double(rtt_milliseconds)); + const utils::SteadyTime::Microseconds &rtt) { + double rtt_milliseconds = double(rtt.count()) / 1000.0; + + average_rtt_ = (alpha_ * average_rtt_) + ((1. - alpha_) * rtt_milliseconds); } TRANSPORT_ALWAYS_INLINE void updateAverageWindowSize(double current_window) { diff --git a/libtransport/includes/hicn/transport/portability/CMakeLists.txt b/libtransport/includes/hicn/transport/portability/CMakeLists.txt index 7a688b1f1..d29ec737c 100644 --- a/libtransport/includes/hicn/transport/portability/CMakeLists.txt +++ b/libtransport/includes/hicn/transport/portability/CMakeLists.txt @@ -15,6 +15,8 @@ list(APPEND HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/c_portability.h ${CMAKE_CURRENT_SOURCE_DIR}/portability.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu.h + ${CMAKE_CURRENT_SOURCE_DIR}/cache.h + ${CMAKE_CURRENT_SOURCE_DIR}/endianess.h ) list(APPEND SOURCE_FILES diff --git a/libtransport/includes/hicn/transport/portability/cache.h b/libtransport/includes/hicn/transport/portability/cache.h new file mode 100644 index 000000000..ae113c7d6 --- /dev/null +++ b/libtransport/includes/hicn/transport/portability/cache.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2022 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace transport { +namespace portability { +namespace cache { + +/** + * @Prefetch utilities + */ + +/* Default cache line size of 64 bytes. */ +#ifndef LOG2_CACHE_LINE_BYTES +static constexpr const std::size_t klog2_cache_line_bytes = 6; +#else +static constexpr const std::size_t klog2_cache_line_bytes = + LOG2_CACHE_LINE_BYTES; +#endif + +/* How much data prefetch instruction prefetches */ +#ifndef LOG2_CACHE_PREFETCH_BYTES +static constexpr const std::size_t klog2_cache_prefetch_bytes = + klog2_cache_line_bytes; +#else +static constexpr const std::size_t klog2_cache_prefetch_bytes = + LOG2_CACHE_PREFETCH_BYTES; +#endif + +/* Default cache line fill buffers. */ +#ifndef N_PREFETCHES +static constexpr const std::size_t kn_prefetches = 16; +#else +static constexpr const std::size_t kn_prefetches = N_PREFETCHES; +#endif + +static constexpr const std::size_t kcache_line_bytes = + (1 << klog2_cache_line_bytes); +static constexpr const std::size_t kcache_prefetch_bytes = + (1 << klog2_cache_prefetch_bytes); + +static constexpr const int READ = 0; +static constexpr const int LOAD = 0; /* alias for read */ +static constexpr const int WRITE = 1; +static constexpr const int STORE = 1; /* alias for write */ + +#if defined(__GNUC__) || defined(__clang__) +// Clang & GCC + +template +static inline void _prefetch(uint8_t *addr, std::size_t n, std::size_t size) { + if (size > n * kcache_prefetch_bytes) { + __builtin_prefetch(addr + n * kcache_prefetch_bytes, type, + /* locality */ 3); + } +} + +template +static inline void prefetch(T *addr, std::size_t size) { + uint8_t *_addr = reinterpret_cast(addr); + + _prefetch(_addr, 0, size); + _prefetch(_addr, 1, size); + _prefetch(_addr, 2, size); + _prefetch(_addr, 3, size); +} +#endif + +} // namespace cache +} // namespace portability +} // namespace transport \ No newline at end of file diff --git a/libtransport/includes/hicn/transport/portability/endianess.h b/libtransport/includes/hicn/transport/portability/endianess.h new file mode 100644 index 000000000..c18ac82cf --- /dev/null +++ b/libtransport/includes/hicn/transport/portability/endianess.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace transport { +namespace portability { + +#if (__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__) +static constexpr const bool kIsBigEndian = false; +static constexpr const bool kIsLittleEndian = true; +#else +static constexpr const bool kIsBigEndian = true; +static constexpr const bool kIsLittleEndian = false; +#endif + +template +inline T bswap(T value) { + throw errors::RuntimeException("Not implemented"); +} + +template <> +inline int16_t bswap(int16_t value) { + return __builtin_bswap16(value); +} + +template <> +inline int32_t bswap(int32_t value) { + return __builtin_bswap32(value); +} + +template <> +inline int64_t bswap(int64_t value) { + return __builtin_bswap64(value); +} + +template <> +inline uint16_t bswap(uint16_t value) { + return __builtin_bswap16(value); +} + +template <> +inline uint32_t bswap(uint32_t value) { + return __builtin_bswap32(value); +} + +template <> +inline uint64_t bswap(uint64_t value) { + return __builtin_bswap64(value); +} + +template +inline T host_to_net(T value) { + if constexpr (kIsLittleEndian) { + return bswap(value); + } + + return value; +} + +template +inline T net_to_host(T value) { + if constexpr (kIsLittleEndian) { + return bswap(value); + } + + return value; +} + +} // namespace portability +} // namespace transport \ No newline at end of file diff --git a/libtransport/includes/hicn/transport/portability/portability.h b/libtransport/includes/hicn/transport/portability/portability.h index b093f8892..fd6eca4de 100644 --- a/libtransport/includes/hicn/transport/portability/portability.h +++ b/libtransport/includes/hicn/transport/portability/portability.h @@ -26,6 +26,7 @@ #include +namespace transport { namespace portability { // Generalize warning push/pop. @@ -66,3 +67,4 @@ namespace portability { #endif } // namespace portability +} // namespace transport \ No newline at end of file diff --git a/libtransport/includes/hicn/transport/utils/chrono_typedefs.h b/libtransport/includes/hicn/transport/utils/chrono_typedefs.h index ddfbd00cd..14234eaa1 100644 --- a/libtransport/includes/hicn/transport/utils/chrono_typedefs.h +++ b/libtransport/includes/hicn/transport/utils/chrono_typedefs.h @@ -79,7 +79,7 @@ class Time { public: using Clock = T; using TimePoint = typename Clock::time_point; - using Rep = double; + using Rep = uint64_t; using Seconds = std::chrono::duration; using Milliseconds = std::chrono::duration; using Microseconds = std::chrono::duration; diff --git a/libtransport/includes/hicn/transport/utils/color.h b/libtransport/includes/hicn/transport/utils/color.h new file mode 100644 index 000000000..3e8d93e14 --- /dev/null +++ b/libtransport/includes/hicn/transport/utils/color.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +namespace utils { + +#define foreach_modifier \ + _(RESET, 0) \ + _(BOLD, 1) \ + _(FG_DEFAULT, 39) \ + _(FG_BLACK, 30) \ + _(FG_RED, 31) \ + _(FG_GREEN, 32) \ + _(FG_YELLOW, 33) \ + _(FG_BLUE, 34) \ + _(FG_MAGENTA, 35) \ + _(FG_CYAN, 36) \ + _(FG_LIGHT_GRAY, 37) \ + _(FG_DARK_GRAY, 90) \ + _(FG_LIGHT_RED, 91) \ + _(FG_LIGHT_GREEN, 92) \ + _(FG_LIGHT_YELLOW, 93) \ + _(FG_LIGHT_BLUE, 94) \ + _(FG_LIGHT_MAGENTA, 95) \ + _(FG_LIGHT_CYAN, 96) \ + _(FG_WHITE, 97) \ + _(BG_RED, 41) \ + _(BG_GREEN, 42) \ + _(BG_BLUE, 44) \ + _(BG_DEFAULT, 49) + +class ColorModifier { + static inline const std::size_t n_modifiers = 23; + static inline const char format_string_start[] = "\033["; + static inline const char format_string_end[] = "m"; + + public: + enum class Code { +#define _(name, value) name = value, + foreach_modifier +#undef _ + }; + + static inline std::array code_array = { +#define _(name, value) Code::name, + foreach_modifier +#undef _ + }; + + static Code getRandomModifier() { + static std::random_device rd; + static std::mt19937 gen(rd()); + static std::uniform_int_distribution<> distr(4, 17); + + return code_array[distr(gen)]; + } + + ColorModifier(Code code) : code_(code), color_string_() { + std::stringstream ss; + if (std::getenv("COLORTERM") != nullptr) { + ss << format_string_start << static_cast(code_) << format_string_end; + color_string_ = ss.str(); + } + } + + ColorModifier() : ColorModifier(getRandomModifier()) {} + + friend std::ostream& operator<<(std::ostream& os, const ColorModifier& mod) { + return os << mod.color_string_; + } + + private: + Code code_; + std::string color_string_; +}; + +} // namespace utils \ No newline at end of file diff --git a/libtransport/includes/hicn/transport/utils/event_thread.h b/libtransport/includes/hicn/transport/utils/event_thread.h index 2cd2f3aca..164c853a5 100644 --- a/libtransport/includes/hicn/transport/utils/event_thread.h +++ b/libtransport/includes/hicn/transport/utils/event_thread.h @@ -29,16 +29,16 @@ class EventThread { EventThread(asio::io_service& io_service, bool detached = false) : internal_io_service_(nullptr), io_service_(std::ref(io_service)), - work_(std::make_unique(io_service_)), + work_guard_(asio::make_work_guard(io_service_.get())), thread_(nullptr), detached_(detached) { run(); } - EventThread(bool detached = false) + explicit EventThread(bool detached = false) : internal_io_service_(std::make_unique()), io_service_(std::ref(*internal_io_service_)), - work_(std::make_unique(io_service_)), + work_guard_(asio::make_work_guard(io_service_.get())), thread_(nullptr), detached_(detached) { run(); @@ -47,22 +47,12 @@ class EventThread { EventThread(const EventThread&) = delete; EventThread& operator=(const EventThread&) = delete; - EventThread(EventThread&& other) + EventThread(EventThread&& other) noexcept : internal_io_service_(std::move(other.internal_io_service_)), io_service_(std::move(other.io_service_)), - work_(std::move(other.work_)), + work_guard_(std::move(other.work_guard_)), thread_(std::move(other.thread_)), - detached_(std::move(other.detached_)) {} - - EventThread& operator=(EventThread&& other) { - internal_io_service_ = std::move(other.internal_io_service_); - io_service_ = std::move(other.io_service_); - work_ = std::move(other.work_); - thread_ = std::move(other.thread_); - detached_ = other.detached_; - - return *this; - } + detached_(other.detached_) {} ~EventThread() { stop(); } @@ -89,16 +79,16 @@ class EventThread { template void add(Func&& f) { - io_service_.get().post(std::forward(f)); + io_service_.get().post(std::forward(f)); } template void tryRunHandlerNow(Func&& f) { - io_service_.get().dispatch(std::forward(f)); + io_service_.get().dispatch(std::forward(f)); } template - void addAndWaitForExecution(Func&& f) { + void addAndWaitForExecution(Func&& f) const { auto promise = std::promise(); auto future = promise.get_future(); @@ -111,7 +101,7 @@ class EventThread { } void stop() { - work_.reset(); + add([this]() { work_guard_.reset(); }); if (thread_ && thread_->joinable()) { thread_->join(); @@ -120,14 +110,14 @@ class EventThread { thread_.reset(); } - bool stopped() { return io_service_.get().stopped(); } + bool stopped() const { return io_service_.get().stopped(); } asio::io_service& getIoService() { return io_service_; } private: std::unique_ptr internal_io_service_; std::reference_wrapper io_service_; - std::unique_ptr work_; + asio::executor_work_guard work_guard_; std::unique_ptr thread_; bool detached_; }; diff --git a/libtransport/includes/hicn/transport/utils/linux.h b/libtransport/includes/hicn/transport/utils/linux.h index 03d29c1db..14ef179ac 100644 --- a/libtransport/includes/hicn/transport/utils/linux.h +++ b/libtransport/includes/hicn/transport/utils/linux.h @@ -44,7 +44,7 @@ static TRANSPORT_ALWAYS_INLINE int retrieveInterfaceAddress( uint16_t prefix = 0; memcpy(&prefix, tmp->sin6_addr.s6_addr, sizeof(uint16_t)); - if (htons(LINK_LOCAL_PREFIX) != prefix) { + if (portability::host_to_net(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); diff --git a/libtransport/includes/hicn/transport/utils/thread_pool.h b/libtransport/includes/hicn/transport/utils/thread_pool.h index e4e47209c..76218ff09 100644 --- a/libtransport/includes/hicn/transport/utils/thread_pool.h +++ b/libtransport/includes/hicn/transport/utils/thread_pool.h @@ -29,8 +29,11 @@ class ThreadPool : public NonCopyable { std::size_t n_threads = std::thread::hardware_concurrency()) : workers_(n_threads > 0 ? n_threads : 1) {} + ~ThreadPool() = default; + std::size_t getNThreads() const { return workers_.size(); } EventThread &getWorker(std::size_t i) { return workers_.at(i); } + std::vector &getWorkers() { return workers_; } private: std::vector workers_; -- cgit 1.2.3-korg