aboutsummaryrefslogtreecommitdiffstats
path: root/apps/ping/src/ping_server.cc
diff options
context:
space:
mode:
Diffstat (limited to 'apps/ping/src/ping_server.cc')
-rw-r--r--apps/ping/src/ping_server.cc301
1 files changed, 301 insertions, 0 deletions
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);
+}