diff options
Diffstat (limited to 'apps/hiperf/src/common.h')
-rw-r--r-- | apps/hiperf/src/common.h | 315 |
1 files changed, 196 insertions, 119 deletions
diff --git a/apps/hiperf/src/common.h b/apps/hiperf/src/common.h index e6ba526f9..0f96bef1f 100644 --- a/apps/hiperf/src/common.h +++ b/apps/hiperf/src/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-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: @@ -15,27 +15,28 @@ #pragma once -#include <hicn/transport/auth/identity.h> #include <hicn/transport/auth/signer.h> #include <hicn/transport/config.h> #include <hicn/transport/core/content_object.h> #include <hicn/transport/core/interest.h> #include <hicn/transport/interfaces/global_conf_interface.h> -#include <hicn/transport/interfaces/p2psecure_socket_consumer.h> -#include <hicn/transport/interfaces/p2psecure_socket_producer.h> #include <hicn/transport/interfaces/socket_consumer.h> #include <hicn/transport/interfaces/socket_producer.h> #include <hicn/transport/utils/chrono_typedefs.h> +#include <hicn/transport/utils/color.h> #include <hicn/transport/utils/literals.h> #ifndef _WIN32 #include <hicn/transport/utils/daemonizator.h> #endif +#include <hicn/apps/utils/logger.h> + #include <asio.hpp> #include <cmath> #include <fstream> #include <iomanip> +#include <iostream> #include <sstream> #include <string> #include <unordered_set> @@ -43,43 +44,151 @@ #ifndef ERROR_SUCCESS #define ERROR_SUCCESS 0 #endif -#define ERROR_SETUP -5 -#define MIN_PROBE_SEQ 0xefffffff - -using namespace transport::interface; -using namespace transport::auth; -using namespace transport::core; - -static inline uint64_t _ntohll(const uint64_t *input) { - uint64_t return_val; - uint8_t *tmp = (uint8_t *)&return_val; - - tmp[0] = *input >> 56; - tmp[1] = *input >> 48; - tmp[2] = *input >> 40; - tmp[3] = *input >> 32; - tmp[4] = *input >> 24; - tmp[5] = *input >> 16; - tmp[6] = *input >> 8; - tmp[7] = *input >> 0; - - return return_val; -} +static constexpr int ERROR_SETUP = -5; +static constexpr uint32_t MIN_PROBE_SEQ = 0xefffffff; +static constexpr uint32_t RTC_HEADER_SIZE = 12; +static constexpr uint32_t FEC_HEADER_MAX_SIZE = 36; +static constexpr uint32_t HIPERF_MTU = 1500; + +namespace hiperf { + +using transport::core::Packet; +using transport::core::Prefix; + +/** + * Logger + */ +template <typename D, typename ConfType, typename ParentType> +class Base : public std::stringbuf, public std::ostream { + protected: + static inline const char separator[] = "| "; + + Base(ParentType &parent, asio::io_service &io_service, int identifier) + : std::stringbuf(), + std::ostream(this), + parent_(parent), + configuration_(parent_.getConfig()), + io_service_(io_service), + identifier_(identifier), + name_id_(D::getContextType() + std::to_string(identifier_)), + flow_name_(configuration_.name_.makeNameWithIndex(identifier_)) { + std::stringstream begin; + std::stringstream end; + if (configuration_.colored_) { + begin << color_mod_ << bold_mod_; + end << end_mod_; + } else { + begin << ""; + end << ""; + } + + begin << "|" << name_id_ << separator; + begin_ = begin.str(); + end_ = end.str(); + } + + Base(Base &&other) noexcept + : parent_(other.parent_), + configuration_(other.configuration_), + io_service_(other.io_service_), + identifier_(other.identifier_), + name_id_(std::move(other.name_id_)), + flow_name_(other.flow_name_) {} + + ~Base() {} + + /*************************************************************** + * std::stringbuf sync override + ***************************************************************/ + + int sync() override { + auto string = str(); + asio::post(io_service_, + [this, string]() { LoggerInfo() << begin_ << string << end_; }); + str(""); + + return 0; + } + + std::ostream &getOutputStream() { return *this; } -static inline uint64_t _htonll(const uint64_t *input) { - return (_ntohll(input)); + // Members initialized by the constructor + ParentType &parent_; + ConfType &configuration_; + asio::io_service &io_service_; + int identifier_; + std::string name_id_; + transport::core::Name flow_name_; + std::string begin_; + std::string end_; + + // Members initialized by the in-class initializer + utils::ColorModifier color_mod_; + utils::ColorModifier bold_mod_{utils::ColorModifier::Code::BOLD}; + utils::ColorModifier end_mod_{utils::ColorModifier::Code::RESET}; +}; + +static inline int ensureFlows(const Prefix &prefix, std::size_t flows) { + int ret = ERROR_SUCCESS; + + // Make sure the provided prefix length not allows to accomodate the + // provided number of flows. + uint16_t max_ip_addr_len_bits; + uint16_t log2_n_flow; + u64 max_n_flow; + if (prefix.getAddressFamily() == AF_INET) { + max_ip_addr_len_bits = IPV4_ADDR_LEN_BITS; + } else if (prefix.getAddressFamily() == AF_INET6) { + max_ip_addr_len_bits = IPV6_ADDR_LEN_BITS; + } else { + LoggerErr() << "Error: unknown address family."; + ret = ERROR_SETUP; + goto END; + } + + log2_n_flow = max_ip_addr_len_bits - prefix.getPrefixLength(); + max_n_flow = log2_n_flow < 64 ? (1 << log2_n_flow) : ~0ULL; + + if (flows > max_n_flow) { + LoggerErr() << "Error: the provided prefix length does not allow to " + "accomodate the provided number of flows (" + << flows << " > " << max_n_flow << ")."; + ret = ERROR_SETUP; + } + +END: + return ret; } -namespace hiperf { +/** + * Class to retrieve the maximum payload size given the MTU and packet headers. + */ +class PayloadSize { + public: + PayloadSize(Packet::Format format, std::size_t mtu = HIPERF_MTU) + : mtu_(mtu), format_(format) {} + + std::size_t getPayloadSizeMax(std::size_t transport_size = 0, + std::size_t fec_size = 0, + std::size_t signature_size = 0) { + return mtu_ - Packet::getHeaderSizeFromFormat(format_, signature_size) - + transport_size - fec_size; + } + + private: + std::size_t mtu_; + Packet::Format format_; +}; /** * Class for handling the production rate for the RTC producer. */ class Rate { public: - Rate() : rate_kbps_(0) {} + Rate() {} + ~Rate() {} - Rate(const std::string &rate) { + explicit Rate(const std::string &rate) { std::size_t found = rate.find("kbps"); if (found != std::string::npos) { rate_kbps_ = std::stof(rate.substr(0, found)); @@ -107,7 +216,7 @@ class Rate { } private: - float rate_kbps_; + float rate_kbps_ = 0.0; }; struct packet_t { @@ -115,103 +224,71 @@ struct packet_t { uint32_t size; }; +struct Configuration { + Prefix name_{"b001::abcd/64"}; + std::string passphrase_; + std::string aggr_interest_passphrase_; + bool rtc_{false}; + uint16_t port_{0}; + bool aggregated_data_{false}; + Packet::Format packet_format_{ + transport::interface::default_values::packet_format}; + uint32_t parallel_flows_{1}; + bool colored_{true}; +}; + /** * Container for command line configuration for hiperf client. */ -struct ClientConfiguration { - ClientConfiguration() - : name("b001::abcd", 0), - beta(-1.f), - drop_factor(-1.f), - window(-1), - producer_certificate(""), - passphrase(""), - receive_buffer(nullptr), - receive_buffer_size_(128 * 1024), - download_size(0), - report_interval_milliseconds_(1000), - transport_protocol_(CBR), - rtc_(false), - test_mode_(false), - relay_(false), - secure_(false), - producer_prefix_(), - interest_lifetime_(500), - relay_name_("c001::abcd/64"), - output_stream_mode_(false), - port_(0) {} - - Name name; - double beta; - double drop_factor; - double window; - std::string producer_certificate; - std::string passphrase; - std::shared_ptr<utils::MemBuf> receive_buffer; - std::size_t receive_buffer_size_; - std::size_t download_size; - std::uint32_t report_interval_milliseconds_; - TransportProtocolAlgorithms transport_protocol_; - bool rtc_; - bool test_mode_; - bool relay_; - bool secure_; +struct ClientConfiguration : Configuration { + double beta_{-1.f}; + double drop_factor_{-1.f}; + double window_{-1.f}; + std::string producer_certificate_; + std::size_t receive_buffer_size_{128 * 1024}; + std::uint32_t report_interval_milliseconds_{1000}; + transport::interface::TransportProtocolAlgorithms transport_protocol_{ + transport::interface::CBR}; + bool test_mode_{false}; + bool relay_{false}; Prefix producer_prefix_; - uint32_t interest_lifetime_; - Prefix relay_name_; - bool output_stream_mode_; - uint16_t port_; + uint32_t interest_lifetime_{500}; + uint32_t manifest_factor_relevant_{100}; + uint32_t manifest_factor_alert_{20}; + Prefix relay_name_{"c001::abcd/64"}; + bool output_stream_mode_{false}; + uint32_t recovery_strategy_{4}; + bool print_headers_{true}; + std::uint32_t nb_iterations_{ + std::numeric_limits<decltype(nb_iterations_)>::max()}; + bool content_sharing_mode_{false}; + bool aggregated_interests_{false}; }; /** * Container for command line configuration for hiperf server. */ -struct ServerConfiguration { - ServerConfiguration() - : name("b001::abcd/64"), - virtual_producer(true), - manifest(false), - live_production(false), - content_lifetime(600000000_U32), - download_size(20 * 1024 * 1024), - hash_algorithm(CryptoHashType::SHA256), - keystore_name(""), - passphrase(""), - keystore_password("cisco"), - multiphase_produce_(false), - rtc_(false), - interactive_(false), - trace_based_(false), - trace_index_(0), - trace_file_(nullptr), - production_rate_(std::string("2048kbps")), - payload_size_(1400), - secure_(false), - input_stream_mode_(false), - port_(0) {} - - Prefix name; - bool virtual_producer; - bool manifest; - bool live_production; - std::uint32_t content_lifetime; - std::uint32_t download_size; - CryptoHashType hash_algorithm; - std::string keystore_name; - std::string passphrase; - std::string keystore_password; - bool multiphase_produce_; - bool rtc_; - bool interactive_; - bool trace_based_; - std::uint32_t trace_index_; - char *trace_file_; - Rate production_rate_; - std::size_t payload_size_; - bool secure_; - bool input_stream_mode_; - uint16_t port_; +struct ServerConfiguration : Configuration { + bool virtual_producer_{true}; + std::uint32_t manifest_max_capacity_{0}; + bool live_production_{false}; + std::uint32_t content_lifetime_{ + transport::interface::default_values::content_object_expiry_time}; + std::uint32_t download_size_{20 * 1024 * 1024}; + transport::auth::CryptoHashType hash_algorithm_{ + transport::auth::CryptoHashType::SHA256}; + std::string keystore_name_; + std::string keystore_password_{"cisco"}; + bool multiphase_produce_{false}; + bool interactive_{false}; + bool trace_based_{false}; + std::uint32_t trace_index_{0}; + char *trace_file_{nullptr}; + Rate production_rate_{"2048kbps"}; + std::size_t payload_size_{1384}; + bool input_stream_mode_{false}; std::vector<struct packet_t> trace_; + std::string fec_type_; }; } // namespace hiperf |