summaryrefslogtreecommitdiffstats
path: root/utils/src/ping_server.cc
diff options
context:
space:
mode:
Diffstat (limited to 'utils/src/ping_server.cc')
-rwxr-xr-xutils/src/ping_server.cc300
1 files changed, 300 insertions, 0 deletions
diff --git a/utils/src/ping_server.cc b/utils/src/ping_server.cc
new file mode 100755
index 000000000..19de34fec
--- /dev/null
+++ b/utils/src/ping_server.cc
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2017-2019 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>
+#include <hicn/transport/utils/daemonizator.h>
+#include <hicn/transport/utils/signer.h>
+#include <hicn/transport/utils/string_tokenizer.h>
+
+namespace transport {
+
+namespace interface {
+
+using HashAlgorithm = core::HashAlgorithm;
+using CryptoSuite = utils::CryptoSuite;
+
+utils::Identity setProducerIdentity(std::string keystore_name,
+ std::string keystore_password,
+ HashAlgorithm hash_algorithm) {
+ if (access(keystore_name.c_str(), F_OK) != -1) {
+ return utils::Identity(keystore_name, keystore_password, hash_algorithm);
+ } else {
+ return utils::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,
+ utils::Identity *identity, bool sign)
+ : buffer_(object_size, 'X'),
+ content_objects_(1 << log2_content_object_buffer_size),
+ mask_((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;
+ }
+ }
+
+ for (int i = 0; i < (1 << log2_content_object_buffer_size); i++) {
+ content_objects_[i] = std::make_shared<ContentObject>(
+ prefix, format, (const uint8_t *)buffer_.data(), buffer_.size());
+ content_objects_[i]->setLifetime(
+ default_values::content_object_expiry_time);
+ }
+ }
+
+ void processInterest(ProducerSocket &p, const Interest &interest) {
+ 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 (dump_) {
+ std::cout << "----- interest dump -----" << std::endl;
+ interest.dump();
+ std::cout << "-------------------------" << std::endl;
+ }
+
+ 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(default_values::content_object_expiry_time);
+ content_object->setLocator(interest.getLocator());
+ content_object->setSrcPort(interest.getDstPort());
+ content_object->setDstPort(interest.getSrcPort());
+ content_object->setTTL(ttl_);
+
+ if (sign_) {
+ content_object->setSignatureSize(identity_->getSignatureLength());
+ } else {
+ 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 (!quite_) std::cout << std::endl;
+
+ if (sign_) {
+ identity_->getSigner().sign(*content_object);
+ }
+
+ p.produce(*content_object);
+ }
+ }
+
+ 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_;
+ utils::Identity *identity_;
+ bool sign_;
+};
+
+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 << "-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;
+ std::cout << "-d daemon mode" << std::endl;
+ std::cout << "-H prints this message" << std::endl;
+}
+
+int main(int argc, char **argv) {
+ std::string name_prefix = "b001::0/64";
+ std::string delimiter = "/";
+ bool daemon = false;
+ bool verbose = false;
+ bool dump = false;
+ bool quite = false;
+ bool flags = false;
+ bool reset = false;
+ uint32_t object_size = 1350;
+ uint8_t ttl = 64;
+ std::string keystore_path = "./rsa_crypto_material.p12";
+ std::string keystore_password = "cisco";
+ bool sign = false;
+
+ int opt;
+ while ((opt = getopt(argc, argv, "s:n:t:qfrVDdHk:p:")) != -1) {
+ switch (opt) {
+ case 's':
+ object_size = std::stoi(optarg);
+ break;
+ case 'n':
+ name_prefix = optarg;
+ break;
+ case 't':
+ ttl = (uint8_t)std::stoi(optarg);
+ break;
+ case 'V':
+ verbose = true;
+ break;
+ case 'D':
+ dump = true;
+ break;
+ case 'q':
+ verbose = false;
+ dump = false;
+ quite = true;
+ break;
+ case 'd':
+ daemon = true;
+ break;
+ case 'f':
+ flags = true;
+ break;
+ case 'r':
+ reset = true;
+ break;
+ case 'k':
+ keystore_path = optarg;
+ sign = true;
+ break;
+ case 'p':
+ keystore_password = optarg;
+ break;
+ case 'H':
+ default:
+ help();
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (daemon) {
+ utils::Daemonizator::daemonize();
+ }
+
+ 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;
+ utils::Identity identity = setProducerIdentity(
+ keystore_path, keystore_password, HashAlgorithm::SHA_256);
+
+ if (sign) {
+ stubs = new CallbackContainer(n, object_size, verbose, dump, quite, flags,
+ reset, ttl, &identity, sign);
+ } else {
+ utils::Identity *identity = nullptr;
+ stubs = new CallbackContainer(n, object_size, verbose, dump, quite, flags,
+ reset, ttl, identity, sign);
+ }
+
+ asio::io_service io_service;
+
+ ProducerSocket p(io_service); // , setProducerIdentity());
+ p.registerPrefix(producer_namespace);
+
+ p.setSocketOption(GeneralTransportOptions::OUTPUT_BUFFER_SIZE, 0U);
+ p.setSocketOption(ProducerCallbacksOptions::CACHE_MISS,
+ (ProducerInterestCallback)bind(
+ &CallbackContainer::processInterest, stubs,
+ std::placeholders::_1, std::placeholders::_2));
+
+ p.connect();
+
+ p.serveForever();
+
+ return 0;
+}
+
+} // namespace interface
+
+} // end namespace transport
+
+int main(int argc, char **argv) {
+ return transport::interface::main(argc, argv);
+}