summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/ping/src/ping_client.cc77
-rw-r--r--apps/ping/src/ping_server.cc90
-rw-r--r--hicn-light/src/hicn/core/forwarder.c3
-rw-r--r--hicn-light/src/hicn/core/strategy.c4
-rw-r--r--hicn-light/src/hicn/core/strategy.h2
-rw-r--r--hicn-light/src/hicn/test/test-strategy-best-path.cc2
-rw-r--r--hicn-light/src/hicn/test/test-strategy-replication.cc2
-rw-r--r--lib/includes/hicn/name.h3
-rw-r--r--lib/src/name.c6
-rw-r--r--lib/src/test/test_name.cc2
-rw-r--r--libtransport/includes/hicn/transport/core/interest.h2
-rw-r--r--libtransport/includes/hicn/transport/core/name.h2
-rw-r--r--libtransport/includes/hicn/transport/utils/CMakeLists.txt1
-rw-r--r--libtransport/includes/hicn/transport/utils/traffic_generator.h72
-rw-r--r--libtransport/src/core/interest.cc10
-rw-r--r--libtransport/src/core/name.cc7
-rw-r--r--libtransport/src/test/CMakeLists.txt1
-rw-r--r--libtransport/src/test/test_traffic_generator.cc119
-rw-r--r--libtransport/src/utils/CMakeLists.txt1
-rw-r--r--libtransport/src/utils/traffic_generator.cc87
-rw-r--r--tests/1-node.yml1
-rw-r--r--tests/Makefile13
-rwxr-xr-xtests/config.sh95
-rw-r--r--tests/functional-tests/hicn-light-ping.robot26
24 files changed, 541 insertions, 87 deletions
diff --git a/apps/ping/src/ping_client.cc b/apps/ping/src/ping_client.cc
index 3e95b8896..6599b74cb 100644
--- a/apps/ping/src/ping_client.cc
+++ b/apps/ping/src/ping_client.cc
@@ -20,6 +20,7 @@
#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>
@@ -40,8 +41,11 @@ using Verifier = auth::AsymmetricVerifier;
class Configuration {
public:
- uint64_t num_int_manifest_suffixes_ =
- 0; // Number of suffixes in interest manifest
+ 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
@@ -49,6 +53,7 @@ class Configuration {
std::string name_ = "b001::1";
std::string certificate_;
std::string passphrase_;
+ std::string traffic_generator_type_;
uint16_t srcPort_ = 9695;
uint16_t dstPort_ = 8080;
bool verbose_ = false;
@@ -68,8 +73,7 @@ class Client : private interface::Portal::TransportCallback {
: signals_(io_service_, SIGINT),
config_(c),
timer_(std::make_unique<asio::steady_timer>(
- portal_.getThread().getIoService())),
- sequence_number_(config_->first_suffix_) {
+ portal_.getThread().getIoService())) {
// Let the main thread to catch SIGINT
signals_.async_wait(std::bind(&Client::afterSignal, this));
@@ -83,6 +87,15 @@ class Client : private interface::Portal::TransportCallback {
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;
@@ -128,8 +141,8 @@ class Client : private interface::Portal::TransportCallback {
if (config_->verbose_) {
std::cout << "<<< recevied object. " << std::endl;
- std::cout << "<<< interest name: " << interest.getName()
- << " (n_suffixes=" << interest.numberOfSuffixes() << ")"
+ std::cout << "<<< interest name: " << interest.getName().getPrefix()
+ << " (n_suffixes=" << config_->num_int_manifest_suffixes_ << ")"
<< " src port: " << interest.getSrcPort()
<< " dst port: " << interest.getDstPort() << std::endl;
std::cout << "<<< object name: " << object.getName()
@@ -141,7 +154,8 @@ class Client : private interface::Portal::TransportCallback {
} 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 << "<<< interest name: " << interest.getName().getPrefix()
+ << std::endl;
std::cout << "<<< object name: " << object.getName() << std::endl;
std::cout << "<<< content object size: "
<< object.payloadSize() + object.headerSize() << " [bytes]"
@@ -197,7 +211,10 @@ class Client : private interface::Portal::TransportCallback {
}
void doPing() {
- const Name interest_name(config_->name_, sequence_number_);
+ 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;
if (interest_name.getAddressFamily() == AF_INET) {
format = signer_ ? HICN_PACKET_FORMAT_IPV4_TCP_AH
@@ -217,12 +234,6 @@ class Client : private interface::Portal::TransportCallback {
interest->setSrcPort(config_->srcPort_);
interest->setDstPort(config_->dstPort_);
interest->setTTL(config_->ttl_);
- uint32_t seq_offset = 1;
- while (seq_offset <= config_->num_int_manifest_suffixes_ &&
- sequence_number_ + seq_offset < config_->maxPing_) {
- interest->appendSuffix(sequence_number_ + seq_offset);
- seq_offset++;
- }
if (config_->verbose_) {
std::cout << ">>> send interest " << interest->getName()
@@ -237,11 +248,15 @@ class Client : private interface::Portal::TransportCallback {
if (!config_->quiet_) std::cout << std::endl;
- send_timestamps_[sequence_number_] = utils::SteadyTime::now();
- for (uint64_t i = 1; i < seq_offset; i++)
- send_timestamps_[sequence_number_ + i] = utils::SteadyTime::now();
+ 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();
- if (signer_) signer_->signPacket(interest.get());
+ interest->appendSuffix(sequence_number);
+ send_timestamps_[sequence_number] = utils::SteadyTime::now();
+ }
if (config_->dump_) {
std::cout << "----- interest dump -----" << std::endl;
@@ -250,13 +265,10 @@ class Client : private interface::Portal::TransportCallback {
}
interest->encodeSuffixes();
-
+ if (signer_) signer_->signPacket(interest.get());
portal_.sendInterest(interest, interest->getLifetime());
- sequence_number_ += seq_offset;
- sent_ += seq_offset;
-
- 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) {
@@ -269,18 +281,18 @@ class Client : private interface::Portal::TransportCallback {
void afterSignal() {
std::cout << "Stop ping" << std::endl;
- std::cout << "Sent: " << sent_ << " Received: " << received_
- << " Timeouts: " << timedout_ << std::endl;
+ std::cout << "Sent: " << traffic_generator_->getSentCount()
+ << " Received: " << received_ << " Timeouts: " << timedout_
+ << std::endl;
io_service_.stop();
}
void reset() {
timer_.reset(new asio::steady_timer(portal_.getThread().getIoService()));
- sequence_number_ = config_->first_suffix_;
+ traffic_generator_->reset();
last_jump_ = 0;
processed_ = 0;
state_ = SYN_STATE;
- sent_ = 0;
received_ = 0;
timedout_ = 0;
}
@@ -292,15 +304,14 @@ class Client : private interface::Portal::TransportCallback {
asio::signal_set signals_;
Configuration *config_;
std::unique_ptr<asio::steady_timer> timer_;
- uint32_t sequence_number_;
uint64_t last_jump_ = 0;
uint64_t processed_ = 0;
uint32_t state_ = SYN_STATE;
- uint32_t sent_ = 0;
uint32_t received_ = 0;
uint32_t timedout_ = 0;
Verifier verifier_;
std::unique_ptr<auth::Signer> signer_;
+ std::unique_ptr<TrafficGenerator> traffic_generator_;
};
void help() {
@@ -339,6 +350,9 @@ void help() {
std::cerr << "-F <conf_file> Path to optional configuration file for "
"libtransport"
<< std::endl;
+ std::cout << "-b <type> Traffic generator type. Use 'RANDOM' for "
+ "random prefixes and suffixes. Default: sequential suffixes."
+ << std::endl;
std::cout << "-H prints this message" << std::endl;
}
@@ -358,13 +372,16 @@ int start(int argc, char *argv[]) {
transport::interface::global_config::IoModuleConfiguration io_config;
io_config.name = "hicnlight_module";
- while ((opt = getopt(argc, argv, "a:j::t:i:m:s:d:n:l:f:c:SAOqVDHz:F:")) !=
+ while ((opt = getopt(argc, argv, "a:b:j::t:i:m:s:d:n:l:f:c:SAOqVDHz:F:")) !=
-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 't':
c->ttl_ = uint8_t(std::stoi(optarg));
break;
diff --git a/apps/ping/src/ping_server.cc b/apps/ping/src/ping_server.cc
index 876efd133..325ef675c 100644
--- a/apps/ping/src/ping_server.cc
+++ b/apps/ping/src/ping_server.cc
@@ -40,6 +40,38 @@ using CryptoSuite = auth::CryptoSuite;
class CallbackContainer {
const std::size_t log2_content_object_buffer_size = 12;
+ private:
+ std::shared_ptr<ContentObject> createContentObject(const Name &name,
+ uint32_t lifetime,
+ const Interest &interest) {
+ auto &content_object = content_objects_[content_objects_index_++ & mask_];
+
+ content_object->setName(name);
+ content_object->setLifetime(lifetime);
+ content_object->setLocator(interest.getLocator());
+ content_object->setSrcPort(interest.getDstPort());
+ content_object->setDstPort(interest.getSrcPort());
+ content_object->setTTL(ttl_);
+
+ if (verbose_) {
+ std::cout << ">>> send object " << content_object->getName()
+ << " src port: " << content_object->getSrcPort()
+ << " dst port: " << content_object->getDstPort()
+ << " TTL: " << (int)content_object->getTTL() << std::endl;
+ } else if (!quiet_) {
+ std::cout << ">>> send object " << content_object->getName() << std::endl;
+ }
+
+ if (dump_) {
+ std::cout << "----- object dump -----" << std::endl;
+ content_object->dump();
+ std::cout << "-----------------------" << std::endl;
+ }
+
+ if (sign_ && signer_) signer_->signPacket(content_object.get());
+ return content_object;
+ }
+
public:
CallbackContainer(const Name &prefix, uint32_t object_size, bool verbose,
bool dump, bool quiet, uint8_t ttl, auth::Signer *signer,
@@ -109,58 +141,24 @@ class CallbackContainer {
std::cout << "-------------------------" << std::endl;
}
- uint32_t *suffix = interest.firstSuffix();
- uint32_t n_suffixes_in_manifest = interest.numberOfSuffixes();
- hicn_uword *request_bitmap = interest.getRequestBitmap();
if (!interest.isValid()) throw std::runtime_error("Bad interest format");
-
Name name = interest.getName();
- uint32_t pos = 0; // Position of current suffix in manifest
- do {
- // If suffix can be processed, i.e. no manifest with bitmap excluding it
- if (!interest.hasManifest() ||
- bitmap_is_set_no_check(request_bitmap, pos)) {
- 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 (verbose_) {
- std::cout << ">>> send object " << content_object->getName()
- << " src port: " << content_object->getSrcPort()
- << " dst port: " << content_object->getDstPort()
- << " TTL: " << (int)content_object->getTTL() << std::endl;
- } else if (!quiet_) {
- std::cout << ">>> send object " << content_object->getName()
- << std::endl;
- }
-
- if (dump_) {
- std::cout << "----- object dump -----" << std::endl;
- content_object->dump();
- std::cout << "-----------------------" << std::endl;
- }
-
- if (sign_ && signer_) {
- signer_->signPacket(content_object.get());
- }
- p.produce(*content_object);
- }
+ if (!interest.hasManifest()) { // Single interest
+ auto content_object = createContentObject(name, lifetime, interest);
+ p.produce(*content_object);
+ } else { // Interest manifest
+ uint32_t _, *suffix = NULL;
+ UNUSED(_);
- if (interest.hasManifest()) {
- uint32_t seq = *suffix;
- suffix++;
+ interest_manifest_foreach_suffix(interest.getIntManifestHeader(), suffix,
+ _) {
+ name.setSuffix(*suffix);
- Name name = interest.getName();
- interest.setName(name.setSuffix(seq));
+ auto content_object = createContentObject(name, lifetime, interest);
+ p.produce(*content_object);
}
- } while (pos++ < n_suffixes_in_manifest);
+ }
if (!quiet_) std::cout << std::endl;
}
diff --git a/hicn-light/src/hicn/core/forwarder.c b/hicn-light/src/hicn/core/forwarder.c
index 60493a9c5..fbf7040e3 100644
--- a/hicn-light/src/hicn/core/forwarder.c
+++ b/hicn-light/src/hicn/core/forwarder.c
@@ -1013,8 +1013,7 @@ static ssize_t forwarder_process_aggregated_interest(
WITH_DEBUG({
char buf[MAXSZ_HICN_PREFIX];
- int rc =
- hicn_name_snprintf(buf, MAXSZ_HICN_NAME, msgbuf_get_name(msgbuf));
+ int rc = hicn_name_snprintf(buf, MAXSZ_HICN_NAME, &name_copy);
if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
snprintf(buf, MAXSZ_HICN_PREFIX, "(error)");
DEBUG("Next in manifest: %s", buf);
diff --git a/hicn-light/src/hicn/core/strategy.c b/hicn-light/src/hicn/core/strategy.c
index 3716cd585..46c83ef02 100644
--- a/hicn-light/src/hicn/core/strategy.c
+++ b/hicn-light/src/hicn/core/strategy.c
@@ -26,6 +26,10 @@ int strategy_initialize(strategy_entry_t *entry, const void *forwarder) {
return strategy_vft[entry->type]->initialize(entry, forwarder);
}
+int strategy_finalize(strategy_entry_t *entry) {
+ return strategy_vft[entry->type]->finalize(entry);
+}
+
nexthops_t *strategy_lookup_nexthops(strategy_entry_t *entry,
nexthops_t *nexthops,
const msgbuf_t *msgbuf) {
diff --git a/hicn-light/src/hicn/core/strategy.h b/hicn-light/src/hicn/core/strategy.h
index 9ce75c51d..9f1a7dac7 100644
--- a/hicn-light/src/hicn/core/strategy.h
+++ b/hicn-light/src/hicn/core/strategy.h
@@ -59,6 +59,8 @@ typedef struct strategy_entry_s {
int strategy_initialize(strategy_entry_t *entry, const void *forwarder);
+int strategy_finalize(strategy_entry_t *entry);
+
nexthops_t *strategy_lookup_nexthops(strategy_entry_t *entry,
nexthops_t *nexthops,
const msgbuf_t *msgbuf);
diff --git a/hicn-light/src/hicn/test/test-strategy-best-path.cc b/hicn-light/src/hicn/test/test-strategy-best-path.cc
index 327c47144..f909c15f2 100644
--- a/hicn-light/src/hicn/test/test-strategy-best-path.cc
+++ b/hicn-light/src/hicn/test/test-strategy-best-path.cc
@@ -66,7 +66,7 @@ class StrategyBestpathTest : public ::testing::Test {
ticks_ = ticks_now();
}
- virtual ~StrategyBestpathTest() {}
+ virtual ~StrategyBestpathTest() { strategy_finalize(&entry); }
strategy_entry_t entry;
nexthops_t available_nexthops_;
diff --git a/hicn-light/src/hicn/test/test-strategy-replication.cc b/hicn-light/src/hicn/test/test-strategy-replication.cc
index 2924173cb..1c4d824b8 100644
--- a/hicn-light/src/hicn/test/test-strategy-replication.cc
+++ b/hicn-light/src/hicn/test/test-strategy-replication.cc
@@ -61,7 +61,7 @@ class StrategyReplicationTest : public ::testing::Test {
ticks_ = ticks_now();
}
- virtual ~StrategyReplicationTest() {}
+ virtual ~StrategyReplicationTest() { strategy_finalize(&entry); }
strategy_entry_t entry;
nexthops_t available_nexthops_;
diff --git a/lib/includes/hicn/name.h b/lib/includes/hicn/name.h
index 895b86341..a1b8e1fc1 100644
--- a/lib/includes/hicn/name.h
+++ b/lib/includes/hicn/name.h
@@ -270,6 +270,9 @@ bool hicn_name_is_v4 (const hicn_name_t *name);
int hicn_name_snprintf (char *s, size_t size, const hicn_name_t *name);
+int hicn_name_no_suffix_snprintf (char *s, size_t size,
+ const hicn_name_t *name);
+
int hicn_name_cmp (const hicn_name_t *n1, const hicn_name_t *n2);
bool hicn_name_equals (const hicn_name_t *n1, const hicn_name_t *n2);
diff --git a/lib/src/name.c b/lib/src/name.c
index 04c48cb4d..1c933d466 100644
--- a/lib/src/name.c
+++ b/lib/src/name.c
@@ -242,6 +242,12 @@ hicn_name_snprintf (char *s, size_t size, const hicn_name_t *name)
}
int
+hicn_name_no_suffix_snprintf (char *s, size_t size, const hicn_name_t *name)
+{
+ return hicn_ip_address_snprintf (s, size, &name->prefix);
+}
+
+int
hicn_prefix_create_from_ip_prefix (const hicn_ip_prefix_t *hicn_ip_prefix,
hicn_prefix_t *prefix)
{
diff --git a/lib/src/test/test_name.cc b/lib/src/test/test_name.cc
index 35e636b63..dbeab96cc 100644
--- a/lib/src/test/test_name.cc
+++ b/lib/src/test/test_name.cc
@@ -31,9 +31,11 @@ protected:
NameTest () : name_{}, name4_{}, name6_{}
{
+ ipv6_prefix_bytes = {};
int rc = inet_pton (AF_INET6, ipv6_prefix, &ipv6_prefix_bytes.v6);
EXPECT_EQ (rc, 1);
+ ipv4_prefix_bytes = {};
rc = inet_pton (AF_INET, ipv4_prefix, &ipv4_prefix_bytes.v4);
EXPECT_EQ (rc, 1);
diff --git a/libtransport/includes/hicn/transport/core/interest.h b/libtransport/includes/hicn/transport/core/interest.h
index 59da5b91f..270ea7027 100644
--- a/libtransport/includes/hicn/transport/core/interest.h
+++ b/libtransport/includes/hicn/transport/core/interest.h
@@ -104,6 +104,8 @@ class Interest
hicn_uword *getRequestBitmap();
+ interest_manifest_header_t *getIntManifestHeader();
+
void setRequestBitmap(const uint32_t *request_bitmap);
bool isValid();
diff --git a/libtransport/includes/hicn/transport/core/name.h b/libtransport/includes/hicn/transport/core/name.h
index 90b665c15..14ea10898 100644
--- a/libtransport/includes/hicn/transport/core/name.h
+++ b/libtransport/includes/hicn/transport/core/name.h
@@ -98,6 +98,8 @@ class Name {
hicn_ip_prefix_t toIpAddress() const;
+ std::string getPrefix() const;
+
void copyPrefixToDestination(uint8_t *destination) const;
int getAddressFamily() const;
diff --git a/libtransport/includes/hicn/transport/utils/CMakeLists.txt b/libtransport/includes/hicn/transport/utils/CMakeLists.txt
index 1dba94451..060b83b63 100644
--- a/libtransport/includes/hicn/transport/utils/CMakeLists.txt
+++ b/libtransport/includes/hicn/transport/utils/CMakeLists.txt
@@ -34,6 +34,7 @@ list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/shared_ptr_utils.h
${CMAKE_CURRENT_SOURCE_DIR}/noncopyable.h
${CMAKE_CURRENT_SOURCE_DIR}/singleton.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/traffic_generator.h
)
if(NOT WIN32)
diff --git a/libtransport/includes/hicn/transport/utils/traffic_generator.h b/libtransport/includes/hicn/transport/utils/traffic_generator.h
new file mode 100644
index 000000000..abd84886d
--- /dev/null
+++ b/libtransport/includes/hicn/transport/utils/traffic_generator.h
@@ -0,0 +1,72 @@
+/*
+ * 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 <random>
+#include <string>
+
+namespace transport {
+
+class TrafficGenerator {
+ public:
+ TrafficGenerator(uint32_t count);
+ virtual ~TrafficGenerator() = default;
+ bool hasFinished();
+ uint32_t getSentCount();
+ virtual std::pair<std::string, uint32_t> getPrefixAndSuffix();
+
+ virtual std::string getPrefix() = 0;
+ virtual uint32_t getSuffix() = 0;
+ virtual void reset();
+
+ protected:
+ void onSuffixGenerated();
+
+ uint32_t count_;
+ uint32_t sent_;
+};
+
+/* Fixed prefix, incremental suffix */
+class IncrSuffixTrafficGenerator : public TrafficGenerator {
+ public:
+ explicit IncrSuffixTrafficGenerator(std::string prefix, uint32_t suffix,
+ uint32_t count);
+ std::string getPrefix() override;
+ uint32_t getSuffix() override;
+ void reset() override;
+
+ private:
+ std::string prefix_;
+ uint32_t suffix_;
+ uint32_t initial_suffix_;
+};
+
+/* Random prefix, random suffix */
+class RandomTrafficGenerator : public TrafficGenerator {
+ public:
+ static constexpr char NET_PREFIX[] = "2001:db8:1::/64";
+
+ RandomTrafficGenerator(uint32_t count, std::string net_prefix = NET_PREFIX);
+ std::string getPrefix() override;
+ uint32_t getSuffix() override;
+
+ private:
+ std::string net_prefix_;
+ std::default_random_engine rand_engine_;
+ std::uniform_int_distribution<uint32_t> uniform_distribution_;
+};
+
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/core/interest.cc b/libtransport/src/core/interest.cc
index 6348a8d3e..c3eb7c379 100644
--- a/libtransport/src/core/interest.cc
+++ b/libtransport/src/core/interest.cc
@@ -170,9 +170,6 @@ void Interest::encodeSuffixes() {
(interest_manifest_header_t *)(writableData() + headerSize());
interest_manifest_init(int_manifest_header, name_.getSuffix());
- memset(int_manifest_header->request_bitmap, 0xFFFFFFFF,
- BITMAP_SIZE * sizeof(hicn_uword));
-
for (auto it = suffix_set_.begin(); it != suffix_set_.end(); it++) {
interest_manifest_add_suffix(int_manifest_header, *it);
}
@@ -237,6 +234,13 @@ hicn_uword *Interest::getRequestBitmap() {
return header->request_bitmap;
}
+interest_manifest_header_t *Interest::getIntManifestHeader() {
+ if (!hasManifest()) return nullptr;
+
+ auto header = (interest_manifest_header_t *)(writableData() + headerSize());
+ return header;
+};
+
void Interest::setRequestBitmap(const uint32_t *request_bitmap) {
if (!hasManifest()) return;
diff --git a/libtransport/src/core/name.cc b/libtransport/src/core/name.cc
index 02cc79be6..4f8ba7873 100644
--- a/libtransport/src/core/name.cc
+++ b/libtransport/src/core/name.cc
@@ -168,6 +168,13 @@ hicn_ip_prefix_t Name::toIpAddress() const {
return ret;
}
+std::string Name::getPrefix() const {
+ char prefix[MAXSZ_HICN_NAME];
+ hicn_name_no_suffix_snprintf(prefix, MAXSZ_HICN_NAME, &name_);
+
+ return std::string(prefix);
+}
+
int Name::getAddressFamily() const {
int ret = 0;
diff --git a/libtransport/src/test/CMakeLists.txt b/libtransport/src/test/CMakeLists.txt
index 356ee0067..864006e5d 100644
--- a/libtransport/src/test/CMakeLists.txt
+++ b/libtransport/src/test/CMakeLists.txt
@@ -33,6 +33,7 @@ list(APPEND TESTS_SRC
test_thread_pool.cc
test_quadloop.cc
test_prefix.cc
+ test_traffic_generator.cc
)
if (ENABLE_RELY)
diff --git a/libtransport/src/test/test_traffic_generator.cc b/libtransport/src/test/test_traffic_generator.cc
new file mode 100644
index 000000000..733acbb74
--- /dev/null
+++ b/libtransport/src/test/test_traffic_generator.cc
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <hicn/transport/utils/traffic_generator.h>
+
+static constexpr int NUM_PINGS = 10;
+static constexpr char PREFIX[] = "b001:1:2:3::";
+static constexpr uint32_t FIRST_SUFFIX = 5;
+
+namespace utils {
+
+using transport::IncrSuffixTrafficGenerator;
+using transport::RandomTrafficGenerator;
+
+class TrafficGeneratorTest : public ::testing::Test {
+ protected:
+ TrafficGeneratorTest() {}
+ virtual ~TrafficGeneratorTest() {}
+};
+
+TEST_F(TrafficGeneratorTest, IncrSuffixGetPrefixAndSuffix) {
+ auto traffic_generator_ = std::make_unique<IncrSuffixTrafficGenerator>(
+ PREFIX, FIRST_SUFFIX, NUM_PINGS);
+
+ std::string prefix = traffic_generator_->getPrefix();
+ EXPECT_EQ(prefix, PREFIX);
+ uint32_t suffix = traffic_generator_->getSuffix();
+ EXPECT_EQ(suffix, FIRST_SUFFIX);
+}
+
+TEST_F(TrafficGeneratorTest, IncrSuffixGetMultipleSuffixes) {
+ auto traffic_generator_ = std::make_unique<IncrSuffixTrafficGenerator>(
+ PREFIX, FIRST_SUFFIX, NUM_PINGS);
+
+ std::string prefix = traffic_generator_->getPrefix();
+ EXPECT_EQ(prefix, PREFIX);
+ EXPECT_EQ(prefix, traffic_generator_->getPrefix());
+
+ for (int i = 0; i < NUM_PINGS; i++)
+ EXPECT_EQ(traffic_generator_->getSuffix(), FIRST_SUFFIX + i);
+}
+
+TEST_F(TrafficGeneratorTest, IncrSuffixReset) {
+ auto traffic_generator_ = std::make_unique<IncrSuffixTrafficGenerator>(
+ PREFIX, FIRST_SUFFIX, NUM_PINGS);
+
+ for (int i = 0; i < NUM_PINGS; i++) traffic_generator_->getSuffix();
+
+ traffic_generator_->reset();
+ EXPECT_EQ(traffic_generator_->getPrefix(), PREFIX);
+ EXPECT_EQ(traffic_generator_->getSuffix(), FIRST_SUFFIX);
+ EXPECT_EQ(traffic_generator_->getSuffix(), FIRST_SUFFIX + 1);
+}
+
+TEST_F(TrafficGeneratorTest, IncrSuffixRequestTooManySuffixes) {
+ auto traffic_generator_ = std::make_unique<IncrSuffixTrafficGenerator>(
+ PREFIX, FIRST_SUFFIX, NUM_PINGS);
+
+ for (int i = 0; i < NUM_PINGS; i++) traffic_generator_->getSuffix();
+ EXPECT_THROW(traffic_generator_->getSuffix(), std::runtime_error);
+}
+
+TEST_F(TrafficGeneratorTest, IncrSuffixGetPrefixAndSuffixTogether) {
+ auto traffic_generator_ = std::make_unique<IncrSuffixTrafficGenerator>(
+ PREFIX, FIRST_SUFFIX, NUM_PINGS);
+
+ auto [prefix, suffix] = traffic_generator_->getPrefixAndSuffix();
+ EXPECT_EQ(prefix, PREFIX);
+ EXPECT_EQ(suffix, FIRST_SUFFIX);
+}
+
+TEST_F(TrafficGeneratorTest, IncrSuffixCheckSentCount) {
+ auto traffic_generator_ = std::make_unique<IncrSuffixTrafficGenerator>(
+ PREFIX, FIRST_SUFFIX, NUM_PINGS);
+
+ for (int i = 0; i < NUM_PINGS; i++) {
+ EXPECT_EQ(traffic_generator_->getSentCount(), (uint32_t)i);
+ EXPECT_FALSE(traffic_generator_->hasFinished());
+ traffic_generator_->getSuffix();
+ }
+ EXPECT_TRUE(traffic_generator_->hasFinished());
+}
+
+TEST_F(TrafficGeneratorTest, RandomGetPrefixAndSuffix) {
+ auto traffic_generator_ = std::make_unique<RandomTrafficGenerator>(NUM_PINGS);
+
+ std::string prefix1 = traffic_generator_->getPrefix();
+ std::string prefix2 = traffic_generator_->getPrefix();
+ EXPECT_NE(prefix1, prefix2);
+
+ uint32_t suffix1 = traffic_generator_->getSuffix();
+ uint32_t suffix2 = traffic_generator_->getSuffix();
+ EXPECT_NE(suffix1, suffix2);
+}
+
+TEST_F(TrafficGeneratorTest, RandomGetPrefixAndSuffixWithNetPrefix) {
+ auto traffic_generator_ = std::make_unique<RandomTrafficGenerator>(
+ NUM_PINGS, std::string(PREFIX) + "/64");
+
+ for (int i = 0; i < NUM_PINGS; i++)
+ EXPECT_THAT(traffic_generator_->getPrefix(),
+ testing::StartsWith(std::string(PREFIX)));
+}
+
+} // namespace utils \ No newline at end of file
diff --git a/libtransport/src/utils/CMakeLists.txt b/libtransport/src/utils/CMakeLists.txt
index 5bb76303a..e7c1c03ea 100644
--- a/libtransport/src/utils/CMakeLists.txt
+++ b/libtransport/src/utils/CMakeLists.txt
@@ -17,6 +17,7 @@ list(APPEND SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/log.cc
${CMAKE_CURRENT_SOURCE_DIR}/membuf.cc
${CMAKE_CURRENT_SOURCE_DIR}/content_store.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/traffic_generator.cc
)
diff --git a/libtransport/src/utils/traffic_generator.cc b/libtransport/src/utils/traffic_generator.cc
new file mode 100644
index 000000000..a617e3dc9
--- /dev/null
+++ b/libtransport/src/utils/traffic_generator.cc
@@ -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.
+ */
+
+#include <hicn/transport/core/prefix.h>
+#include <hicn/transport/utils/traffic_generator.h>
+
+#include <iostream>
+
+namespace transport {
+
+/* TrafficGenerator */
+
+TrafficGenerator::TrafficGenerator(uint32_t count) : count_(count), sent_(0) {}
+
+bool TrafficGenerator::hasFinished() { return sent_ >= count_; }
+
+uint32_t TrafficGenerator::getSentCount() { return sent_; }
+
+std::pair<std::string, uint32_t> TrafficGenerator::getPrefixAndSuffix() {
+ return std::make_pair(getPrefix(), getSuffix());
+}
+
+void TrafficGenerator::reset() { sent_ = 0; };
+
+void TrafficGenerator::onSuffixGenerated() {
+ if (hasFinished()) throw std::runtime_error("Too many pings");
+ sent_++;
+};
+
+/* IncrSuffixTrafficGenerator */
+
+IncrSuffixTrafficGenerator::IncrSuffixTrafficGenerator(std::string prefix,
+ uint32_t suffix,
+ uint32_t count)
+ : TrafficGenerator(count),
+ prefix_(prefix),
+ suffix_(suffix),
+ initial_suffix_(suffix) {}
+
+std::string IncrSuffixTrafficGenerator::getPrefix() { return prefix_; }
+
+uint32_t IncrSuffixTrafficGenerator::getSuffix() {
+ TrafficGenerator::onSuffixGenerated();
+ return suffix_++;
+}
+
+void IncrSuffixTrafficGenerator::reset() {
+ TrafficGenerator::reset();
+ suffix_ = initial_suffix_;
+};
+
+/* RandomTrafficGenerator */
+
+RandomTrafficGenerator::RandomTrafficGenerator(uint32_t count,
+ std::string net_prefix)
+ : TrafficGenerator(count),
+ net_prefix_(net_prefix),
+ rand_engine_((std::random_device())()),
+ uniform_distribution_(0, std::numeric_limits<uint32_t>::max()) {}
+
+std::string RandomTrafficGenerator::getPrefix() {
+ // Generate random prefix
+ core::Prefix prefix(net_prefix_);
+ core::Name name = prefix.makeRandomName();
+ return name.getPrefix();
+}
+
+uint32_t RandomTrafficGenerator::getSuffix() {
+ TrafficGenerator::onSuffixGenerated();
+
+ // Generate random suffix
+ return uniform_distribution_(rand_engine_);
+}
+
+} // namespace transport \ No newline at end of file
diff --git a/tests/1-node.yml b/tests/1-node.yml
index eb8c19f34..859d1b838 100644
--- a/tests/1-node.yml
+++ b/tests/1-node.yml
@@ -16,7 +16,6 @@ services:
command:
- |
if [ -d /workspace/build-dev ]; then
- git config --global --add safe.directory \*
sudo ninja -C /workspace/build-dev install
fi
diff --git a/tests/Makefile b/tests/Makefile
index f9c166b8d..a31a6f1a6 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,4 +1,4 @@
-# Use when building for the fist time,
+# Use when building for the first time,
# then `make test` forces a rebuild if local changes
build:
DOCKERFILE=Dockerfile.dev BUILD_SOFTWARE=1 \
@@ -28,8 +28,15 @@ shell:
down:
docker-compose -f 1-node.yml down
-functional:
+functional-ctrl:
sleep 1 # Wait for the forwarder to be ready
bash config.sh ctrl listeners
bash config.sh ctrl connections
- bash config.sh ctrl routes \ No newline at end of file
+ bash config.sh ctrl routes
+
+functional-ping-manifest:
+ bash config.sh ping manifest
+functional-ping-signature:
+ bash config.sh ping signature
+functional-ping-timeout:
+ bash config.sh ping timeout \ No newline at end of file
diff --git a/tests/config.sh b/tests/config.sh
index a6bc6ad2d..16000bff6 100755
--- a/tests/config.sh
+++ b/tests/config.sh
@@ -465,6 +465,97 @@ function ctrl() {
${ctrl_tests[${type}]}
}
+################################################################
+# Test ping
+################################################################
+function test_ping_manifest() {
+ docker exec forwarder bash -c 'hicn-ping-server -a intmanifest >/tmp/ping_server.log 2>&1 &'
+ sleep 1
+
+ # 2 interests w/ 3 suffixes each (1 in header + 2 in manifest)
+ docker exec forwarder bash -c 'hicn-ping-client -m 6 -a 2 intmanifest | grep "Sent" >>/tmp/ping_client.log'
+ sleep 1
+
+ # 2 interests w/ 3 suffixes each + 1 single interest
+ docker exec forwarder bash -c 'hicn-ping-client -m 7 -a 2 intmanifest | grep "Sent" >>/tmp/ping_client.log'
+ sleep 1
+
+ # 2 interests w/ 3 suffixes each + 1 interest w/ 2 suffixes
+ docker exec forwarder bash -c 'hicn-ping-client -m 8 -a 2 intmanifest | grep "Sent" >>/tmp/ping_client.log'
+ sleep 1
+
+ # 2 interests w/ 3 suffixes each + 1 single interest,
+ # using random prefix/suffix generation
+ docker exec forwarder bash -c 'hicn-ping-client -m 7 -a 2 intmanifest -b RANDOM | grep "Sent" >>/tmp/ping_client.log'
+
+ # No 'failed' expected
+ ping_server_logs=$(docker exec forwarder cat /tmp/ping_server.log)
+ if [[ $(echo $ping_server_logs | grep failed | wc -l) -ne 0 ]]; then
+ echo "******** Server logs (ping) ********"
+ echo "$ping_server_logs"
+ exit 1
+ fi
+
+ # No 'Timeouts: 0' expected
+ ping_client_logs=$(docker exec forwarder cat /tmp/ping_client.log)
+ if [[ $(echo $ping_client_logs | grep -v "Timeouts: 0" | wc -l) -ne 0 ]]; then
+ echo "******** Client logs (ping) ********"
+ echo "$ping_client_logs"
+ exit 1
+ fi
+}
+
+function test_ping_wrong_signature() {
+ docker exec forwarder bash -c 'hicn-ping-server -a intmanifest >/tmp/ping_server.log 2>&1 &'
+ sleep 1
+
+ # Signature mismatch ('intmamifest' on server vs 'wrong_sign' on client)
+ docker exec forwarder bash -c 'hicn-ping-client -m 6 -a 2 wrong_sig | grep "Sent" >>/tmp/ping_client.log'
+
+ # 'failed' expected
+ ping_server_logs=$(docker exec forwarder cat /tmp/ping_server.log)
+ if [[ $(echo $ping_server_logs | grep "failed" | wc -l) -eq 0 ]]; then
+ echo "******** Server logs (signature fail) ********"
+ echo "$ping_server_logs"
+ exit 1
+ fi
+}
+
+function test_ping_no_server() {
+ # Server not started to check for ping client timeout
+ docker exec forwarder bash -c 'hicn-ping-client -m 6 | grep "Sent" >>/tmp/ping_client.log'
+
+ # 'Timeouts: 6' expected
+ ping_client_logs=$(docker exec forwarder cat /tmp/ping_client.log)
+ if [[ $(echo $ping_client_logs | grep "Timeouts: 6" | wc -l) -eq 0 ]]; then
+ echo "******** Client logs (timeout) ********"
+ echo "$ping_client_logs"
+ exit 1
+ fi
+}
+
+declare -A ping_tests=(
+ ["manifest"]="test_ping_manifest"
+ ["signature"]="test_ping_wrong_signature"
+ ["timeout"]="test_ping_no_server"
+)
+
+function ping_test_exists() {
+ [[ "${!ping_tests[*]}" =~ ${1} ]] && return 0 || return 1
+}
+
+function ping() {
+ type=$1
+ if ! ping_test_exists "${type}"; then
+ error "Error: hicn-ping test does not exist."
+ exit 1
+ fi
+
+ ${ping_tests[${type}]}
+}
+
+#--------------------------------------------------------------#
+
while (("${#}")); do
case "$1" in
'build')
@@ -510,6 +601,10 @@ while (("${#}")); do
ctrl "${2}"
break
;;
+ 'ping')
+ ping "${2}"
+ break
+ ;;
*)
exit 1
;;
diff --git a/tests/functional-tests/hicn-light-ping.robot b/tests/functional-tests/hicn-light-ping.robot
new file mode 100644
index 000000000..238f49e0e
--- /dev/null
+++ b/tests/functional-tests/hicn-light-ping.robot
@@ -0,0 +1,26 @@
+*** Settings ***
+Resource resources/libraries/robot/common.robot
+Test Setup Run Keywords
+... Build Topology 1-node AND
+... Check Environment
+Test Teardown Run Keywords
+... Destroy Topology
+
+*** Test Cases ***
+Ping with manifest
+ Log to console Test ping with manifest
+ ${result} = Run Process ${EXECDIR}/config.sh ping manifest
+ Log Many stdout: ${result.stdout}
+ Should Be Equal As Integers ${result.rc} 0
+
+Ping wrong signature
+ Log to console Test ping with wrong signature
+ ${result} = Run Process ${EXECDIR}/config.sh ping signature
+ Log Many stdout: ${result.stdout}
+ Should Be Equal As Integers ${result.rc} 0
+
+Ping timeout
+ Log to console Test ping timeout
+ ${result} = Run Process ${EXECDIR}/config.sh ping timeout
+ Log Many stdout: ${result.stdout}
+ Should Be Equal As Integers ${result.rc} 0
#n2223'>2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663