From 6b94663b2455e212009a544ae23bb6a8c55407f8 Mon Sep 17 00:00:00 2001 From: Luca Muscariello Date: Thu, 9 Jun 2022 21:34:09 +0200 Subject: refactor(lib, hicn-light, vpp, hiperf): HICN-723 - move infra data structure into the shared lib - new packet cache using double hashing and lookup on prefix suffix - testing updates - authenticated requests using interest manifests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mauro Sardara Co-authored-by: Jordan Augé Co-authored-by: Michele Papalini Co-authored-by: Olivier Roques Co-authored-by: Enrico Loparco Change-Id: Iaddebfe6aa5279ea8553433b0f519578f6b9ccd9 Signed-off-by: Luca Muscariello --- apps/ping/src/ping_client.cc | 71 +++++++++++++++---- apps/ping/src/ping_server.cc | 162 +++++++++++++++++++++++++++---------------- 2 files changed, 161 insertions(+), 72 deletions(-) (limited to 'apps/ping') diff --git a/apps/ping/src/ping_client.cc b/apps/ping/src/ping_client.cc index 0217f2f8c..2371e4453 100644 --- a/apps/ping/src/ping_client.cc +++ b/apps/ping/src/ping_client.cc @@ -13,6 +13,7 @@ * limitations under the License. */ +#include #include #include #include @@ -39,12 +40,14 @@ typedef auth::AsymmetricVerifier Verifier; class Configuration { public: + uint64_t num_int_manifest_suffixes_; uint64_t interestLifetime_; uint64_t pingInterval_; uint64_t maxPing_; uint64_t first_suffix_; std::string name_; std::string certificate_; + std::string passphrase_; uint16_t srcPort_; uint16_t dstPort_; bool verbose_; @@ -59,9 +62,10 @@ class Configuration { uint8_t ttl_; Configuration() { - interestLifetime_ = 500; // ms - pingInterval_ = 1000000; // us - maxPing_ = 10; // number of interests + num_int_manifest_suffixes_ = 0; // Number of suffixes in interest manifest + interestLifetime_ = 500; // ms + pingInterval_ = 1000000; // us + maxPing_ = 10; // number of interests first_suffix_ = 0; name_ = "b001::1"; // string srcPort_ = 9695; @@ -96,6 +100,13 @@ class Client : interface::Portal::TransportCallback { 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::CryptoSuite::HMAC_SHA256, c->passphrase_); + } } virtual ~Client() {} @@ -142,6 +153,7 @@ class Client : interface::Portal::TransportCallback { if (config_->verbose_) { std::cout << "<<< recevied object. " << std::endl; std::cout << "<<< interest name: " << interest.getName() + << " (n_suffixes=" << interest.numberOfSuffixes() << ")" << " src port: " << interest.getSrcPort() << " dst port: " << interest.getDstPort() << " flags: " << interest.printFlags() << std::endl; @@ -221,15 +233,18 @@ class Client : interface::Portal::TransportCallback { const Name interest_name(config_->name_, (uint32_t)sequence_number_); hicn_format_t format; if (interest_name.getAddressFamily() == AF_INET) { - format = HF_INET_TCP; + format = signer_ ? HF_INET_TCP_AH : HF_INET_TCP; } else { - format = HF_INET6_TCP; + format = signer_ ? HF_INET6_TCP_AH : HF_INET6_TCP; } - auto interest = std::make_shared(interest_name, format); + size_t additional_header_size = 0; + if (signer_) additional_header_size = signer_->getSignatureFieldSize(); + auto interest = std::make_shared(interest_name, format, + additional_header_size); interest->setLifetime(uint32_t(config_->interestLifetime_)); - interest->resetFlags(); + if (!signer_) interest->resetFlags(); if (config_->open_ || config_->always_syn_) { if (state_ == SYN_STATE) { @@ -244,13 +259,21 @@ class Client : interface::Portal::TransportCallback { interest->setSrcPort(config_->srcPort_); interest->setDstPort(config_->dstPort_); interest->setTTL(config_->ttl_); + uint64_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() << " src port: " << interest->getSrcPort() << " dst port: " << interest->getDstPort() << " flags: " << interest->printFlags() - << " TTL: " << (int)interest->getTTL() << std::endl; + << " TTL: " << (int)interest->getTTL() + << " suffixes in manifest: " + << config_->num_int_manifest_suffixes_ << std::endl; } else if (!config_->quiet_) { std::cout << ">>> send interest " << interest->getName() << std::endl; } @@ -264,11 +287,16 @@ class Client : 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(); - portal_.sendInterest(std::move(interest)); + interest->encodeSuffixes(); + if (signer_) signer_->signPacket(interest.get()); - sequence_number_++; - sent_++; + portal_.sendInterest(interest, interest->getLifetime()); + + sequence_number_ += seq_offset; + sent_ += seq_offset; if (sent_ < config_->maxPing_) { this->timer_->expires_from_now( @@ -314,6 +342,7 @@ class Client : interface::Portal::TransportCallback { std::unique_ptr timer_; Configuration *config_; Verifier verifier_; + std::unique_ptr signer_; }; void help() { @@ -327,6 +356,12 @@ void help() { std::cout << "-s sorce port (default 9695)" << std::endl; std::cout << "-d destination port (default 8080)" << std::endl; std::cout << "-t set packet ttl (default 64)" << std::endl; + std::cout << "-a set the passphrase and the number of " + "suffixes in interest manifest (default 0);" + << std::endl; + std::cout << " e.g. '-m 6 -a -2' sends two interest (0 and " + "3) with 2 suffixes each (1,2 and 4,5 respectively)" + << std::endl; std::cout << "-O open tcp connection (three way handshake) " "(default false)" << std::endl; @@ -362,6 +397,8 @@ int main(int argc, char *argv[]) { WSAStartup(MAKEWORD(2, 2), &wsaData); #endif + transport::interface::global_config::GlobalConfigInterface global_conf; + Configuration *c = new Configuration(); int opt; std::string producer_certificate = ""; @@ -370,8 +407,13 @@ int main(int argc, char *argv[]) { transport::interface::global_config::IoModuleConfiguration io_config; io_config.name = "hicnlightng_module"; - while ((opt = getopt(argc, argv, "j::t:i:m:s:d:n:l:f:c:SAOqVDHz:F:")) != -1) { + while ((opt = getopt(argc, argv, "a: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 't': c->ttl_ = (uint8_t)std::stoi(optarg); break; @@ -447,7 +489,7 @@ int main(int argc, char *argv[]) { /** * Parse config file */ - transport::interface::global_config::parseConfigurationFile(conf_file); + global_conf.parseConfigurationFile(conf_file); auto ping = std::make_unique(c); @@ -456,7 +498,8 @@ int main(int argc, char *argv[]) { auto t1 = std::chrono::steady_clock::now(); std::cout << "Elapsed time: " - << utils::SteadyTime::getDurationUs(t0, t1).count() << std::endl; + << utils::SteadyTime::getDurationMs(t0, t1).count() << "ms" + << std::endl; #ifdef _WIN32 WSACleanup(); diff --git a/apps/ping/src/ping_server.cc b/apps/ping/src/ping_server.cc index 3ffbc7325..dd7d23b5e 100644 --- a/apps/ping/src/ping_server.cc +++ b/apps/ping/src/ping_server.cc @@ -22,6 +22,7 @@ #endif #include +#include #include #include #include @@ -42,7 +43,8 @@ class CallbackContainer { public: CallbackContainer(const Name &prefix, uint32_t object_size, bool verbose, bool dump, bool quite, bool flags, bool reset, uint8_t ttl, - auth::Signer *signer, bool sign, uint32_t lifetime) + auth::Signer *signer, bool sign, std::string passphrase, + 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), @@ -55,8 +57,11 @@ class CallbackContainer { ttl_(ttl), signer_(signer), sign_(sign) { - core::Packet::Format format; + // Verifier for interest manifests + if (!passphrase.empty()) + verifier_ = std::make_unique(passphrase); + core::Packet::Format format; if (prefix.getAddressFamily() == AF_INET) { format = core::Packet::Format::HF_INET_TCP; if (sign_) { @@ -76,14 +81,28 @@ class CallbackContainer { } } - void processInterest(ProducerSocket &p, const Interest &interest, + 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); + std::cout << "Verification time: " << dt.count() << std::endl; + std::cout << "<<< Signature Ok." << std::endl; + } else { + std::cout << "<<< Signature verification failed!" << std::endl; + } + } + 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; + << "TTL: " << (int)interest.getTTL() + << " suffixes in manifest: " << interest.numberOfSuffixes() + << std::endl; } else if (!quite_) { std::cout << "<<< received interest " << interest.getName() << std::endl; } @@ -97,54 +116,74 @@ class CallbackContainer { 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 (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 (dump_) { - std::cout << "----- object dump -----" << std::endl; - content_object->dump(); - std::cout << "-----------------------" << std::endl; - } + uint32_t *suffix = interest.firstSuffix(); + uint32_t n_suffixes_in_manifest = interest.numberOfSuffixes(); + uint32_t *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() || is_bit_set(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 (!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 (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 (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()) { + uint32_t seq = *suffix; + suffix++; + + interest.setName(name.setSuffix(seq)); + } + } while (pos++ < n_suffixes_in_manifest); if (!quite_) std::cout << std::endl; - - if (sign_ && signer_) { - signer_->signPacket(content_object.get()); - } - - p.produce(*content_object); } } @@ -161,6 +200,7 @@ class CallbackContainer { uint8_t ttl_; auth::Signer *signer_; bool sign_; + std::unique_ptr verifier_; }; void help() { @@ -199,6 +239,7 @@ void help() { } int main(int argc, char **argv) { + transport::interface::global_config::GlobalConfigInterface global_conf; #ifdef _WIN32 WSADATA wsaData = {0}; WSAStartup(MAKEWORD(2, 2), &wsaData); @@ -216,6 +257,7 @@ int main(int argc, char **argv) { 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; @@ -225,11 +267,14 @@ int main(int argc, char **argv) { int opt; #ifndef _WIN32 - while ((opt = getopt(argc, argv, "s:n:t:l:qfrVDdHk:p:z:F:")) != -1) { + while ((opt = getopt(argc, argv, "a:s:n:t:l:qfrVDdHk:p:z:F:")) != -1) { #else while ((opt = getopt(argc, argv, "s:n:t:l:qfrVDHk:p:z:F:")) != -1) { #endif switch (opt) { + case 'a': + passphrase = optarg; + break; case 's': object_size = std::stoi(optarg); break; @@ -298,7 +343,7 @@ int main(int argc, char **argv) { /** * Parse config file */ - transport::interface::global_config::parseConfigurationFile(conf_file); + global_conf.parseConfigurationFile(conf_file); core::Prefix producer_namespace(name_prefix); @@ -309,24 +354,25 @@ int main(int argc, char **argv) { if (object_size > 1350) object_size = 1350; CallbackContainer *stubs; - std::unique_ptr signer; + std::unique_ptr signer; if (sign) { signer = std::make_unique(keystore_path, keystore_password); - stubs = - new CallbackContainer(n, object_size, verbose, dump, quite, flags, - reset, ttl, signer.get(), sign, data_lifetime); + stubs = new CallbackContainer(n, object_size, verbose, dump, quite, flags, + reset, ttl, signer.get(), sign, passphrase, + data_lifetime); } else { auth::Signer *signer = nullptr; stubs = new CallbackContainer(n, object_size, verbose, dump, quite, flags, - reset, ttl, signer, sign, data_lifetime); + reset, ttl, signer, sign, passphrase, + data_lifetime); } ProducerSocket p; p.registerPrefix(producer_namespace); - p.setSocketOption(GeneralTransportOptions::MAKE_MANIFEST, false); + p.setSocketOption(GeneralTransportOptions::MANIFEST_MAX_CAPACITY, 0U); p.setSocketOption(GeneralTransportOptions::OUTPUT_BUFFER_SIZE, 0U); p.setSocketOption( ProducerCallbacksOptions::CACHE_MISS, -- cgit 1.2.3-korg