aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorAlberto Compagno <acompagn+fdio@cisco.com>2020-01-07 11:46:02 +0100
committerMauro Sardara <msardara@cisco.com>2020-02-21 15:48:18 +0100
commit35058cdfe0134c88f1aa8d23342d1d7b9d39e296 (patch)
tree978ca9c2232ac381c8391b3d1eeb0f875670d5b1 /utils
parent0710f1ff754ebf01ae5befabb055349fe472b0c2 (diff)
[HICN-2] Added P2P confidential communication on hICN
P2P confidential communications exploit the TLS 1.3 protocol to let a consumer to establish a secure communication on an hICN name. Currently we don't support the consumer authentication (mutual authentication in TLS) and the 0-rtt session establishment. Change-Id: I2be073847c08a17f28c837d444081920c5e57a07 Signed-off-by: Alberto Compagno <acompagn+fdio@cisco.com> Signed-off-by: Olivier Roques <oroques+fdio@cisco.com> Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'utils')
-rw-r--r--utils/src/hiperf.cc560
-rw-r--r--utils/src/ping_client.cc198
-rw-r--r--utils/src/ping_server.cc53
3 files changed, 532 insertions, 279 deletions
diff --git a/utils/src/hiperf.cc b/utils/src/hiperf.cc
index 078e9c3f1..dd6ed0840 100644
--- a/utils/src/hiperf.cc
+++ b/utils/src/hiperf.cc
@@ -13,10 +13,19 @@
* limitations under the License.
*/
+#include <hicn/transport/config.h>
#include <hicn/transport/interfaces/rtc_socket_producer.h>
#include <hicn/transport/interfaces/socket_consumer.h>
#include <hicn/transport/interfaces/socket_producer.h>
+#include <hicn/transport/utils/chrono_typedefs.h>
#include <hicn/transport/utils/identity.h>
+#include <hicn/transport/utils/signer.h>
+
+#ifdef SECURE_HICNTRANSPORT
+#include <hicn/transport/interfaces/p2psecure_socket_consumer.h>
+#include <hicn/transport/interfaces/p2psecure_socket_producer.h>
+#endif
+
#ifndef _WIN32
#include <hicn/transport/utils/daemonizator.h>
#endif
@@ -44,12 +53,8 @@ namespace interface {
#define ERROR_SUCCESS 0
#endif
#define ERROR_SETUP -5
-
#define MIN_PROBE_SEQ 0xefffffff
-using CryptoSuite = utils::CryptoSuite;
-using Identity = utils::Identity;
-
/**
* Container for command line configuration for hiperf client.
*/
@@ -61,13 +66,20 @@ struct ClientConfiguration {
drop_factor(-1.f),
window(-1),
virtual_download(true),
- producer_certificate("/tmp/rsa_certificate.pem"),
+ producer_certificate(""),
+ passphrase(""),
receive_buffer(nullptr),
download_size(0),
report_interval_milliseconds_(1000),
+ transport_protocol_(CBR),
rtc_(false),
test_mode_(false),
- interest_lifetime_(1000) {}
+#ifdef SECURE_HICNTRANSPORT
+ secure_(false),
+#endif
+ producer_prefix_(),
+ interest_lifetime_(500) {
+ }
Name name;
bool verify;
@@ -76,12 +88,17 @@ struct ClientConfiguration {
double window;
bool virtual_download;
std::string producer_certificate;
+ std::string passphrase;
std::shared_ptr<utils::MemBuf> receive_buffer;
std::size_t download_size;
std::uint32_t report_interval_milliseconds_;
TransportProtocolAlgorithms transport_protocol_;
bool rtc_;
bool test_mode_;
+#ifdef SECURE_HICNTRANSPORT
+ bool secure_;
+#endif
+ Prefix producer_prefix_;
uint32_t interest_lifetime_;
};
@@ -137,13 +154,20 @@ struct ServerConfiguration {
content_object_size(1440),
download_size(20 * 1024 * 1024),
hash_algorithm(HashAlgorithm::SHA_256),
- keystore_name("/tmp/rsa_crypto_material.p12"),
+ keystore_name(""),
+ passphrase(""),
keystore_password("cisco"),
multiphase_produce_(false),
rtc_(false),
interactive_(false),
production_rate_(std::string("2048kbps")),
- payload_size_(1400) {}
+ payload_size_(1400)
+#ifdef SECURE_HICNTRANSPORT
+ ,
+ secure_(false)
+#endif
+ {
+ }
Prefix name;
bool virtual_producer;
@@ -155,12 +179,16 @@ struct ServerConfiguration {
std::uint32_t download_size;
HashAlgorithm hash_algorithm;
std::string keystore_name;
+ std::string passphrase;
std::string keystore_password;
bool multiphase_produce_;
bool rtc_;
bool interactive_;
Rate production_rate_;
std::size_t payload_size_;
+#ifdef SECURE_HICNTRANSPORT
+ bool secure_;
+#endif
};
/**
@@ -168,6 +196,7 @@ struct ServerConfiguration {
*/
class RTCCallback;
class Callback;
+class KeyCallback;
/**
* Hiperf client class: configure and setup an hicn consumer following the
@@ -177,8 +206,9 @@ class HIperfClient {
typedef std::chrono::time_point<std::chrono::steady_clock> Time;
typedef std::chrono::microseconds TimeDuration;
- friend class RTCCallback;
friend class Callback;
+ friend class KeyCallback;
+ friend class RTCCallback;
public:
HIperfClient(const ClientConfiguration &conf)
@@ -189,10 +219,12 @@ class HIperfClient {
expected_seg_(0),
lost_packets_(std::unordered_set<uint32_t>()),
rtc_callback_(configuration_.rtc_ ? new RTCCallback(*this) : nullptr),
- callback_(configuration_.rtc_ ? nullptr : new Callback(*this)) {}
+ callback_(configuration_.rtc_ ? nullptr : new Callback(*this)),
+ key_callback_(configuration_.rtc_ ? nullptr : new KeyCallback(*this)) {}
~HIperfClient() {
delete callback_;
+ delete key_callback_;
delete rtc_callback_;
}
@@ -317,18 +349,35 @@ class HIperfClient {
int setup() {
int ret;
- // Set the transport algorithm
- TransportProtocolAlgorithms transport_protocol;
-
if (configuration_.rtc_) {
- transport_protocol = RTC;
+ configuration_.transport_protocol_ = RTC;
} else if (configuration_.window < 0) {
- transport_protocol = RAAQM;
+ configuration_.transport_protocol_ = RAAQM;
+ } else {
+ configuration_.transport_protocol_ = CBR;
+ }
+
+#ifdef SECURE_HICNSOCKET
+ if (configuration_.secure_) {
+ consumer_socket_ = std::make_shared<P2PSecureConsumerSocket>(
+ RAAQM, configuration_.transport_protocol_);
+ if (configuration_.producer_prefix_.getPrefixLength() == 0) {
+ std::cerr << "ERROR -- Missing producer prefix on which perform the "
+ "handshake."
+ << std::endl;
+ } else {
+ P2PSecureConsumerSocket &secure_consumer_socket =
+ *(static_cast<P2PSecureConsumerSocket *>(consumer_socket_.get()));
+ secure_consumer_socket.registerPrefix(configuration_.producer_prefix_);
+ }
} else {
- transport_protocol = CBR;
+#endif
+ consumer_socket_ =
+ std::make_shared<ConsumerSocket>(configuration_.transport_protocol_);
+#ifdef SECURE_HICNSOCKET
}
+#endif
- consumer_socket_ = std::make_unique<ConsumerSocket>(transport_protocol);
consumer_socket_->setSocketOption(
GeneralTransportOptions::INTEREST_LIFETIME,
configuration_.interest_lifetime_);
@@ -352,7 +401,8 @@ class HIperfClient {
return ERROR_SETUP;
}
- if (transport_protocol == RAAQM && configuration_.beta != -1.f) {
+ if (configuration_.transport_protocol_ == RAAQM &&
+ configuration_.beta != -1.f) {
if (consumer_socket_->setSocketOption(RaaqmTransportOptions::BETA_VALUE,
configuration_.beta) ==
SOCKET_OPTION_NOT_SET) {
@@ -360,7 +410,8 @@ class HIperfClient {
}
}
- if (transport_protocol == RAAQM && configuration_.drop_factor != -1.f) {
+ if (configuration_.transport_protocol_ == RAAQM &&
+ configuration_.drop_factor != -1.f) {
if (consumer_socket_->setSocketOption(RaaqmTransportOptions::DROP_FACTOR,
configuration_.drop_factor) ==
SOCKET_OPTION_NOT_SET) {
@@ -375,9 +426,25 @@ class HIperfClient {
}
if (configuration_.verify) {
- if (consumer_socket_->setSocketOption(
- GeneralTransportOptions::CERTIFICATE,
- configuration_.producer_certificate) == SOCKET_OPTION_NOT_SET) {
+ std::shared_ptr<utils::Verifier> verifier =
+ std::make_shared<utils::Verifier>();
+ PARCKeyId *key_id_;
+
+ if (!configuration_.producer_certificate.empty()) {
+ key_id_ = verifier->addKeyFromCertificate(
+ configuration_.producer_certificate);
+ if (key_id_ == nullptr) return ERROR_SETUP;
+ }
+
+ if (!configuration_.passphrase.empty()) {
+ key_id_ = verifier->addKeyFromPassphrase(
+ configuration_.passphrase, utils::CryptoSuite::HMAC_SHA256);
+ if (key_id_ == nullptr) return ERROR_SETUP;
+ }
+
+ if (consumer_socket_->setSocketOption(GeneralTransportOptions::VERIFIER,
+ verifier) ==
+ SOCKET_OPTION_NOT_SET) {
return ERROR_SETUP;
}
}
@@ -399,6 +466,11 @@ class HIperfClient {
}
if (!configuration_.rtc_) {
+ /* key_callback_->setConsumer(consumer_socket_); */
+ /* consumer_socket_->setSocketOption(ConsumerCallbacksOptions::READ_CALLBACK,
+ * key_callback_); */
+ /* consumer_socket_->setSocketOption(GeneralTransportOptions::KEY_CONTENT,
+ * true); */
ret = consumer_socket_->setSocketOption(
ConsumerCallbacksOptions::READ_CALLBACK, callback_);
} else {
@@ -476,10 +548,7 @@ class HIperfClient {
*max_length = mtu;
}
- void readDataAvailable(std::size_t length) noexcept override {
- // Do nothing
- return;
- }
+ void readDataAvailable(std::size_t length) noexcept override {}
size_t maxBufferSize() const override { return mtu; }
@@ -505,19 +574,12 @@ class HIperfClient {
bool isBufferMovable() noexcept override { return true; }
void getReadBuffer(uint8_t **application_buffer,
- size_t *max_length) override {
- // Not used
- }
+ size_t *max_length) override {}
- void readDataAvailable(std::size_t length) noexcept override {
- // Do nothing
- return;
- }
+ void readDataAvailable(std::size_t length) noexcept override {}
void readBufferAvailable(
- std::unique_ptr<utils::MemBuf> &&buffer) noexcept override {
- return;
- }
+ std::unique_ptr<utils::MemBuf> &&buffer) noexcept override {}
size_t maxBufferSize() const override { return read_size; }
@@ -547,6 +609,77 @@ class HIperfClient {
HIperfClient &client_;
};
+ class KeyCallback : public ConsumerSocket::ReadCallback {
+ static constexpr std::size_t read_size = 16 * 1024;
+
+ public:
+ KeyCallback(HIperfClient &hiperf_client)
+ : client_(hiperf_client), key_(nullptr) {}
+
+ bool isBufferMovable() noexcept override { return true; }
+
+ void getReadBuffer(uint8_t **application_buffer,
+ size_t *max_length) override {}
+
+ void readDataAvailable(std::size_t length) noexcept override {}
+
+ void readBufferAvailable(
+ std::unique_ptr<utils::MemBuf> &&buffer) noexcept override {
+ key_ = std::make_unique<std::string>((const char *)buffer->data(),
+ buffer->length());
+ std::cout << "Key: " << *key_ << std::endl;
+ }
+
+ size_t maxBufferSize() const override { return read_size; }
+
+ void readError(const std::error_code ec) noexcept override {
+ std::cerr << "Error " << ec.message() << " while reading from socket"
+ << std::endl;
+ client_.io_service_.stop();
+ }
+
+ bool verifyKey() { return !key_->empty(); }
+
+ void readSuccess(std::size_t total_size) noexcept override {
+ std::cout << "Key size: " << total_size << " bytes" << std::endl;
+ }
+
+ void afterRead() override {
+ std::shared_ptr<utils::Verifier> verifier =
+ std::make_shared<utils::Verifier>();
+ verifier->addKeyFromPassphrase(*key_, utils::CryptoSuite::HMAC_SHA256);
+
+ if (consumer_socket_) {
+ consumer_socket_->setSocketOption(GeneralTransportOptions::KEY_CONTENT,
+ false);
+ consumer_socket_->setSocketOption(GeneralTransportOptions::VERIFIER,
+ verifier);
+ } else {
+ std::cout << "Could not set verifier" << std::endl;
+ return;
+ }
+
+ if (consumer_socket_->verifyKeyPackets()) {
+ std::cout << "Verification of packet signatures successful"
+ << std::endl;
+ } else {
+ std::cout << "Could not verify packet signatures" << std::endl;
+ return;
+ }
+
+ std::cout << "Key retrieval done" << std::endl;
+ }
+
+ void setConsumer(std::shared_ptr<ConsumerSocket> consumer_socket) {
+ consumer_socket_ = consumer_socket;
+ }
+
+ private:
+ HIperfClient &client_;
+ std::unique_ptr<std::string> key_;
+ std::shared_ptr<ConsumerSocket> consumer_socket_;
+ };
+
ClientConfiguration configuration_;
Time t_stats_;
Time t_download_;
@@ -554,12 +687,13 @@ class HIperfClient {
uint64_t old_bytes_value_;
asio::io_service io_service_;
asio::signal_set signals_;
- std::unique_ptr<ConsumerSocket> consumer_socket_;
+ std::shared_ptr<ConsumerSocket> consumer_socket_;
uint32_t expected_seg_;
std::unordered_set<uint32_t> lost_packets_;
RTCCallback *rtc_callback_;
Callback *callback_;
-};
+ KeyCallback *key_callback_;
+}; // namespace interface
/**
* Hiperf server class: configure and setup an hicn producer following the
@@ -573,9 +707,12 @@ class HIperfServer {
: configuration_(conf),
signals_(io_service_, SIGINT),
rtc_timer_(io_service_),
+ unsatisfied_interests_(),
content_objects_((std::uint16_t)(1 << log2_content_object_buffer_size)),
content_objects_index_(0),
mask_((std::uint16_t)(1 << log2_content_object_buffer_size) - 1),
+ last_segment_(0),
+ ptr_last_segment_(&last_segment_),
#ifndef _WIN32
input_(io_service_),
rtc_running_(false)
@@ -599,39 +736,67 @@ class HIperfServer {
}
}
- void processInterest(ProducerSocket &p, const Interest &interest) {
+ void virtualProcessInterest(ProducerSocket &p, const Interest &interest) {
content_objects_[content_objects_index_ & mask_]->setName(
interest.getName());
producer_socket_->produce(
*content_objects_[content_objects_index_++ & mask_]);
}
- void processInterest2(ProducerSocket &p, const Interest &interest) {
- producer_socket_->setSocketOption(ProducerCallbacksOptions::CACHE_MISS,
- (ProducerInterestCallback)VOID_HANDLER);
- producer_socket_->setSocketOption(
- GeneralTransportOptions::CONTENT_OBJECT_EXPIRY_TIME, 5000_U32);
- produceContent(interest.getName().getSuffix());
- producer_socket_->setSocketOption(
- ProducerCallbacksOptions::CACHE_MISS,
- (ProducerInterestCallback)bind(&HIperfServer::processInterest2, this,
- std::placeholders::_1,
- std::placeholders::_2));
+ void processInterest(ProducerSocket &p, const Interest &interest) {
+ p.setSocketOption(ProducerCallbacksOptions::CACHE_MISS,
+ (ProducerInterestCallback)VOID_HANDLER);
+ p.setSocketOption(GeneralTransportOptions::CONTENT_OBJECT_EXPIRY_TIME,
+ 5000000_U32);
+
+ produceContent(p, interest.getName(), interest.getName().getSuffix());
+ std::cout << "Received interest " << interest.getName().getSuffix()
+ << std::endl;
}
- void produceContent(uint32_t suffix) {
- core::Name name = configuration_.name.getName();
+ void asyncProcessInterest(ProducerSocket &p, const Interest &interest) {
+ p.setSocketOption(ProducerCallbacksOptions::CACHE_MISS,
+ (ProducerInterestCallback)bind(
+ &HIperfServer::cacheMiss, this, std::placeholders::_1,
+ std::placeholders::_2));
+ p.setSocketOption(GeneralTransportOptions::CONTENT_OBJECT_EXPIRY_TIME,
+ 5000000_U32);
+ uint32_t suffix = interest.getName().getSuffix();
+
+ if (suffix == 0) {
+ last_segment_ = 0;
+ ptr_last_segment_ = &last_segment_;
+ unsatisfied_interests_.clear();
+ }
+
+ // The suffix will either be the one from the received interest or the
+ // smallest suffix of a previous interest not satisfed
+ if (!unsatisfied_interests_.empty()) {
+ auto it =
+ std::lower_bound(unsatisfied_interests_.begin(),
+ unsatisfied_interests_.end(), *ptr_last_segment_);
+ if (it != unsatisfied_interests_.end()) {
+ suffix = *it;
+ }
+ unsatisfied_interests_.erase(unsatisfied_interests_.begin(), it);
+ }
+
+ std::cout << "Received interest " << interest.getName().getSuffix()
+ << ", starting production at " << suffix << std::endl;
+ std::cout << unsatisfied_interests_.size() << " interests still unsatisfied"
+ << std::endl;
+ produceContentAsync(p, interest.getName(), suffix);
+ }
+ void produceContent(ProducerSocket &p, Name content_name, uint32_t suffix) {
auto b = utils::MemBuf::create(configuration_.download_size);
std::memset(b->writableData(), '?', configuration_.download_size);
b->append(configuration_.download_size);
uint32_t total;
utils::TimePoint t0 = utils::SteadyClock::now();
-
- total = producer_socket_->produce(
- name, std::move(b), !configuration_.multiphase_produce_, suffix);
-
+ total = p.produce(content_name, std::move(b),
+ !configuration_.multiphase_produce_, suffix);
utils::TimePoint t1 = utils::SteadyClock::now();
std::cout
@@ -641,7 +806,35 @@ class HIperfServer {
<< " us)" << std::endl;
}
- std::shared_ptr<utils::Identity> setProducerIdentity(
+ void produceContentAsync(ProducerSocket &p, Name content_name,
+ uint32_t suffix) {
+ auto b = utils::MemBuf::create(configuration_.download_size);
+ std::memset(b->writableData(), '?', configuration_.download_size);
+ b->append(configuration_.download_size);
+ /* std::string passphrase = "hunter2"; */
+ /* auto b = utils::MemBuf::create(passphrase.length() + 1); */
+ /* std::memcpy(b->writableData(), passphrase.c_str(), passphrase.length() +
+ * 1); */
+ /* b->append(passphrase.length() + 1); */
+
+ p.asyncProduce(content_name, std::move(b),
+ !configuration_.multiphase_produce_, suffix,
+ &ptr_last_segment_);
+ }
+
+ void cacheMiss(ProducerSocket &p, const Interest &interest) {
+ unsatisfied_interests_.push_back(interest.getName().getSuffix());
+ }
+
+ void onContentProduced(ProducerSocket &p, const std::error_code &err,
+ uint64_t bytes_written) {
+ p.setSocketOption(ProducerCallbacksOptions::CACHE_MISS,
+ (ProducerInterestCallback)bind(
+ &HIperfServer::asyncProcessInterest, this,
+ std::placeholders::_1, std::placeholders::_2));
+ }
+
+ std::shared_ptr<utils::Identity> getProducerIdentity(
std::string &keystore_name, std::string &keystore_password,
HashAlgorithm &hash_algorithm) {
if (access(keystore_name.c_str(), F_OK) != -1) {
@@ -649,28 +842,49 @@ class HIperfServer {
hash_algorithm);
} else {
return std::make_shared<utils::Identity>(keystore_name, keystore_password,
- CryptoSuite::RSA_SHA256, 1024,
- 365, "producer-test");
+ utils::CryptoSuite::RSA_SHA256,
+ 1024, 365, "producer-test");
}
}
int setup() {
int ret;
- if (configuration_.rtc_) {
- producer_socket_ = std::make_unique<RTCProducerSocket>();
+#ifdef SECURE_HICNSOCKET
+ if (configuration_.secure_) {
+ auto identity = getProducerIdentity(configuration_.keystore_name,
+ configuration_.keystore_password,
+ configuration_.hash_algorithm);
+ producer_socket_ = std::make_unique<P2PSecureProducerSocket>(
+ configuration_.rtc_, identity);
} else {
- producer_socket_ = std::make_unique<ProducerSocket>();
+#endif
+ if (configuration_.rtc_) {
+ producer_socket_ = std::make_unique<RTCProducerSocket>();
+ } else {
+ producer_socket_ = std::make_unique<ProducerSocket>();
+ }
+#ifdef SECURE_HICNSOCKET
}
+#endif
if (configuration_.sign) {
- auto identity = setProducerIdentity(configuration_.keystore_name,
- configuration_.keystore_password,
- configuration_.hash_algorithm);
+ std::shared_ptr<utils::Signer> signer;
+
+ if (!configuration_.passphrase.empty()) {
+ signer = std::make_shared<utils::Signer>(
+ configuration_.passphrase, utils::CryptoSuite::HMAC_SHA256);
+ } else if (!configuration_.keystore_name.empty()) {
+ auto identity = getProducerIdentity(configuration_.keystore_name,
+ configuration_.keystore_password,
+ configuration_.hash_algorithm);
+ signer = identity->getSigner();
+ } else {
+ return ERROR_SETUP;
+ }
- if (producer_socket_->setSocketOption(GeneralTransportOptions::IDENTITY,
- identity) ==
- SOCKET_OPTION_NOT_SET) {
+ if (producer_socket_->setSocketOption(GeneralTransportOptions::SIGNER,
+ signer) == SOCKET_OPTION_NOT_SET) {
return ERROR_SETUP;
}
}
@@ -699,17 +913,24 @@ class HIperfServer {
}
if (producer_socket_->setSocketOption(
+ GeneralTransportOptions::DATA_PACKET_SIZE,
+ (uint32_t)(configuration_.payload_size_)) ==
+ SOCKET_OPTION_NOT_SET) {
+ return ERROR_SETUP;
+ }
+
+ if (producer_socket_->setSocketOption(
GeneralTransportOptions::OUTPUT_BUFFER_SIZE, 200000U) ==
SOCKET_OPTION_NOT_SET) {
return ERROR_SETUP;
}
if (!configuration_.live_production) {
- produceContent(0);
+ produceContent(*producer_socket_, configuration_.name.getName(), 0);
} else {
ret = producer_socket_->setSocketOption(
ProducerCallbacksOptions::CACHE_MISS,
- (ProducerInterestCallback)bind(&HIperfServer::processInterest2,
+ (ProducerInterestCallback)bind(&HIperfServer::asyncProcessInterest,
this, std::placeholders::_1,
std::placeholders::_2));
@@ -727,8 +948,8 @@ class HIperfServer {
ret = producer_socket_->setSocketOption(
ProducerCallbacksOptions::CACHE_MISS,
- (ProducerInterestCallback)bind(&HIperfServer::processInterest, this,
- std::placeholders::_1,
+ (ProducerInterestCallback)bind(&HIperfServer::virtualProcessInterest,
+ this, std::placeholders::_1,
std::placeholders::_2));
if (ret == SOCKET_OPTION_NOT_SET) {
@@ -736,21 +957,25 @@ class HIperfServer {
}
}
+ ret = producer_socket_->setSocketOption(
+ ProducerCallbacksOptions::CONTENT_PRODUCED,
+ (ProducerContentCallback)bind(
+ &HIperfServer::onContentProduced, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3));
+
return ERROR_SUCCESS;
}
void sendRTCContentObjectCallback(std::error_code ec) {
- if (!ec) {
- rtc_timer_.expires_from_now(
- configuration_.production_rate_.getMicrosecondsForPacket(
- configuration_.payload_size_));
- rtc_timer_.async_wait(
- std::bind(&HIperfServer::sendRTCContentObjectCallback, this,
- std::placeholders::_1));
- auto payload =
- content_objects_[content_objects_index_++ & mask_]->getPayload();
- producer_socket_->produce(payload->data(), payload->length());
- }
+ if (ec) return;
+ rtc_timer_.expires_from_now(
+ configuration_.production_rate_.getMicrosecondsForPacket(
+ configuration_.payload_size_));
+ rtc_timer_.async_wait(std::bind(&HIperfServer::sendRTCContentObjectCallback,
+ this, std::placeholders::_1));
+ auto payload =
+ content_objects_[content_objects_index_++ & mask_]->getPayload();
+ producer_socket_->produce(payload->data(), payload->length());
}
#ifndef _WIN32
@@ -828,101 +1053,126 @@ class HIperfServer {
asio::io_service io_service_;
asio::signal_set signals_;
asio::steady_timer rtc_timer_;
+ std::vector<uint32_t> unsatisfied_interests_;
std::vector<std::shared_ptr<ContentObject>> content_objects_;
std::uint16_t content_objects_index_;
std::uint16_t mask_;
+ std::uint32_t last_segment_;
+ std::uint32_t *ptr_last_segment_;
std::unique_ptr<ProducerSocket> producer_socket_;
#ifndef _WIN32
asio::posix::stream_descriptor input_;
asio::streambuf input_buffer_;
bool rtc_running_;
#endif
-};
+}; // namespace interface
void usage() {
- std::cerr << std::endl;
std::cerr << "HIPERF - A tool for performing network throughput "
"measurements with hICN"
<< std::endl;
std::cerr << "usage: hiperf [-S|-C] [options] [prefix|name]" << std::endl;
- std::cerr << "Server or Client:" << std::endl;
+ std::cerr << std::endl;
+ std::cerr << "SERVER OR CLIENT:" << std::endl;
#ifndef _WIN32
- std::cerr << "-D = run as a daemon" << std::endl;
-
+ std::cerr << "-D\t\t\t\t\t"
+ << "Run as a daemon" << std::endl;
+ std::cerr << "-R\t\t\t\t\t"
+ << "Run RTC protocol (client or server)" << std::endl;
+ std::cerr << "-f\t<filename>\t\t\t"
+ << "Log file" << std::endl;
#endif
- std::cerr
- << "-R = run RTC protocol (client or server)"
- << std::endl;
- std::cerr << "-f <ouptup_log_file> = output log file path"
- << std::endl;
std::cerr << std::endl;
- std::cerr << "Server specific:" << std::endl;
- std::cerr << "-A <download_size> = size of the content to publish"
- "This is not the size of the packet (see -s for it)"
- << std::endl;
- std::cerr
- << "-s <payload_size> = size of the payload of each data packet"
- << std::endl;
- std::cerr << "-r = produce real content of "
- "content_size bytes"
+ std::cerr << "SERVER SPECIFIC:" << std::endl;
+ std::cerr << "-A\t<content_size>\t\t\t"
+ "Size of the content to publish. This "
+ "is not the size of the packet (see -s for it)."
<< std::endl;
- std::cerr << "-m = produce transport manifest"
+ std::cerr << "-s\t<packet_size>\t\t\tSize of the payload of each data packet."
<< std::endl;
- std::cerr << "-l = start producing content upon the "
- "reception of the first interest"
+ std::cerr << "-r\t\t\t\t\t"
+ << "Produce real content of <content_size> bytes" << std::endl;
+ std::cerr << "-m\t\t\t\t\t"
+ << "Produce transport manifest" << std::endl;
+ std::cerr << "-l\t\t\t\t\t"
+ << "Start producing content upon the reception of the "
+ "first interest"
<< std::endl;
- std::cerr << "-k <keystore_path> = path of p12 file containing the "
- "crypto material used for signing the packets"
+ std::cerr << "-K\t<keystore_path>\t\t\t"
+ << "Path of p12 file containing the "
+ "crypto material used for signing packets"
<< std::endl;
- std::cerr << "-y <hash_algorithm> = use the selected hash algorithm "
- "for calculating manifest digests"
+ std::cerr << "-k\t<passphrase>\t\t\t"
+ << "String from which a 128-bit symmetric key will be "
+ "derived for signing packets"
<< std::endl;
- std::cerr << "-p <password> = password for p12 keystore"
+ std::cerr << "-y\t<hash_algorithm>\t\t"
+ << "Use the selected hash algorithm for "
+ "calculating manifest digests"
<< std::endl;
- std::cerr
- << "-x = produce a content of <download_size>, "
- "then after downloading it produce a new content of"
- << std::endl;
- std::cerr << " <download_size> without "
- "resetting the suffix to 0"
+ std::cerr << "-p\t<password>\t\t\t"
+ << "Password for p12 keystore" << std::endl;
+ std::cerr << "-x\t\t\t\t\t"
+ << "Produce a content of <content_size>, then after downloading "
+ "it produce a new content of"
+ << "\n\t\t\t\t\t<content_size> without resetting "
+ "the suffix to 0."
<< std::endl;
- std::cerr << "-B <bitrate> = bitrate for RTC "
- "producer, to be used with the -R option"
+ std::cerr << "-B\t<bitrate>\t\t\t"
+ << "Bitrate for RTC producer, to be used with the -R option."
<< std::endl;
#ifndef _WIN32
- std::cerr << "-I = interactive mode,"
- "start/stop real time content production "
+ std::cerr << "-I\t\t\t\t\t"
+ "Interactive mode, start/stop real time content production "
"by pressing return. To be used with the -R option"
<< std::endl;
+#ifdef SECURE_HICNTRANSPORT
+ std::cerr << "-E\t\t\t\t\t"
+ << "Enable encrypted communication. Requires the path to a p12 "
+ "file containing the "
+ "crypto material used for the TLS handshake"
+ << std::endl;
+#endif
#endif
std::cerr << std::endl;
- std::cerr << "Client specific:" << std::endl;
- std::cerr << "-b <beta_parameter> = RAAQM beta parameter"
- << std::endl;
- std::cerr << "-d <drop_factor_parameter> = RAAQM drop factor parameter"
+ std::cerr << "CLIENT SPECIFIC:" << std::endl;
+ std::cerr << "-b\t<beta_parameter>\t\t"
+ << "RAAQM beta parameter" << std::endl;
+ std::cerr << "-d\t<drop_factor_parameter>\t\t"
+ << "RAAQM drop factor "
+ "parameter"
<< std::endl;
std::cerr << "-L\t<interest lifetime>\t\t"
<< "Set interest lifetime." << std::endl;
- std::cerr << "-M = store the content downloaded"
- "(default false)"
+ std::cerr << "-M\t<Download for real>\t\t"
+ << "Store the content downloaded." << std::endl;
+ std::cerr << "-W\t<window_size>\t\t\t"
+ << "Use a fixed congestion window "
+ "for retrieving the data."
+ << std::endl;
+ std::cerr << "-i\t<stats_interval>\t\t"
+ << "Show the statistics every <stats_interval> milliseconds."
<< std::endl;
- std::cerr << "-W <window_size> = use a fixed congestion window"
- "for retrieving the data"
+ std::cerr << "-v\t\t\t\t\t"
+ << "Enable verification of received data" << std::endl;
+ std::cerr << "-c\t<certificate_path>\t\t"
+ << "Path of the producer certificate to be used for verifying the "
+ "origin of the packets received. Must be used with -v."
<< std::endl;
- std::cerr << "-c <certificate_path> = path of the producer certificate"
- "to be used for verifying the origin of the packets received"
+ std::cerr << "-k\t<passphrase>\t\t\t"
+ << "String from which is derived the symmetric key used by the "
+ "producer to sign packets and by the consumer to verify them. "
+ "Must be used with -v."
<< std::endl;
- std::cerr << "-i <stats_interval> = show the statistics every "
- "<stats_interval> milliseconds"
+ std::cerr << "-t\t\t\t\t\t"
+ "Test mode, check if the client is receiving the "
+ "correct data. This is an RTC specific option, to be "
+ "used with the -R (default false)"
<< std::endl;
- std::cout
- << "-v = Enable verification of received data"
- << std::endl;
- std::cout
- << "-t = Test mode, check if the client is "
- "receiving the correct data. This is an RTC specific option, to be "
- "used with the -R (default false)"
- << std::endl;
+#ifdef SECURE_HICNTRANSPORT
+ std::cerr << "-P\t\t\t\t\t"
+ << "Prefix of the producer where to do the handshake" << std::endl;
+#endif
}
int main(int argc, char *argv[]) {
@@ -949,7 +1199,8 @@ int main(int argc, char *argv[]) {
int opt;
#ifndef _WIN32
while ((opt = getopt(argc, argv,
- "DSCf:b:d:W:RMc:vA:s:rmlk:y:p:hi:xB:ItL:")) != -1) {
+ "DSCf:b:d:W:RMc:vA:s:rmlK:k:y:p:hi:xE:P:B:ItL:")) !=
+ -1) {
switch (opt) {
// Common
case 'D': {
@@ -961,8 +1212,8 @@ int main(int argc, char *argv[]) {
break;
}
#else
- while ((opt = getopt(argc, argv, "SCf:b:d:W:RMc:vA:s:rmlk:y:p:hi:xB:tL:")) !=
- -1) {
+ while ((opt = getopt(argc, argv,
+ "SCf:b:d:W:RMc:vA:s:rmlK:k:y:p:hi:xB:E:P:tL:")) != -1) {
switch (opt) {
#endif
case 'f': {
@@ -984,6 +1235,13 @@ int main(int argc, char *argv[]) {
role += 1;
break;
}
+ case 'k': {
+ server_configuration.passphrase = std::string(optarg);
+ client_configuration.passphrase = std::string(optarg);
+ server_configuration.sign = true;
+ options = -1;
+ break;
+ }
// Client specifc
case 'b': {
@@ -1006,6 +1264,13 @@ int main(int argc, char *argv[]) {
options = 1;
break;
}
+#ifdef SECURE_HICNTRANSPORT
+ case 'P': {
+ client_configuration.producer_prefix_ = Prefix(optarg);
+ client_configuration.secure_ = true;
+ break;
+ }
+#endif
case 'c': {
client_configuration.producer_certificate = std::string(optarg);
options = 1;
@@ -1057,7 +1322,7 @@ int main(int argc, char *argv[]) {
options = -1;
break;
}
- case 'k': {
+ case 'K': {
server_configuration.keystore_name = std::string(optarg);
server_configuration.sign = true;
options = -1;
@@ -1097,6 +1362,13 @@ int main(int argc, char *argv[]) {
options = -1;
break;
}
+#ifdef SECURE_HICNTRANSPORT
+ case 'E': {
+ server_configuration.keystore_name = std::string(optarg);
+ server_configuration.secure_ = true;
+ break;
+ }
+#endif
case 'h':
default:
usage();
diff --git a/utils/src/ping_client.cc b/utils/src/ping_client.cc
index f88bc7eec..cdf786cba 100644
--- a/utils/src/ping_client.cc
+++ b/utils/src/ping_client.cc
@@ -40,7 +40,7 @@ typedef std::map<uint64_t, uint64_t> SendTimeMap;
typedef utils::Verifier Verifier;
class Configuration {
-public:
+ public:
uint64_t interestLifetime_;
uint64_t pingInterval_;
uint64_t maxPing_;
@@ -61,11 +61,11 @@ public:
uint8_t ttl_;
Configuration() {
- interestLifetime_ = 500; // ms
- pingInterval_ = 1000000; // us
- maxPing_ = 10; // number of interests
+ interestLifetime_ = 500; // ms
+ pingInterval_ = 1000000; // us
+ maxPing_ = 10; // number of interests
first_suffix_ = 0;
- name_ = "b001::1"; // string
+ name_ = "b001::1"; // string
srcPort_ = 9695;
dstPort_ = 8080;
verbose_ = false;
@@ -82,7 +82,7 @@ public:
};
class Client : interface::BasePortal::ConsumerCallback {
-public:
+ public:
Client(Configuration *c)
: portal_(), signals_(portal_.getIoService(), SIGINT) {
// Let the main thread to catch SIGINT
@@ -171,8 +171,7 @@ public:
std::cout << "-------------------------" << std::endl;
}
- if (!config_->quiet_)
- std::cout << std::endl;
+ if (!config_->quiet_) std::cout << std::endl;
if (!config_->always_syn_) {
if (object->testSyn() && object->testAck() && state_ == SYN_STATE) {
@@ -203,8 +202,7 @@ public:
std::cout << "-------------------------" << std::endl;
}
- if (!config_->quiet_)
- std::cout << std::endl;
+ if (!config_->quiet_) std::cout << std::endl;
timedout_++;
processed_++;
@@ -259,8 +257,7 @@ public:
std::cout << "-------------------------" << std::endl;
}
- if (!config_->quiet_)
- std::cout << std::endl;
+ if (!config_->quiet_) std::cout << std::endl;
send_timestamps_[sequence_number_] =
std::chrono::duration_cast<std::chrono::microseconds>(
@@ -297,7 +294,7 @@ public:
timedout_ = 0;
}
-private:
+ private:
SendTimeMap send_timestamps_;
interface::BasePortal portal_;
asio::signal_set signals_;
@@ -315,45 +312,38 @@ private:
};
void help() {
- std::cout << "usage: hicn-ping-client [options]" << std::endl;
- std::cout << "PING client options:" << std::endl;
- std::cout << "-i <ping_interval> = ping interval in microseconds "
- "(default 1000000ms)"
- << std::endl;
- std::cout << "-m <max_pings> = maximum number of pings to send "
- "(default 10)"
- << std::endl;
- std::cout << "-s <source_port> = source port (default 9695)"
- << std::endl;
- std::cout << "-d <destination_port> = destination port (default 8080)"
- << std::endl;
- std::cout << "-t <ttl> = 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::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 << "-A = send always ack messages "
+ 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 << "HICN options" << std::endl;
- std::cout << "-n <hicn_name> = hicn name (default b001::1)"
+ std::cout << "-S send always syn messages (default false)"
<< std::endl;
- std::cout << "-l <lifetime> = interest lifetime in "
- "milliseconds (default 500ms)"
+ 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::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::cout << "-D dump, dumps sent and received packets "
+ "(default false)"
<< std::endl;
- std::cout << "-q = quiet, not prints (default false)"
+ std::cout << "-q quiet, not prints (default false)"
<< std::endl;
- std::cout << "-H = prints this message" << std::endl;
+ std::cout << "-H prints this message" << std::endl;
}
int main(int argc, char *argv[]) {
@@ -368,64 +358,64 @@ int main(int argc, char *argv[]) {
while ((opt = getopt(argc, argv, "j::t:i:m:s:d:n:l:f:c:SAOqVDH")) != -1) {
switch (opt) {
- case 't':
- c->ttl_ = (uint8_t)std::stoi(optarg);
- break;
- case 'i':
- c->pingInterval_ = std::stoi(optarg);
- break;
- case 'm':
- 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);
- break;
- case 'n':
- c->name_ = optarg;
- break;
- 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;
- break;
- case 'A':
- c->always_syn_ = false;
- c->always_ack_ = true;
- c->open_ = false;
- break;
- case 'q':
- c->quiet_ = true;
- c->verbose_ = false;
- c->dump_ = false;
- break;
- case 'c':
- c->certificate_ = std::string(optarg);
- break;
- case 'H':
- default:
- help();
- exit(EXIT_FAILURE);
+ case 't':
+ c->ttl_ = (uint8_t)std::stoi(optarg);
+ break;
+ case 'i':
+ c->pingInterval_ = std::stoi(optarg);
+ break;
+ case 'm':
+ 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);
+ break;
+ case 'n':
+ c->name_ = optarg;
+ break;
+ 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;
+ break;
+ case 'A':
+ c->always_syn_ = false;
+ c->always_ack_ = true;
+ c->open_ = false;
+ break;
+ case 'q':
+ c->quiet_ = true;
+ c->verbose_ = false;
+ c->dump_ = false;
+ break;
+ case 'c':
+ c->certificate_ = std::string(optarg);
+ break;
+ case 'H':
+ default:
+ help();
+ exit(EXIT_FAILURE);
}
}
@@ -446,11 +436,11 @@ int main(int argc, char *argv[]) {
return 0;
}
-} // namespace ping
+} // namespace ping
-} // namespace core
+} // namespace core
-} // namespace transport
+} // namespace transport
int main(int argc, char *argv[]) {
return transport::core::ping::main(argc, argv);
diff --git a/utils/src/ping_server.cc b/utils/src/ping_server.cc
index 049ab3ac5..cd51ce5c3 100644
--- a/utils/src/ping_server.cc
+++ b/utils/src/ping_server.cc
@@ -81,8 +81,7 @@ class CallbackContainer {
}
}
- void processInterest(ProducerSocket &p, const Interest &interest,
- uint32_t lifetime) {
+ void processInterest(ProducerSocket &p, const Interest &interest, uint32_t lifetime) {
if (verbose_) {
std::cout << "<<< received interest " << interest.getName()
<< " src port: " << interest.getSrcPort()
@@ -146,7 +145,7 @@ class CallbackContainer {
if (!quite_) std::cout << std::endl;
if (sign_) {
- identity_->getSigner().sign(*content_object);
+ identity_->getSigner()->sign(*content_object);
}
p.produce(*content_object);
@@ -169,35 +168,28 @@ class CallbackContainer {
};
void help() {
- std::cout << "usage: hicn-ping-server [options]" << std::endl;
- std::cout << "PING server options" << std::endl;
- std::cout
- << "-s <content_size> = object content size (default 1350B)"
- << std::endl;
- std::cout << "-n <hicn_name> = 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 <lifetime> = data lifetime" << std::endl;
- std::cout << "-r = always reply with a reset flag "
+ 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 << "-t <ttl> = set ttl (default 64)"
+ 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::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::cout << "-D dump, dumps sent and received packets (default false)"
<< std::endl;
+ std::cout << "-q quite, not prints (default false)" << std::endl;
#ifndef _WIN32
- std::cout << "-d = daemon mode" << std::endl;
+ std::cout << "-d daemon mode" << std::endl;
#endif
- std::cout << "-H = prints help options" << std::endl;
+ std::cout << "-H prints this message" << std::endl;
}
int main(int argc, char **argv) {
@@ -238,8 +230,8 @@ int main(int argc, char **argv) {
ttl = (uint8_t)std::stoi(optarg);
break;
case 'l':
- data_lifetime = std::stoi(optarg);
- break;
+ data_lifetime = std::stoi(optarg);
+ break;
case 'V':
verbose = true;
break;
@@ -307,11 +299,10 @@ int main(int argc, char **argv) {
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, data_lifetime));
+ p.setSocketOption(ProducerCallbacksOptions::CACHE_MISS,
+ (ProducerInterestCallback)bind(
+ &CallbackContainer::processInterest, stubs,
+ std::placeholders::_1, std::placeholders::_2, data_lifetime));
p.connect();