diff options
Diffstat (limited to 'apps/ping')
-rw-r--r-- | apps/ping/.clang-format | 14 | ||||
-rw-r--r-- | apps/ping/CMakeLists.txt | 60 | ||||
-rw-r--r-- | apps/ping/src/ping_client.cc | 461 | ||||
-rw-r--r-- | apps/ping/src/ping_server.cc | 301 |
4 files changed, 836 insertions, 0 deletions
diff --git a/apps/ping/.clang-format b/apps/ping/.clang-format new file mode 100644 index 000000000..adc73c6fd --- /dev/null +++ b/apps/ping/.clang-format @@ -0,0 +1,14 @@ +# 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. + +BasedOnStyle: Google diff --git a/apps/ping/CMakeLists.txt b/apps/ping/CMakeLists.txt new file mode 100644 index 000000000..ab3fdf56d --- /dev/null +++ b/apps/ping/CMakeLists.txt @@ -0,0 +1,60 @@ +# 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: +# +# 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. + +if (NOT DISABLE_EXECUTABLES) +############################################################## +# Compiler options +############################################################## +set(COMPILER_OPTIONS + ${DEFAULT_COMPILER_OPTIONS} +) + +############################################################## +# Libraries to link +############################################################## + list (APPEND PING_LIBRARIES + PRIVATE ${LIBHICN_LIBRARIES} + PRIVATE ${LIBTRANSPORT_LIBRARIES} + PRIVATE ${CMAKE_THREAD_LIBS_INIT} + PRIVATE ${WSOCK32_LIBRARY} + PRIVATE ${WS2_32_LIBRARY} + ) + +############################################################## +# Build ping server +############################################################## + build_executable(hicn-ping-server + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/ping_server.cc + LINK_LIBRARIES ${PING_LIBRARIES} + INCLUDE_DIRS + PRIVATE ${THIRD_PARTY_INCLUDE_DIRS} ${COMMON_INCLUDE_DIRS} + DEPENDS ${DEPENDENCIES} ${THIRD_PARTY_DEPENDENCIES} + COMPONENT ${HICN_APPS} + LINK_FLAGS ${LINK_FLAGS} + COMPILE_OPTIONS ${COMPILER_OPTIONS} + ) + +############################################################## +# Build ping client +############################################################## + build_executable(hicn-ping-client + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/ping_client.cc + LINK_LIBRARIES ${PING_LIBRARIES} + INCLUDE_DIRS + PRIVATE ${THIRD_PARTY_INCLUDE_DIRS} ${COMMON_INCLUDE_DIRS} + DEPENDS ${DEPENDENCIES} ${THIRD_PARTY_DEPENDENCIES} + COMPONENT ${HICN_APPS} + LINK_FLAGS ${LINK_FLAGS} + COMPILE_OPTIONS ${COMPILER_OPTIONS} + ) +endif ()
\ No newline at end of file diff --git a/apps/ping/src/ping_client.cc b/apps/ping/src/ping_client.cc new file mode 100644 index 000000000..08938734b --- /dev/null +++ b/apps/ping/src/ping_client.cc @@ -0,0 +1,461 @@ +/* + * 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: + * + * 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/apps/utils/logger.h> +#include <hicn/transport/auth/signer.h> +#include <hicn/transport/auth/verifier.h> +#include <hicn/transport/core/global_object_pool.h> +#include <hicn/transport/core/interest.h> +#include <hicn/transport/interfaces/global_conf_interface.h> +#include <hicn/transport/interfaces/portal.h> +#include <hicn/transport/utils/chrono_typedefs.h> +#include <hicn/transport/utils/traffic_generator.h> + +#include <asio/signal_set.hpp> +#include <asio/steady_timer.hpp> +#include <chrono> +#include <map> + +static constexpr uint32_t SYN_STATE = 1; + +namespace transport { + +namespace core { + +namespace ping { + +using SendTimeMap = std::map<uint64_t, utils::SteadyTime::TimePoint>; +using Verifier = auth::AsymmetricVerifier; + +class Configuration { + public: + static constexpr char TRAFFIC_GENERATOR_RAND[] = "RANDOM"; + + uint32_t num_int_manifest_suffixes_ = + 0; // Number of suffixes in interest manifest (suffix in the header + // is not included in the count) + uint64_t interestLifetime_ = 500; // ms + uint64_t pingInterval_ = 1000000; // us + uint32_t maxPing_ = 10; // number of interests + uint32_t first_suffix_ = 0; + std::string name_ = "b001::1"; + std::string certificate_; + std::string passphrase_; + std::string traffic_generator_type_; + bool jump_ = false; + uint32_t jump_freq_ = 0; + uint32_t jump_size_ = 0; + hicn_packet_format_t packet_format_ = HICN_PACKET_FORMAT_DEFAULT; + + Configuration() = default; +}; + +class Client : public interface::Portal::TransportCallback { + public: + explicit Client(Configuration *c) + : signals_(io_service_, SIGINT), + config_(c), + timer_(std::make_unique<asio::steady_timer>( + portal_.getThread().getIoService())) { + // Let the main thread to catch SIGINT + signals_.async_wait(std::bind(&Client::afterSignal, this)); + + if (!c->certificate_.empty()) { + verifier_.useCertificate(c->certificate_); + } + + // If interst manifest, sign it + if (c->num_int_manifest_suffixes_ != 0) { + assert(!c->passphrase_.empty()); + signer_ = std::make_unique<auth::SymmetricSigner>( + auth::CryptoSuite::HMAC_SHA256, c->passphrase_); + } + + if (c->traffic_generator_type_ == + std::string(Configuration::TRAFFIC_GENERATOR_RAND)) { + traffic_generator_ = + std::make_unique<RandomTrafficGenerator>(config_->maxPing_); + } else { + traffic_generator_ = std::make_unique<IncrSuffixTrafficGenerator>( + config_->name_, config_->first_suffix_, config_->maxPing_); + } + } + + virtual ~Client() = default; + + void ping() { + LoggerInfo() << "Starting ping..."; + + portal_.getThread().add([this]() { + portal_.connect(); + portal_.registerTransportCallback(this); + doPing(); + }); + + io_service_.run(); + } + + void onInterest(Interest &interest) override { + LoggerInfo() << "Unexpected interest received."; + } + + void onContentObject(Interest &interest, ContentObject &object) override { + uint64_t rtt = 0; + + if (!config_->certificate_.empty()) { + auto t0 = utils::SteadyTime::now(); + if (verifier_.verifyPacket(&object)) { + auto t1 = utils::SteadyTime::now(); + auto dt = utils::SteadyTime::getDurationUs(t0, t1); + LoggerInfo() << "Verification time: " << dt.count(); + LoggerInfo() << "<<< Signature Ok."; + } else { + LoggerErr() << "<<< Signature verification failed!"; + } + } + + if (auto it = send_timestamps_.find(interest.getName().getSuffix()); + it != send_timestamps_.end()) { + rtt = + utils::SteadyTime::getDurationUs(it->second, utils::SteadyTime::now()) + .count(); + send_timestamps_.erase(it); + } + + if (LoggerIsOn(2)) { + LoggerInfo() << "<<< recevied object. "; + LoggerInfo() << "<<< interest name: " << interest.getName().getPrefix() + << " (n_suffixes=" << config_->num_int_manifest_suffixes_ + << ")"; + LoggerInfo() << "<<< object name: " << object.getName() << " path label " + << object.getPathLabel() << " (" + << (object.getPathLabel() >> 24) << ")"; + } else if (LoggerIsOn(1)) { + LoggerInfo() << "<<< received object. "; + LoggerInfo() << "<<< round trip: " << rtt << " [us]"; + LoggerInfo() << "<<< interest name: " << interest.getName().getPrefix(); + + LoggerInfo() << "<<< object name: " << object.getName(); + LoggerInfo() << "<<< content object size: " + << object.payloadSize() + object.headerSize() << " [bytes]"; + } + + if (LoggerIsOn(3)) { + LoggerInfo() << "----- interest dump -----"; + interest.dump(); + LoggerInfo() << "-------------------------"; + LoggerInfo() << "----- object dump -------"; + object.dump(); + LoggerInfo() << "-------------------------"; + } + LoggerVerbose(1) << "\n"; + + received_++; + processed_++; + if (processed_ >= config_->maxPing_) { + afterSignal(); + } + } + + void onTimeout(Interest::Ptr &interest, const Name &name) override { + if (LoggerIsOn(2)) { + LoggerInfo() << "### timeout for " << name; + } else if (LoggerIsOn(1)) { + LoggerInfo() << "### timeout for " << name; + } + + if (LoggerIsOn(3)) { + LoggerInfo() << "----- interest dump -----"; + interest->dump(); + LoggerInfo() << "-------------------------"; + } + LoggerVerbose(1) << "\n"; + + timedout_++; + processed_++; + if (processed_ >= config_->maxPing_) afterSignal(); + } + + void onError(const std::error_code &ec) override { + LoggerErr() << "Aborting ping due to internal error: " << ec.message(); + afterSignal(); + } + + void checkFamily(hicn_packet_format_t format, int family) { + switch (HICN_PACKET_FORMAT_GET(format, 0)) { + case IPPROTO_IP: + if (family != AF_INET) throw std::runtime_error("Bad packet format"); + break; + case IPPROTO_IPV6: + if (family != AF_INET6) throw std::runtime_error("Bad packet format"); + break; + default: + throw std::runtime_error("Bad packet format"); + } + } + + void doPing() { + std::string name = traffic_generator_->getPrefix(); + uint32_t sequence_number = traffic_generator_->getSuffix(); + const Name interest_name(name, sequence_number); + + hicn_packet_format_t format = config_->packet_format_; + + switch (format) { + case HICN_PACKET_FORMAT_NEW: + /* Nothing to do */ + break; + case HICN_PACKET_FORMAT_IPV4_TCP: + case HICN_PACKET_FORMAT_IPV6_TCP: + checkFamily(format, interest_name.getAddressFamily()); + break; + default: + throw std::runtime_error("Bad packet format"); + } + + /* + * Eventually add the AH header if a signer is defined. Raise an error + * if format include the AH header but no signer is defined. + */ + if (HICN_PACKET_FORMAT_IS_AH(format)) { + if (!signer_) throw std::runtime_error("Bad packet format"); + } else { + if (signer_) format = Packet::toAHFormat(format); + } + + auto interest = core::PacketManager<>::getInstance().getPacket<Interest>( + format, signer_ ? signer_->getSignatureFieldSize() : 0); + interest->setName(interest_name); + + interest->setLifetime(uint32_t(config_->interestLifetime_)); + + if (LoggerIsOn(2)) { + LoggerInfo() << ">>> send interest " << interest->getName() + << " suffixes in manifest: " + << config_->num_int_manifest_suffixes_; + } else if (LoggerIsOn(1)) { + LoggerInfo() << ">>> send interest " << interest->getName(); + } + LoggerVerbose(1) << "\n"; + + send_timestamps_[sequence_number] = utils::SteadyTime::now(); + for (uint32_t i = 0; i < config_->num_int_manifest_suffixes_ && + !traffic_generator_->hasFinished(); + i++) { + uint32_t sequence_number = traffic_generator_->getSuffix(); + + interest->appendSuffix(sequence_number); + send_timestamps_[sequence_number] = utils::SteadyTime::now(); + } + + if (LoggerIsOn(3)) { + LoggerInfo() << "----- interest dump -----"; + interest->dump(); + LoggerInfo() << "-------------------------"; + } + + interest->encodeSuffixes(); + if (signer_) signer_->signPacket(interest.get()); + portal_.sendInterest(interest, interest->getLifetime()); + + if (!traffic_generator_->hasFinished()) { + this->timer_->expires_from_now( + std::chrono::microseconds(config_->pingInterval_)); + this->timer_->async_wait([this](const std::error_code e) { + if (!e) { + doPing(); + } + }); + } + } + + void afterSignal() { + LoggerInfo() << "Stopping ping..."; + LoggerInfo() << "Sent: " << traffic_generator_->getSentCount() + << " Received: " << received_ << " Timeouts: " << timedout_; + io_service_.stop(); + } + + void reset() { + timer_.reset(new asio::steady_timer(portal_.getThread().getIoService())); + traffic_generator_->reset(); + last_jump_ = 0; + processed_ = 0; + state_ = SYN_STATE; + received_ = 0; + timedout_ = 0; + } + + private: + SendTimeMap send_timestamps_; + asio::io_service io_service_; + interface::Portal portal_; + asio::signal_set signals_; + Configuration *config_; + std::unique_ptr<asio::steady_timer> timer_; + uint64_t last_jump_ = 0; + uint64_t processed_ = 0; + uint32_t state_ = SYN_STATE; + uint32_t received_ = 0; + uint32_t timedout_ = 0; + Verifier verifier_; + std::unique_ptr<auth::Signer> signer_; + std::unique_ptr<TrafficGenerator> traffic_generator_; +}; + +static std::unordered_map<std::string, hicn_packet_format_t> const + packet_format_map = {{"ipv4_tcp", HICN_PACKET_FORMAT_IPV4_TCP}, + {"ipv6_tcp", HICN_PACKET_FORMAT_IPV6_TCP}, + {"new", HICN_PACKET_FORMAT_NEW}}; + +std::string str_tolower(std::string s) { + std::transform(s.begin(), s.end(), s.begin(), + [](unsigned char c) { return std::tolower(c); }); + return s; +} + +void help() { + LoggerInfo() << "usage: hicn-consumer-ping [options]"; + LoggerInfo() << "PING options"; + LoggerInfo() << "-i <val> ping interval in microseconds (default " + "1000000ms)"; + LoggerInfo() + << "-m <val> maximum number of pings to send (default 10)"; + LoggerInfo() << "-a <val> <pass> set the passphrase and the number of " + "suffixes in interest manifest (default 0);"; + LoggerInfo() + << " e.g. '-m 6 -a -2' sends two interest (0 and " + "3) with 2 suffixes each (1,2 and 4,5 respectively)"; + LoggerInfo() << "HICN options"; + LoggerInfo() << "-n <val> hicn name (default b001::1)"; + LoggerInfo() + << "-l <val> interest lifetime in milliseconds (default " + "500ms)"; + LoggerInfo() << "OUTPUT options"; + LoggerInfo() << "-V verbose, prints statistics about the " + "messagges sent and received (default false)"; + LoggerInfo() << "-D dump, dumps sent and received packets " + "(default false)"; + LoggerInfo() << "-q quiet, not prints (default false)"; + LoggerInfo() + << "-z <io_module> IO module to use. Default: hicnlight_module"; + LoggerInfo() << "-F <conf_file> Path to optional configuration file for " + "libtransport"; + LoggerInfo() << "-b <type> Traffic generator type. Use 'RANDOM' for " + "random prefixes and suffixes. Default: sequential suffixes."; + LoggerInfo() + << "-w <packet_format> Packet format (without signature, defaults " + "to IPV6_TCP)"; + LoggerInfo() << "-H prints this message"; +} + +int start(int argc, char *argv[]) { +#ifdef _WIN32 + WSADATA wsaData = {0}; + WSAStartup(MAKEWORD(2, 2), &wsaData); +#endif + + transport::interface::global_config::GlobalConfigInterface global_conf; + + auto c = std::make_unique<Configuration>(); + int opt; + std::string producer_certificate = ""; + + std::string conf_file; + transport::interface::global_config::IoModuleConfiguration io_config; + io_config.name = "hicnlight_module"; + + while ((opt = getopt(argc, argv, "a:b:i:m:f:n:l:c:z:F:w:H")) != -1) { + switch (opt) { + case 'a': + c->num_int_manifest_suffixes_ = std::stoi(optarg); + c->passphrase_ = argv[optind]; + break; + case 'b': + c->traffic_generator_type_ = optarg; + break; + case 'i': + c->pingInterval_ = std::stoi(optarg); + break; + case 'm': + c->maxPing_ = std::stoi(optarg); + break; + case 'f': + c->first_suffix_ = uint32_t(std::stoul(optarg)); + break; + case 'n': + c->name_ = optarg; + break; + case 'l': + c->interestLifetime_ = std::stoi(optarg); + break; + case 'c': + c->certificate_ = std::string(optarg); + break; + case 'z': + io_config.name = optarg; + break; + case 'F': + conf_file = optarg; + break; + case 'w': { + std::string packet_format_s = std::string(optarg); + packet_format_s = str_tolower(packet_format_s); + auto it = packet_format_map.find(std::string(optarg)); + if (it == packet_format_map.end()) + throw std::runtime_error("Bad packet format"); + c->packet_format_ = it->second; + break; + } + default: + help(); + exit(EXIT_FAILURE); + } + } + + /** + * IO module configuration + */ + io_config.set(); + + /** + * Parse config file + */ + global_conf.parseConfigurationFile(conf_file); + + auto ping = std::make_unique<Client>(c.get()); + + auto t0 = std::chrono::steady_clock::now(); + ping->ping(); + auto t1 = std::chrono::steady_clock::now(); + + LoggerInfo() << "Elapsed time: " + << utils::SteadyTime::getDurationMs(t0, t1).count() << "ms"; + +#ifdef _WIN32 + WSACleanup(); +#endif + return 0; +} + +} // namespace ping + +} // namespace core + +} // namespace transport + +int main(int argc, char *argv[]) { + return transport::core::ping::start(argc, argv); +} diff --git a/apps/ping/src/ping_server.cc b/apps/ping/src/ping_server.cc new file mode 100644 index 000000000..900da18ca --- /dev/null +++ b/apps/ping/src/ping_server.cc @@ -0,0 +1,301 @@ +/* + * 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: + * + * 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/interfaces/socket_producer.h> +#ifndef _WIN32 +#include <hicn/transport/utils/daemonizator.h> +#include <unistd.h> +#else +#include <openssl/applink.c> +#endif + +#include <hicn/apps/utils/logger.h> +#include <hicn/transport/auth/signer.h> +#include <hicn/transport/auth/verifier.h> +#include <hicn/transport/core/content_object.h> +#include <hicn/transport/core/global_object_pool.h> +#include <hicn/transport/core/interest.h> +#include <hicn/transport/interfaces/global_conf_interface.h> +#include <hicn/transport/utils/string_tokenizer.h> + +#include <asio.hpp> + +namespace transport { + +namespace interface { + +using HashAlgorithm = core::HashAlgorithm; +using CryptoSuite = auth::CryptoSuite; + +class CallbackContainer { + private: + std::shared_ptr<ContentObject> createContentObject(const Name &name, + uint32_t lifetime, + const Interest &interest) { + auto content_object = + core::PacketManager<>::getInstance().getPacket<ContentObject>( + interest.getFormat(), + (sign_ && signer_) ? signer_->getSignatureFieldSize() : 0); + + content_object->setName(name); + content_object->setLifetime(lifetime); + content_object->setLocator(interest.getLocator()); + + if (LoggerIsOn(2)) { + LoggerInfo() << ">>> send object " << content_object->getName(); + } else if (LoggerIsOn(1)) { + LoggerInfo() << ">>> send object " << content_object->getName(); + } + + if (LoggerIsOn(3)) { + LoggerInfo() << "----- object dump -----"; + content_object->dump(); + LoggerInfo() << "-----------------------"; + } + + if (sign_ && signer_) signer_->signPacket(content_object.get()); + return content_object; + } + + public: + CallbackContainer([[maybe_unused]] const Name &prefix, uint32_t object_size, + auth::Signer *signer, bool sign, std::string passphrase, + [[maybe_unused]] uint32_t lifetime) + : buffer_(object_size, 'X'), signer_(signer), sign_(sign) { + // Verifier for interest manifests + if (!passphrase.empty()) + verifier_ = std::make_unique<auth::SymmetricVerifier>(passphrase); + } + + void processInterest(ProducerSocket &p, Interest &interest, + uint32_t lifetime) { + if (verifier_ && interest.hasManifest()) { + auto t0 = utils::SteadyTime::now(); + if (verifier_->verifyPacket(&interest)) { + auto t1 = utils::SteadyTime::now(); + auto dt = utils::SteadyTime::getDurationUs(t0, t1); + LoggerInfo() << "Verification time: " << dt.count(); + LoggerInfo() << "<<< Signature Ok."; + } else { + LoggerErr() << "<<< Signature verification failed!"; + } + } + + if (LoggerIsOn(2)) { + LoggerInfo() << "<<< received interest " << interest.getName() + << " suffixes in manifest: " << interest.numberOfSuffixes(); + } else if (LoggerIsOn(1)) { + LoggerInfo() << "<<< received interest " << interest.getName(); + } + + if (LoggerIsOn(3)) { + LoggerInfo() << "----- interest dump -----"; + interest.dump(); + LoggerInfo() << "-------------------------"; + } + + if (!interest.isValid()) throw std::runtime_error("Bad interest format"); + Name name = interest.getName(); + + if (!interest.hasManifest()) { // Single interest + auto content_object = createContentObject(name, lifetime, interest); + p.produce(*content_object); + } else { // Interest manifest + uint32_t _; + const uint32_t *suffix = NULL; + UNUSED(_); + + interest_manifest_foreach_suffix(interest.getIntManifestHeader(), suffix, + _) { + name.setSuffix(*suffix); + + auto content_object = createContentObject(name, lifetime, interest); + p.produce(*content_object); + } + } + + LoggerVerbose(1) << "\n"; + } + + private: + std::string buffer_; + auth::Signer *signer_; + bool sign_; + std::unique_ptr<auth::Verifier> verifier_; +}; + +void help() { + LoggerInfo() << "usage: hicn-preoducer-ping [options]"; + LoggerInfo() << "PING options"; + LoggerInfo() << "-s <val> object content size (default 1350B)"; + LoggerInfo() << "-n <val> hicn name (default b001::/64)"; + LoggerInfo() << "-l data lifetime"; + LoggerInfo() << "OUTPUT options"; + LoggerInfo() << "-V verbose, prints statistics about the " + "messagges sent " + " and received (default false)"; + LoggerInfo() << "-D dump, dumps sent and received packets " + "(default false)"; + LoggerInfo() << "-q quiet, not prints (default false)"; + LoggerInfo() + << "-z <io_module> IO module to use. Default: hicnlight_module"; + LoggerInfo() << "-F <conf_file> Path to optional configuration file for " + "libtransport"; +#ifndef _WIN32 + LoggerInfo() << "-d daemon mode"; +#endif + LoggerInfo() << "-H prints this message"; +} + +int ping_main(int argc, char **argv) { + transport::interface::global_config::GlobalConfigInterface global_conf; +#ifdef _WIN32 + WSADATA wsaData = {0}; + WSAStartup(MAKEWORD(2, 2), &wsaData); +#else + bool daemon = false; +#endif + std::string name_prefix = "b001::0/64"; + std::string delimiter = "/"; + uint32_t object_size = 1250; + std::string keystore_path = "./rsa_crypto_material.p12"; + std::string keystore_password = "cisco"; + std::string passphrase = ""; + bool sign = false; + uint32_t data_lifetime = default_values::content_object_expiry_time; + + std::string conf_file; + transport::interface::global_config::IoModuleConfiguration io_config; + io_config.name = "hicnlight_module"; + + int opt; +#ifndef _WIN32 + while ((opt = getopt(argc, argv, "a:s:n:t:l:frdHk:p:z:F:")) != -1) { +#else + while ((opt = getopt(argc, argv, "s:n:t:l:frHk:p:z:F:")) != -1) { +#endif + switch (opt) { + case 'a': + passphrase = optarg; + break; + case 's': + object_size = std::stoi(optarg); + break; + case 'n': + name_prefix = optarg; + break; + case 'l': + data_lifetime = std::stoi(optarg); + break; +#ifndef _WIN32 + case 'd': + daemon = true; + break; +#endif + case 'k': + keystore_path = optarg; + sign = true; + break; + case 'p': + keystore_password = optarg; + break; + case 'z': + io_config.name = optarg; + break; + case 'F': + conf_file = optarg; + break; + default: + help(); + exit(EXIT_FAILURE); + } + } + +#ifndef _WIN32 + if (daemon) { + utils::Daemonizator::daemonize(); + } +#endif + + /** + * IO module configuration + */ + io_config.set(); + + /** + * Parse config file + */ + global_conf.parseConfigurationFile(conf_file); + + core::Prefix producer_namespace(name_prefix); + + utils::StringTokenizer tokenizer(name_prefix, delimiter); + std::string ip_address = tokenizer.nextToken(); + Name n(ip_address); + + if (object_size > 1350) object_size = 1350; + + CallbackContainer *stubs; + std::unique_ptr<auth::Signer> signer; + + if (sign) { + signer = std::make_unique<auth::AsymmetricSigner>(keystore_path, + keystore_password); + stubs = new CallbackContainer(n, object_size, signer.get(), sign, + passphrase, data_lifetime); + } else { + auth::Signer *signer = nullptr; + stubs = new CallbackContainer(n, object_size, signer, sign, passphrase, + data_lifetime); + } + + ProducerSocket p; + p.registerPrefix(producer_namespace); + + p.setSocketOption(GeneralTransportOptions::MANIFEST_MAX_CAPACITY, 0U); + p.setSocketOption(GeneralTransportOptions::OUTPUT_BUFFER_SIZE, 0U); + p.setSocketOption( + ProducerCallbacksOptions::CACHE_MISS, + (ProducerInterestCallback)bind(&CallbackContainer::processInterest, stubs, + std::placeholders::_1, + std::placeholders::_2, data_lifetime)); + + p.connect(); + p.start(); + + asio::io_service io_service; + asio::signal_set signal_set(io_service, SIGINT); + signal_set.async_wait( + [&p, &io_service](const std::error_code &, const int &) { + LoggerInfo() << "STOPPING!!"; + p.stop(); + io_service.stop(); + }); + + io_service.run(); + +#ifdef _WIN32 + WSACleanup(); +#endif + return 0; +} + +} // namespace interface + +} // end namespace transport + +int main(int argc, char **argv) { + return transport::interface::ping_main(argc, argv); +} |