aboutsummaryrefslogtreecommitdiffstats
path: root/apps/ping
diff options
context:
space:
mode:
Diffstat (limited to 'apps/ping')
-rw-r--r--apps/ping/.clang-format2
-rw-r--r--apps/ping/CMakeLists.txt39
-rw-r--r--apps/ping/src/ping_client.cc538
-rw-r--r--apps/ping/src/ping_server.cc311
4 files changed, 446 insertions, 444 deletions
diff --git a/apps/ping/.clang-format b/apps/ping/.clang-format
index cd21e2017..adc73c6fd 100644
--- a/apps/ping/.clang-format
+++ b/apps/ping/.clang-format
@@ -1,4 +1,4 @@
-# Copyright (c) 2017-2021 Cisco and/or its affiliates.
+# 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:
diff --git a/apps/ping/CMakeLists.txt b/apps/ping/CMakeLists.txt
index 42f7f98c1..ab3fdf56d 100644
--- a/apps/ping/CMakeLists.txt
+++ b/apps/ping/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2017-2019 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:
@@ -12,28 +12,49 @@
# limitations under the License.
if (NOT DISABLE_EXECUTABLES)
+##############################################################
+# Compiler options
+##############################################################
+set(COMPILER_OPTIONS
+ ${DEFAULT_COMPILER_OPTIONS}
+)
+
+##############################################################
+# Libraries to link
+##############################################################
list (APPEND PING_LIBRARIES
- ${LIBTRANSPORT_LIBRARIES}
- ${CMAKE_THREAD_LIBS_INIT}
- ${WSOCK32_LIBRARY}
- ${WS2_32_LIBRARY}
+ 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 ${LIBTRANSPORT_INCLUDE_DIRS}
- DEPENDS ${DEPENDENCIES}
+ 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 ${LIBTRANSPORT_INCLUDE_DIRS}
- DEPENDS ${DEPENDENCIES}
+ 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
index 24e0bf3ed..08938734b 100644
--- a/apps/ping/src/ping_client.cc
+++ b/apps/ping/src/ping_client.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 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:
@@ -13,18 +13,22 @@
* 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>
-#define SYN_STATE 1
-#define ACK_STATE 2
+static constexpr uint32_t SYN_STATE = 1;
namespace transport {
@@ -32,147 +36,131 @@ namespace core {
namespace ping {
-typedef std::map<uint64_t, uint64_t> SendTimeMap;
-typedef auth::AsymmetricVerifier Verifier;
+using SendTimeMap = std::map<uint64_t, utils::SteadyTime::TimePoint>;
+using Verifier = auth::AsymmetricVerifier;
class Configuration {
public:
- uint64_t interestLifetime_;
- uint64_t pingInterval_;
- uint64_t maxPing_;
- uint64_t first_suffix_;
- std::string name_;
+ 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_;
- uint16_t srcPort_;
- uint16_t dstPort_;
- bool verbose_;
- bool dump_;
- bool jump_;
- bool open_;
- bool always_syn_;
- bool always_ack_;
- bool quiet_;
- uint32_t jump_freq_;
- uint32_t jump_size_;
- uint8_t ttl_;
-
- Configuration() {
- interestLifetime_ = 500; // ms
- pingInterval_ = 1000000; // us
- maxPing_ = 10; // number of interests
- first_suffix_ = 0;
- name_ = "b001::1"; // string
- srcPort_ = 9695;
- dstPort_ = 8080;
- verbose_ = false;
- dump_ = false;
- jump_ = false;
- open_ = false;
- always_syn_ = false;
- always_ack_ = false;
- quiet_ = false;
- jump_freq_ = 0;
- jump_size_ = 0;
- ttl_ = 64;
- }
+ 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 : interface::Portal::ConsumerCallback {
+class Client : public interface::Portal::TransportCallback {
public:
- Client(Configuration *c)
- : portal_(), signals_(portal_.getIoService(), SIGINT) {
+ 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
- portal_.connect();
- portal_.setConsumerCallback(this);
-
signals_.async_wait(std::bind(&Client::afterSignal, this));
- timer_.reset(new asio::steady_timer(portal_.getIoService()));
- config_ = c;
- sequence_number_ = config_->first_suffix_;
- last_jump_ = 0;
- processed_ = 0;
- state_ = SYN_STATE;
- sent_ = 0;
- received_ = 0;
- timedout_ = 0;
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() {}
+ virtual ~Client() = default;
void ping() {
- std::cout << "start ping" << std::endl;
- doPing();
- portal_.runEventsLoop();
+ 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 = std::chrono::steady_clock::now();
+ auto t0 = utils::SteadyTime::now();
if (verifier_.verifyPacket(&object)) {
- auto t1 = std::chrono::steady_clock::now();
- auto dt =
- std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0);
- std::cout << "Verification time: " << dt.count() << std::endl;
- std::cout << "<<< Signature Ok." << std::endl;
+ auto t1 = utils::SteadyTime::now();
+ auto dt = utils::SteadyTime::getDurationUs(t0, t1);
+ LoggerInfo() << "Verification time: " << dt.count();
+ LoggerInfo() << "<<< Signature Ok.";
} else {
- std::cout << "<<< Signature verification failed!" << std::endl;
+ LoggerErr() << "<<< Signature verification failed!";
}
}
- auto it = send_timestamps_.find(interest.getName().getSuffix());
- if (it != send_timestamps_.end()) {
- rtt = std::chrono::duration_cast<std::chrono::microseconds>(
- std::chrono::steady_clock::now().time_since_epoch())
- .count() -
- it->second;
+ 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 (config_->verbose_) {
- std::cout << "<<< recevied object. " << std::endl;
- std::cout << "<<< interest name: " << interest.getName()
- << " src port: " << interest.getSrcPort()
- << " dst port: " << interest.getDstPort()
- << " flags: " << interest.printFlags() << std::endl;
- std::cout << "<<< object name: " << object.getName()
- << " src port: " << object.getSrcPort()
- << " dst port: " << object.getDstPort()
- << " flags: " << object.printFlags() << " path label "
- << object.getPathLabel() << " ("
- << (object.getPathLabel() >> 24) << ")"
- << " TTL: " << (int)object.getTTL() << std::endl;
- } else if (!config_->quiet_) {
- std::cout << "<<< received object. " << std::endl;
- std::cout << "<<< round trip: " << rtt << " [us]" << std::endl;
- std::cout << "<<< interest name: " << interest.getName() << std::endl;
- std::cout << "<<< object name: " << object.getName() << std::endl;
- std::cout << "<<< content object size: "
- << object.payloadSize() + object.headerSize() << " [bytes]"
- << std::endl;
+ 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 (config_->dump_) {
- std::cout << "----- interest dump -----" << std::endl;
+ if (LoggerIsOn(3)) {
+ LoggerInfo() << "----- interest dump -----";
interest.dump();
- std::cout << "-------------------------" << std::endl;
- std::cout << "----- object dump -------" << std::endl;
+ LoggerInfo() << "-------------------------";
+ LoggerInfo() << "----- object dump -------";
object.dump();
- std::cout << "-------------------------" << std::endl;
- }
-
- if (!config_->quiet_) std::cout << std::endl;
-
- if (!config_->always_syn_) {
- if (object.testSyn() && object.testAck() && state_ == SYN_STATE) {
- state_ = ACK_STATE;
- }
+ LoggerInfo() << "-------------------------";
}
+ LoggerVerbose(1) << "\n";
received_++;
processed_++;
@@ -182,178 +170,221 @@ class Client : interface::Portal::ConsumerCallback {
}
void onTimeout(Interest::Ptr &interest, const Name &name) override {
- if (config_->verbose_) {
- std::cout << "### timeout for " << name
- << " src port: " << interest->getSrcPort()
- << " dst port: " << interest->getDstPort()
- << " flags: " << interest->printFlags() << std::endl;
- } else if (!config_->quiet_) {
- std::cout << "### timeout for " << name << std::endl;
+ if (LoggerIsOn(2)) {
+ LoggerInfo() << "### timeout for " << name;
+ } else if (LoggerIsOn(1)) {
+ LoggerInfo() << "### timeout for " << name;
}
- if (config_->dump_) {
- std::cout << "----- interest dump -----" << std::endl;
+ if (LoggerIsOn(3)) {
+ LoggerInfo() << "----- interest dump -----";
interest->dump();
- std::cout << "-------------------------" << std::endl;
+ LoggerInfo() << "-------------------------";
}
-
- if (!config_->quiet_) std::cout << std::endl;
+ LoggerVerbose(1) << "\n";
timedout_++;
processed_++;
- if (processed_ >= config_->maxPing_) {
- afterSignal();
- }
+ if (processed_ >= config_->maxPing_) afterSignal();
}
- void onError(std::error_code ec) override {}
+ 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() {
- const Name interest_name(config_->name_, (uint32_t)sequence_number_);
- hicn_format_t format;
- if (interest_name.getAddressFamily() == AF_INET) {
- format = HF_INET_TCP;
+ 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 {
- format = HF_INET6_TCP;
+ if (signer_) format = Packet::toAHFormat(format);
}
- auto interest = std::make_shared<Interest>(interest_name, format);
+ auto interest = core::PacketManager<>::getInstance().getPacket<Interest>(
+ format, signer_ ? signer_->getSignatureFieldSize() : 0);
+ interest->setName(interest_name);
interest->setLifetime(uint32_t(config_->interestLifetime_));
- interest->resetFlags();
- if (config_->open_ || config_->always_syn_) {
- if (state_ == SYN_STATE) {
- interest->setSyn();
- } else if (state_ == ACK_STATE) {
- interest->setAck();
- }
- } else if (config_->always_ack_) {
- interest->setAck();
+ 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->setSrcPort(config_->srcPort_);
- interest->setDstPort(config_->dstPort_);
- interest->setTTL(config_->ttl_);
-
- if (config_->verbose_) {
- std::cout << ">>> send interest " << interest->getName()
- << " src port: " << interest->getSrcPort()
- << " dst port: " << interest->getDstPort()
- << " flags: " << interest->printFlags()
- << " TTL: " << (int)interest->getTTL() << std::endl;
- } else if (!config_->quiet_) {
- std::cout << ">>> send interest " << interest->getName() << std::endl;
+ interest->appendSuffix(sequence_number);
+ send_timestamps_[sequence_number] = utils::SteadyTime::now();
}
- if (config_->dump_) {
- std::cout << "----- interest dump -----" << std::endl;
+ if (LoggerIsOn(3)) {
+ LoggerInfo() << "----- interest dump -----";
interest->dump();
- std::cout << "-------------------------" << std::endl;
+ LoggerInfo() << "-------------------------";
}
- if (!config_->quiet_) std::cout << std::endl;
+ interest->encodeSuffixes();
+ if (signer_) signer_->signPacket(interest.get());
+ portal_.sendInterest(interest, interest->getLifetime());
- send_timestamps_[sequence_number_] =
- std::chrono::duration_cast<std::chrono::microseconds>(
- std::chrono::steady_clock::now().time_since_epoch())
- .count();
-
- portal_.sendInterest(std::move(interest));
-
- sequence_number_++;
- sent_++;
-
- if (sent_ < config_->maxPing_) {
+ if (!traffic_generator_->hasFinished()) {
this->timer_->expires_from_now(
std::chrono::microseconds(config_->pingInterval_));
- this->timer_->async_wait([this](const std::error_code e) { doPing(); });
+ this->timer_->async_wait([this](const std::error_code e) {
+ if (!e) {
+ doPing();
+ }
+ });
}
}
void afterSignal() {
- std::cout << "Stop ping" << std::endl;
- std::cout << "Sent: " << sent_ << " Received: " << received_
- << " Timeouts: " << timedout_ << std::endl;
- portal_.stopEventsLoop();
+ LoggerInfo() << "Stopping ping...";
+ LoggerInfo() << "Sent: " << traffic_generator_->getSentCount()
+ << " Received: " << received_ << " Timeouts: " << timedout_;
+ io_service_.stop();
}
void reset() {
- timer_.reset(new asio::steady_timer(portal_.getIoService()));
- sequence_number_ = config_->first_suffix_;
+ timer_.reset(new asio::steady_timer(portal_.getThread().getIoService()));
+ traffic_generator_->reset();
last_jump_ = 0;
processed_ = 0;
state_ = SYN_STATE;
- sent_ = 0;
received_ = 0;
timedout_ = 0;
}
private:
SendTimeMap send_timestamps_;
+ asio::io_service io_service_;
interface::Portal portal_;
asio::signal_set signals_;
- uint64_t sequence_number_;
- uint64_t last_jump_;
- uint64_t processed_;
- uint32_t state_;
- uint32_t sent_;
- uint32_t received_;
- uint32_t timedout_;
- std::unique_ptr<asio::steady_timer> timer_;
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() {
- std::cout << "usage: hicn-consumer-ping [options]" << std::endl;
- std::cout << "PING options" << std::endl;
- std::cout
- << "-i <val> ping interval in microseconds (default 1000000ms)"
- << std::endl;
- std::cout << "-m <val> maximum number of pings to send (default 10)"
- << std::endl;
- std::cout << "-s <val> sorce port (default 9695)" << std::endl;
- std::cout << "-d <val> destination port (default 8080)" << std::endl;
- std::cout << "-t <val> set packet ttl (default 64)" << std::endl;
- std::cout << "-O open tcp connection (three way handshake) "
- "(default false)"
- << std::endl;
- std::cout << "-S send always syn messages (default false)"
- << std::endl;
- std::cout << "-A send always ack messages (default false)"
- << std::endl;
- std::cout << "HICN options" << std::endl;
- std::cout << "-n <val> hicn name (default b001::1)" << std::endl;
- std::cout
- << "-l <val> interest lifetime in milliseconds (default 500ms)"
- << std::endl;
- std::cout << "OUTPUT options" << std::endl;
- std::cout << "-V verbose, prints statistics about the "
- "messagges sent and received (default false)"
- << std::endl;
- std::cout << "-D dump, dumps sent and received packets "
- "(default false)"
- << std::endl;
- std::cout << "-q quiet, not prints (default false)"
- << std::endl;
- std::cout << "-H prints this message" << std::endl;
+ 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 main(int argc, char *argv[]) {
+int start(int argc, char *argv[]) {
#ifdef _WIN32
WSADATA wsaData = {0};
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
- Configuration *c = new Configuration();
+ transport::interface::global_config::GlobalConfigInterface global_conf;
+
+ auto c = std::make_unique<Configuration>();
int opt;
std::string producer_certificate = "";
- while ((opt = getopt(argc, argv, "j::t:i:m:s:d:n:l:f:c:SAOqVDH")) != -1) {
+ 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 't':
- c->ttl_ = (uint8_t)std::stoi(optarg);
+ 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);
@@ -362,13 +393,7 @@ int main(int argc, char *argv[]) {
c->maxPing_ = std::stoi(optarg);
break;
case 'f':
- c->first_suffix_ = std::stoul(optarg);
- break;
- case 's':
- c->srcPort_ = std::stoi(optarg);
- break;
- case 'd':
- c->dstPort_ = std::stoi(optarg);
+ c->first_suffix_ = uint32_t(std::stoul(optarg));
break;
case 'n':
c->name_ = optarg;
@@ -376,53 +401,48 @@ int main(int argc, char *argv[]) {
case 'l':
c->interestLifetime_ = std::stoi(optarg);
break;
- case 'V':
- c->verbose_ = true;
- ;
- break;
- case 'D':
- c->dump_ = true;
- break;
- case 'O':
- c->always_syn_ = false;
- c->always_ack_ = false;
- c->open_ = true;
- break;
- case 'S':
- c->always_syn_ = true;
- c->always_ack_ = false;
- c->open_ = false;
+ case 'c':
+ c->certificate_ = std::string(optarg);
break;
- case 'A':
- c->always_syn_ = false;
- c->always_ack_ = true;
- c->open_ = false;
+ case 'z':
+ io_config.name = optarg;
break;
- case 'q':
- c->quiet_ = true;
- c->verbose_ = false;
- c->dump_ = false;
+ case 'F':
+ conf_file = optarg;
break;
- case 'c':
- c->certificate_ = std::string(optarg);
+ 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;
- case 'H':
+ }
default:
help();
exit(EXIT_FAILURE);
}
}
- auto ping = std::make_unique<Client>(c);
+ /**
+ * 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();
- std::cout
- << "Elapsed time: "
- << std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count()
- << std::endl;
+ LoggerInfo() << "Elapsed time: "
+ << utils::SteadyTime::getDurationMs(t0, t1).count() << "ms";
#ifdef _WIN32
WSACleanup();
@@ -437,5 +457,5 @@ int main(int argc, char *argv[]) {
} // namespace transport
int main(int argc, char *argv[]) {
- return transport::core::ping::main(argc, argv);
+ return transport::core::ping::start(argc, argv);
}
diff --git a/apps/ping/src/ping_server.cc b/apps/ping/src/ping_server.cc
index baf9c6698..900da18ca 100644
--- a/apps/ping/src/ping_server.cc
+++ b/apps/ping/src/ping_server.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 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:
@@ -21,10 +21,13 @@
#include <openssl/applink.c>
#endif
-#include <hicn/transport/auth/identity.h>
+#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>
@@ -36,170 +39,128 @@ namespace interface {
using HashAlgorithm = core::HashAlgorithm;
using CryptoSuite = auth::CryptoSuite;
-auth::Identity setProducerIdentity(std::string keystore_name,
- std::string keystore_password,
- auth::CryptoHashType hash_algorithm) {
- if (access(keystore_name.c_str(), F_OK) != -1) {
- return auth::Identity(keystore_name, keystore_password, hash_algorithm);
- } else {
- return auth::Identity(keystore_name, keystore_password,
- CryptoSuite::RSA_SHA256, 1024, 365, "producer-test");
- }
-}
-
class CallbackContainer {
- const std::size_t log2_content_object_buffer_size = 12;
-
- public:
- CallbackContainer(const Name &prefix, uint32_t object_size, bool verbose,
- bool dump, bool quite, bool flags, bool reset, uint8_t ttl,
- auth::Identity *identity, bool sign, uint32_t lifetime)
- : buffer_(object_size, 'X'),
- content_objects_((std::uint32_t)(1 << log2_content_object_buffer_size)),
- mask_((std::uint16_t)(1 << log2_content_object_buffer_size) - 1),
- content_objects_index_(0),
- verbose_(verbose),
- dump_(dump),
- quite_(quite),
- flags_(flags),
- reset_(reset),
- ttl_(ttl),
- identity_(identity),
- sign_(sign) {
- core::Packet::Format format;
-
- if (prefix.getAddressFamily() == AF_INET) {
- format = core::Packet::Format::HF_INET_TCP;
- if (sign_) {
- format = core::Packet::Format::HF_INET_TCP_AH;
- }
- } else {
- format = core::Packet::Format::HF_INET6_TCP;
- if (sign_) {
- format = core::Packet::Format::HF_INET6_TCP_AH;
- }
+ 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();
}
- for (int i = 0; i < (1 << log2_content_object_buffer_size); i++) {
- content_objects_[i] = std::make_shared<ContentObject>(
- prefix, format, 0, (const uint8_t *)buffer_.data(), buffer_.size());
- content_objects_[i]->setLifetime(lifetime);
+ if (LoggerIsOn(3)) {
+ LoggerInfo() << "----- object dump -----";
+ content_object->dump();
+ LoggerInfo() << "-----------------------";
}
+
+ if (sign_ && signer_) signer_->signPacket(content_object.get());
+ return content_object;
}
- void processInterest(ProducerSocket &p, const Interest &interest,
+ 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 (verbose_) {
- std::cout << "<<< received interest " << interest.getName()
- << " src port: " << interest.getSrcPort()
- << " dst port: " << interest.getDstPort()
- << " flags: " << interest.printFlags()
- << "TTL: " << (int)interest.getTTL() << std::endl;
- } else if (!quite_) {
- std::cout << "<<< received interest " << interest.getName() << std::endl;
+ 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 (dump_) {
- std::cout << "----- interest dump -----" << std::endl;
- interest.dump();
- std::cout << "-------------------------" << std::endl;
+ if (LoggerIsOn(2)) {
+ LoggerInfo() << "<<< received interest " << interest.getName()
+ << " suffixes in manifest: " << interest.numberOfSuffixes();
+ } else if (LoggerIsOn(1)) {
+ LoggerInfo() << "<<< received interest " << interest.getName();
}
- if (interest.testRst()) {
- std::cout << "!!!got a reset, I don't reply" << std::endl;
- } else {
- auto &content_object = content_objects_[content_objects_index_++ & mask_];
-
- content_object->setName(interest.getName());
- content_object->setLifetime(lifetime);
- content_object->setLocator(interest.getLocator());
- content_object->setSrcPort(interest.getDstPort());
- content_object->setDstPort(interest.getSrcPort());
- content_object->setTTL(ttl_);
-
- if (!sign_) {
- content_object->resetFlags();
- }
-
- if (flags_) {
- if (interest.testSyn()) {
- content_object->setSyn();
- content_object->setAck();
- } else if (interest.testAck()) {
- content_object->setAck();
- } // here I may need to handle the FIN flag;
- } else if (reset_) {
- content_object->setRst();
- }
+ if (LoggerIsOn(3)) {
+ LoggerInfo() << "----- interest dump -----";
+ interest.dump();
+ LoggerInfo() << "-------------------------";
+ }
- if (verbose_) {
- std::cout << ">>> send object " << content_object->getName()
- << " src port: " << content_object->getSrcPort()
- << " dst port: " << content_object->getDstPort()
- << " flags: " << content_object->printFlags()
- << " TTL: " << (int)content_object->getTTL() << std::endl;
- } else if (!quite_) {
- std::cout << ">>> send object " << content_object->getName()
- << std::endl;
- }
+ if (!interest.isValid()) throw std::runtime_error("Bad interest format");
+ Name name = interest.getName();
- if (dump_) {
- std::cout << "----- object dump -----" << std::endl;
- content_object->dump();
- std::cout << "-----------------------" << std::endl;
- }
+ 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(_);
- if (!quite_) std::cout << std::endl;
+ interest_manifest_foreach_suffix(interest.getIntManifestHeader(), suffix,
+ _) {
+ name.setSuffix(*suffix);
- if (sign_) {
- identity_->getSigner()->signPacket(content_object.get());
+ auto content_object = createContentObject(name, lifetime, interest);
+ p.produce(*content_object);
}
-
- p.produce(*content_object);
}
+
+ LoggerVerbose(1) << "\n";
}
private:
std::string buffer_;
- std::vector<std::shared_ptr<ContentObject>> content_objects_;
- std::uint16_t mask_;
- std::uint16_t content_objects_index_;
- bool verbose_;
- bool dump_;
- bool quite_;
- bool flags_;
- bool reset_;
- uint8_t ttl_;
- auth::Identity *identity_;
+ auth::Signer *signer_;
bool sign_;
+ std::unique_ptr<auth::Verifier> verifier_;
};
void help() {
- std::cout << "usage: hicn-preoducer-ping [options]" << std::endl;
- std::cout << "PING options" << std::endl;
- std::cout << "-s <val> object content size (default 1350B)" << std::endl;
- std::cout << "-n <val> hicn name (default b001::/64)" << std::endl;
- std::cout << "-f set tcp flags according to the flag received "
- "(default false)"
- << std::endl;
- std::cout << "-l data lifetime" << std::endl;
- std::cout << "-r always reply with a reset flag (default false)"
- << std::endl;
- std::cout << "-t set ttl (default 64)" << std::endl;
- std::cout << "OUTPUT options" << std::endl;
- std::cout << "-V verbose, prints statistics about the messagges sent "
- "and received (default false)"
- << std::endl;
- std::cout << "-D dump, dumps sent and received packets (default false)"
- << std::endl;
- std::cout << "-q quite, not prints (default false)" << std::endl;
+ 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
- std::cout << "-d daemon mode" << std::endl;
+ LoggerInfo() << "-d daemon mode";
#endif
- std::cout << "-H prints this message" << std::endl;
+ LoggerInfo() << "-H prints this message";
}
-int main(int argc, char **argv) {
+int ping_main(int argc, char **argv) {
+ transport::interface::global_config::GlobalConfigInterface global_conf;
#ifdef _WIN32
WSADATA wsaData = {0};
WSAStartup(MAKEWORD(2, 2), &wsaData);
@@ -208,59 +169,41 @@ int main(int argc, char **argv) {
#endif
std::string name_prefix = "b001::0/64";
std::string delimiter = "/";
- bool verbose = false;
- bool dump = false;
- bool quite = false;
- bool flags = false;
- bool reset = false;
uint32_t object_size = 1250;
- uint8_t ttl = 64;
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, "s:n:t:l:qfrVDdHk:p:")) != -1) {
+ 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:qfrVDHk:p:")) != -1) {
+ 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 't':
- ttl = (uint8_t)std::stoi(optarg);
- break;
case 'l':
data_lifetime = std::stoi(optarg);
break;
- case 'V':
- verbose = true;
- break;
- case 'D':
- dump = true;
- break;
- case 'q':
- verbose = false;
- dump = false;
- quite = true;
- break;
#ifndef _WIN32
case 'd':
daemon = true;
break;
#endif
- case 'f':
- flags = true;
- break;
- case 'r':
- reset = true;
- break;
case 'k':
keystore_path = optarg;
sign = true;
@@ -268,7 +211,12 @@ int main(int argc, char **argv) {
case 'p':
keystore_password = optarg;
break;
- case 'H':
+ case 'z':
+ io_config.name = optarg;
+ break;
+ case 'F':
+ conf_file = optarg;
+ break;
default:
help();
exit(EXIT_FAILURE);
@@ -281,6 +229,16 @@ int main(int argc, char **argv) {
}
#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);
@@ -290,21 +248,23 @@ int main(int argc, char **argv) {
if (object_size > 1350) object_size = 1350;
CallbackContainer *stubs;
- auth::Identity identity = setProducerIdentity(
- keystore_path, keystore_password, auth::CryptoHashType::SHA256);
+ std::unique_ptr<auth::Signer> signer;
if (sign) {
- stubs = new CallbackContainer(n, object_size, verbose, dump, quite, flags,
- reset, ttl, &identity, sign, data_lifetime);
+ signer = std::make_unique<auth::AsymmetricSigner>(keystore_path,
+ keystore_password);
+ stubs = new CallbackContainer(n, object_size, signer.get(), sign,
+ passphrase, data_lifetime);
} else {
- auth::Identity *identity = nullptr;
- stubs = new CallbackContainer(n, object_size, verbose, dump, quite, flags,
- reset, ttl, identity, sign, data_lifetime);
+ 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,
@@ -313,12 +273,13 @@ int main(int argc, char **argv) {
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 &) {
- std::cout << "STOPPING!!" << std::endl;
+ LoggerInfo() << "STOPPING!!";
p.stop();
io_service.stop();
});
@@ -336,5 +297,5 @@ int main(int argc, char **argv) {
} // end namespace transport
int main(int argc, char **argv) {
- return transport::interface::main(argc, argv);
+ return transport::interface::ping_main(argc, argv);
}