A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
examples_qkd_etsi_combined_input.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2022 www.tk.etf.unsa.ba
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Execute using ./waf --run scratch/qkd_etsi_combined_input.cc --command-template="mpirun -np 4 %s"
19 *
20 * Author: Emir Dervisevic <emir.dervisevic@etf.unsa.ba>
21 * Miralem Mehic <miralem.mehic@ieee.org>
22 */
23#include <stdio.h>
24#include <fstream>
25#include "ns3/core-module.h"
26#include "ns3/applications-module.h"
27#include "ns3/internet-module.h"
28#include "ns3/flow-monitor-module.h"
29#include "ns3/mobility-module.h"
30#include "ns3/point-to-point-module.h"
31#include "ns3/internet-apps-module.h"
32#include "ns3/gnuplot.h"
33
34#include "ns3/qkd-link-helper.h"
35#include "ns3/qkd-app-helper.h"
36#include "ns3/qkd-app-004.h"
37
38#include "ns3/network-module.h"
39#include "ns3/internet-apps-module.h"
40#include "ns3/netanim-module.h"
41#include "ns3/mpi-module.h"
42
43using namespace ns3;
44
45NS_LOG_COMPONENT_DEFINE ("QKD_ETSI004");
46
49std::map<std::string, Ipv4InterfaceContainer> m_interfaces;
50
51std::string outputFileType ("json");
52std::ofstream logFile;
53nlohmann::json outputLogFile;
54
56{
57 std::string title;
58 std::string nodes;
59 uint32_t type; //0-PP; 1-ETSI004; 2-ETSI014
60
70
76
87
92
97
100
103
106
109
111
112 std::map<std::string, uint32_t> m_keyIDGeneratedInBuffers;
113 std::map<std::string, uint32_t> m_keyIDConsumedInBuffers;
114 std::map<std::string, uint32_t> m_keyIDConsumedByKMS;
115};
116
117std::map<std::string, LinkDetails*> m_nodePairs;
118
119void
120write_csv(std::string filename, std::vector<std::pair<std::string, std::vector<uint32_t>>> dataset)
121{
122 // Make a CSV file with one or more columns of integer values
123 // Each column of data is represented by the pair <column name, column data>
124 // as std::pair<std::string, std::vector<int>>
125 // The dataset is represented as a vector of these columns
126 // Note that all columns should be the same size
127
128 // Create an output filestream object
129 std::ofstream myFile(filename);
130
131 // Send column names to the stream
132 for(uint32_t j = 0; j < dataset.size(); ++j)
133 {
134 myFile << dataset.at(j).first;
135 if(j != dataset.size() - 1) myFile << ","; // No comma at end of line
136 }
137 myFile << "\n";
138
139 // Send data to the stream
140 for(uint32_t i = 0; i < dataset.at(0).second.size(); ++i)
141 {
142 for(uint32_t j = 0; j < dataset.size(); ++j)
143 {
144 myFile << dataset.at(j).second.at(i);
145 if(j != dataset.size() - 1) myFile << ","; // No comma at end of line
146 }
147 myFile << "\n";
148 }
149
150 // Close the file
151 myFile.close();
152}
153
154
155std::vector<std::pair<std::string, std::vector<uint32_t>>>
156read_csv(std::string filename){
157 // Reads a CSV file into a vector of <string, vector<uint32_t>> pairs where
158 // each pair represents <column name, column values>
159
160 // Create a vector of <string, uint32_t vector> pairs to store the result
161 std::vector<std::pair<std::string, std::vector<uint32_t> > > result;
162
163 // Create an input filestream
164 std::ifstream myFile(filename);
165
166 // Make sure the file is open
167 if(!myFile.is_open()) throw std::runtime_error("Could not open file");
168
169 // Helper vars
170 std::string line, colname;
172
173 // Read the column names
174 if(myFile.good())
175 {
176 // Extract the first line in the file
177 std::getline(myFile, line);
178
179 // Create a stringstream from line
180 std::stringstream ss(line);
181
182 // Extract each column name
183 while(std::getline(ss, colname, ',')){
184
185 // Initialize and add <colname, uint32_t vector> pairs to result
186 result.push_back({colname, std::vector<uint32_t> {}});
187 }
188 }
189
190 // Read data, line by line
191 while(std::getline(myFile, line))
192 {
193 // Create a stringstream of the current line
194 std::stringstream ss(line);
195
196 // Keep track of the current column index
197 uint32_t colIdx = 0;
198
199 // Extract each integer
200 while(ss >> val){
201
202 // Add the current integer to the 'colIdx' column's values vector
203 result.at(colIdx).second.push_back(val);
204
205 // If the next token is a comma, ignore it and move on
206 if(ss.peek() == ',') ss.ignore();
207
208 // Increment the column index
209 colIdx++;
210 }
211 }
212
213 // Close file
214 myFile.close();
215 return result;
216}
217
218
219//////////
220void
221KeyGenerated(std::string context, const std::string& appId, const std::string& keyId, const uint32_t& amountInBits){
222
223 std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.find(appId);
224 std::string linkId = it->second->nodes;
225
226
227 std::map<std::string, uint32_t>::iterator it2 = it->second->m_keyIDGeneratedInBuffers.find ( keyId );
228 if (it2 == it->second->m_keyIDGeneratedInBuffers.end ()){
229 it->second->m_keyIDGeneratedInBuffers.insert( std::make_pair( keyId, amountInBits));
230 }else{
231 it->second->m_keysGeneratedBits += amountInBits;
232 it->second->m_keysGenerated++;
233
234 if(showKeyAdded){
235 if(outputFileType == "csv"){
236 logFile << (double)Simulator::Now().GetSeconds() << ",+," << linkId << "," << amountInBits;
237 logFile << std::endl;
238 }else if(outputFileType == "json"){
239 if(outputLogFile.size() > 0){
240 logFile << ',';
241 }
242 nlohmann::json jsonRecord;
244 jsonRecord["id"] = linkId;
245 jsonRecord["action"] = "+";
246 jsonRecord["keysize"] = amountInBits;
247 outputLogFile.push_back(jsonRecord);
248 logFile << jsonRecord.dump();;
249 logFile << std::endl;
250 }
251 }
252 }
253}
254
255/**
256 * Keys fetched from qkdBuffers for transformation before delivery to end-user application
257 */
258void
259KeyConsumedLink (std::string context, const uint32_t& srcNodeId, const uint32_t& dstNodeId, const uint32_t& amountInBits)
260{
261 //std::cout << context << "\tsrcNodeId:" << srcNodeId << "\t dstNodeId:" << dstNodeId << "\tamountInBits:" << amountInBits << "\n";
262
263 for (std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.begin(); it != m_nodePairs.end(); ++it)
264 {
265 if(it->second->type == 0 && it->second->srcKMSNodeId == srcNodeId && it->second->dstKMSNodeId == dstNodeId){
266
267 std::string linkId = it->second->nodes;
268
269 it->second->m_keysConsumed++;
270 it->second->m_keysConsumedBits += amountInBits;
271
272 if(showKeyAdded){
273 if(outputFileType == "csv"){
274 logFile << (double)Simulator::Now().GetSeconds() << ",-," << linkId << "," << amountInBits;
275 logFile << std::endl;
276 }else if(outputFileType == "json"){
277 if(outputLogFile.size() > 0){
278 logFile << ',';
279 }
280 nlohmann::json jsonRecord;
282 jsonRecord["id"] = linkId;
283 jsonRecord["action"] = "-";
284 jsonRecord["keysize"] = amountInBits;
285 outputLogFile.push_back(jsonRecord);
286 logFile << jsonRecord.dump();;
287 logFile << std::endl;
288 }
289 }
290 break;
291 }
292 }
293
294}
295
296/**
297 * Keys served from KMS to end-user application
298 */
299void
300KeyServed (std::string context, const std::string& appId, const std::string& keyId, const uint32_t& amountInBits)
301{
302
303 //std::cout << appId << ";" << keyId << ";" << amountInBits << "\n";
304 std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.find(appId);
305 std::string linkId = it->second->nodes;
306 std::string jointKeyId = keyId + std::to_string(amountInBits);
307
308 std::map<std::string, uint32_t>::iterator it2 = it->second->m_keyIDConsumedInBuffers.find ( jointKeyId );
309
310 if (it2 == it->second->m_keyIDConsumedInBuffers.end ()){
311 it->second->m_keyIDConsumedInBuffers.insert( std::make_pair( jointKeyId, amountInBits) );
312
313 }else{
314 //std::cout << "consumed" << "\t" << it->second->nodes << "\n";
315 it->second->m_keysConsumedBits += amountInBits;
316 it->second->m_keysConsumed++;
317
318 if(showKeyServed){
319 if(outputFileType == "csv"){
320 logFile << (double)Simulator::Now().GetSeconds() << ",-," << linkId << "," << amountInBits;
321 logFile << std::endl;
322 }else if(outputFileType == "json"){
323 if(outputLogFile.size() > 0){
324 logFile << ',';
325 }
326 nlohmann::json jsonRecord;
328 jsonRecord["id"] = linkId;
329 jsonRecord["action"] = "-";
330 jsonRecord["keysize"] = amountInBits;
331 outputLogFile.push_back(jsonRecord);
332 logFile << jsonRecord.dump();;
333 logFile << std::endl;
334 }
335 }
336 }
337
338}
339
340void
342 std::string context,
343 const uint32_t& nodeId,
344 const uint32_t& srcNodeId,
345 const uint32_t& dstNodeId,
347){
348
349 for (std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.begin(); it != m_nodePairs.end(); ++it)
350 {
351 if(it->second->type == 0 && ( (it->second->srcKMSNodeId == srcNodeId && it->second->dstKMSNodeId == dstNodeId)
352 || (it->second->srcKMSNodeId == dstNodeId && it->second->dstKMSNodeId == srcNodeId))){
353
354 std::string linkId = it->second->nodes;
355
356 it->second->m_keysRelayed++;
357 it->second->m_keysRelayedBits += amountInBits;
358
359 if(showKeyAdded){
360 if(outputFileType == "csv"){
361 logFile << (double)Simulator::Now().GetSeconds() << ",r," << linkId << "," << amountInBits;
362 logFile << std::endl;
363 }else if(outputFileType == "json"){
364 if(outputLogFile.size() > 0){
365 logFile << ',';
366 }
367 nlohmann::json jsonRecord;
369 jsonRecord["id"] = linkId;
370 jsonRecord["action"] = "r";
371 jsonRecord["keysize"] = amountInBits;
372 outputLogFile.push_back(jsonRecord);
373 logFile << jsonRecord.dump();;
374 logFile << std::endl;
375 }
376 }
377 break;
378 }
379 }
380}
381
382void
383SentPacket(std::string context, const std::string& appId, Ptr<const Packet> p)
384{
385 std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.find(appId);
386 std::string linkId = it->second->nodes;
387
388 it->second->m_bytes_sent += p->GetSize();
389 it->second->m_appPacketsSent++;
390
391 if(outputFileType == "csv"){
392 logFile << (double)Simulator::Now().GetSeconds() << ",app2app_data," << linkId << "," << p->GetSize();
393 logFile << std::endl;
394 }else if(outputFileType == "json"){
395 if(outputLogFile.size() > 0){
396 logFile << ',';
397 }
398 nlohmann::json jsonRecord;
400 jsonRecord["id"] = linkId;
401 jsonRecord["action"] = "app2app_data";
402 jsonRecord["keysize"] = p->GetSize();
403 outputLogFile.push_back(jsonRecord);
404 logFile << jsonRecord.dump();;
405 logFile << std::endl;
406 }
407}
408
410 std::string linkName,
412){
413 //std::cout << "check link exist " << linkName << "\n";
414 //std::map<std::string, Ipv4InterfaceContainer>::iterator it2;
415 //for (it2 = m_interfaces.begin(); it2 != m_interfaces.end(); ++it2) std::cout << it2->first << "\n";
416
417 //check whether p2p link between srcNode and dstNode is already established
418 std::map<std::string, Ipv4InterfaceContainer>::iterator it = m_interfaces.find(linkName);
419 if(it != m_interfaces.end()){
420 interfacesToApp = it->second;
421 return true;
422 }
423 return false;
424}
425
426void MissedSendPacketCall (std::string context, const std::string& appId, Ptr<const Packet> p)
427{
428 std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.find(appId);
429 it->second->m_missedSendPacketCalls++;
430}
431
432void
433ReceivedPacket(std::string context, const std::string& appId, Ptr<const Packet> p)
434{
435 std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.find(appId);
436 it->second->m_bytes_received += p->GetSize();
437 it->second->m_appPacketsReceived++;
438}
439
440void
441SentPacketSig(std::string context, const std::string& appId, Ptr<const Packet> p)
442{
443 std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.find(appId);
444 it->second->m_sig_bytes_sent += p->GetSize();
445 it->second->m_appSigPacketsSent++;
446 std::string linkId = it->second->nodes;
447
448 if(outputFileType == "csv"){
449 logFile << (double)Simulator::Now().GetSeconds() << ",app2app_sig," << linkId << "," << p->GetSize();
450 logFile << std::endl;
451 }else if(outputFileType == "json"){
452 if(outputLogFile.size() > 0){
453 logFile << ',';
454 }
455 nlohmann::json jsonRecord;
457 jsonRecord["id"] = linkId;
458 jsonRecord["action"] = "app2app_sig";
459 jsonRecord["keysize"] = p->GetSize();
460 outputLogFile.push_back(jsonRecord);
461 logFile << jsonRecord.dump();;
462 logFile << std::endl;
463 }
464}
465
466void
467ReceivedPacketSig(std::string context, const std::string& appId, Ptr<const Packet> p)
468{
469 std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.find(appId);
470 it->second->m_sig_bytes_received += p->GetSize();
471 it->second->m_appSigPacketsReceived++;
472}
473
474void
475SentPacketToKMS(std::string context, const std::string& appId, Ptr<const Packet> p)
476{
477 std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.find(appId);
478 it->second->m_bytes_sent_to_kms += p->GetSize();
479 it->second->m_kmsPacketsSent++;
480 std::string linkId = it->second->nodes;
481
482 if(showKeyAdded){
483 if(outputFileType == "csv"){
484 logFile << (double)Simulator::Now().GetSeconds() << ",app2kms," << linkId << "," << p->GetSize();
485 logFile << std::endl;
486 }else if(outputFileType == "json"){
487 if(outputLogFile.size() > 0){
488 logFile << ',';
489 }
490 nlohmann::json jsonRecord;
492 jsonRecord["id"] = linkId;
493 jsonRecord["action"] = "app2kms";
494 jsonRecord["keysize"] = p->GetSize();
495 outputLogFile.push_back(jsonRecord);
496 logFile << jsonRecord.dump();;
497 logFile << std::endl;
498 }
499 }
500}
501
502void
503ReceivedPacketFromKMS(std::string context, const std::string& appId, Ptr<const Packet> p)
504{
505 std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.find(appId);
506 it->second->m_bytes_received_from_kms += p->GetSize();
507 it->second->m_kmsPacketsReceived++;
508 std::string linkId = it->second->nodes;
509
510 if(showKeyServed){
511 if(outputFileType == "csv"){
512 logFile << (double)Simulator::Now().GetSeconds() << ",kms2app," << linkId << "," << p->GetSize();
513 logFile << std::endl;
514 }else if(outputFileType == "json"){
515 if(outputLogFile.size() > 0){
516 logFile << ',';
517 }
518 nlohmann::json jsonRecord;
520 jsonRecord["id"] = linkId;
521 jsonRecord["action"] = "kms2app";
522 jsonRecord["keysize"] = p->GetSize();
523 outputLogFile.push_back(jsonRecord);
524 logFile << jsonRecord.dump();;
525 logFile << std::endl;
526 }
527 }
528}
529
530void
532{
533 std::vector<std::pair<std::string, std::vector<uint32_t> > > output;
534
535 for (std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.begin(); it != m_nodePairs.end(); ++it) {
536
537 if(it->second->m_printed)continue;
538
539 std::vector<uint32_t> temp(45,0);
540 temp[0] = it->second->type;
541
542 if(it->second->type == 0){
543
544 double avgSizeOfConsumedKeys = 0;
545 for (std::map<std::string, uint32_t>::iterator it2 = it->second->m_keyIDConsumedInBuffers.begin();
546 it2 != it->second->m_keyIDConsumedInBuffers.end(); ++it2) {
547 avgSizeOfConsumedKeys += it2->second;
548 }
549 avgSizeOfConsumedKeys = avgSizeOfConsumedKeys/it->second->m_keyIDConsumedInBuffers.size();
550 it->second->m_avgSizeOfConsumedKeys = avgSizeOfConsumedKeys;
551
552 double avgSizeOfGeneratedKeys = 0;
553 for (std::map<std::string, uint32_t>::iterator it2 = it->second->m_keyIDGeneratedInBuffers.begin();
554 it2 != it->second->m_keyIDGeneratedInBuffers.end(); ++it2) {
555 avgSizeOfGeneratedKeys += it2->second;
556 }
557 avgSizeOfGeneratedKeys = avgSizeOfGeneratedKeys/it->second->m_keyIDGeneratedInBuffers.size();
558 it->second->m_avgSizeOfGeneratedKeys = avgSizeOfGeneratedKeys;
559
560 temp[1] = it->second->m_linkDistance;
561 temp[2] = it->second->m_keyRate;
562 temp[3] = it->second->m_keysGenerated;
563 temp[4] = it->second->m_keysGeneratedBits;
564 temp[5] = it->second->m_keysConsumed;
565 temp[6] = it->second->m_keysConsumedBits;
566 temp[7] = it->second->m_avgSizeOfGeneratedKeys;
567 temp[8] = it->second->m_avgSizeOfConsumedKeys;
568 temp[9] = it->second->m_bufferCapacityBits;
569 temp[23] = it->second->m_startTime;
570 temp[24] = it->second->m_stopTime;
571
572 temp[36] = it->second->m_keysRelayed;
573 temp[37] = it->second->m_keysRelayedBits;
574 //temp[38] = it->second->m_keysWasted;
575 //temp[39] = it->second->m_keysWastedBits;
576
577 }else{
578
579 double avgSizeOfConsumedKeys = 0;
580 for (std::map<std::string, uint32_t>::iterator it2 = it->second->m_keyIDConsumedInBuffers.begin();
581 it2 != it->second->m_keyIDConsumedInBuffers.end(); ++it2) {
582 avgSizeOfConsumedKeys += it2->second;
583 }
584 avgSizeOfConsumedKeys = avgSizeOfConsumedKeys/it->second->m_keyIDConsumedInBuffers.size();
585 it->second->m_avgSizeOfConsumedKeys = avgSizeOfConsumedKeys;
586
587 temp[10] = it->second->m_bytes_sent;
588 temp[11] = it->second->m_bytes_received;
589 temp[12] = it->second->m_appPacketsSent;
590 temp[13] = it->second->m_appPacketsReceived;
591 temp[14] = it->second->m_missedSendPacketCalls;
592 temp[15] = it->second->m_encryptionType;
593 temp[16] = it->second->m_authenticationType;
594 temp[17] = it->second->m_aesLifeTime;
595 temp[18] = it->second->m_packetSize;
596 temp[19] = it->second->m_trafficRate;
597 temp[20] = it->second->m_sizeOfKeyBufferForEncryption;
598 temp[21] = it->second->m_sizeOfKeyBufferForAuthentication;
599 temp[22] = it->second->m_numberOfKeysToFetchFromKMS;
600 temp[23] = it->second->m_startTime;
601 temp[24] = it->second->m_stopTime;
602
603 temp[5] = it->second->m_keysConsumed;
604 temp[6] = it->second->m_keysConsumedBits;
605 temp[8] = it->second->m_avgSizeOfConsumedKeys;
606
607 temp[25] = it->second->m_sig_bytes_sent;
608 temp[26] = it->second->m_sig_bytes_received;
609 temp[27] = it->second->m_appSigPacketsSent;
610 temp[28] = it->second->m_appSigPacketsReceived;
611
612 temp[29] = it->second->m_bytes_sent_to_kms;
613 temp[30] = it->second->m_bytes_received_from_kms;
614 temp[31] = it->second->m_kmsPacketsSent;
615 temp[32] = it->second->m_kmsPacketsReceived;
616
617
618 }
619
620 output.push_back( std::make_pair( it->second->nodes, temp) );
621 it->second->m_printed = 1;
622 }
623
625}
626
627void
629
630 // prepare a JSON file
631 nlohmann::json output;
632
633 //Initialize JSON file
634 for (std::map<std::string, LinkDetails* >::iterator it = m_nodePairs.begin(); it != m_nodePairs.end(); ++it) {
635
636 if(it->second->m_printed)continue;
637 std::string nodes = it->second->nodes;
638
639 if(it->second->type == 0){
640 output["qkd_links"][nodes]["Link distance (meters)"] = 0;
641 output["qkd_links"][nodes]["Key rate (bit/sec)"] = 0;
642 output["qkd_links"][nodes]["Key-pairs generated"] = 0;
643 output["qkd_links"][nodes]["Key-pairs generated (bits)"] = 0;
644 output["qkd_links"][nodes]["Key-pairs consumed"] = 0;
645 output["qkd_links"][nodes]["Key-pairs consumed (bits)"] = 0;
646 output["qkd_links"][nodes]["Key-pairs relayed"] = 0;
647 output["qkd_links"][nodes]["Key-pairs relayed (bits)"] = 0;
648 //output["qkd_links"][nodes]["Key-pairs wasted"] = 0;
649 //output["qkd_links"][nodes]["Key-pairs wasted (bits)"] = 0;
650 output["qkd_links"][nodes]["Average size of generated key-pairs (bits)"] = 0;
651 output["qkd_links"][nodes]["Average size of consumed key-pairs (bits)"] = 0;
652 output["qkd_links"][nodes]["Start Time (sec)"] = 0;
653 output["qkd_links"][nodes]["Stop Time (sec)"] = 0;
654 output["qkd_links"][nodes]["QKDBuffer Capacity (bits)"] = 0;
655 }else{
656 std::string type = (it->second->type == 1) ? "etsi_004": "etsi_014";
657 output[type][nodes]["QKDApps Statistics"]["Bytes Sent"] = 0;
658 output[type][nodes]["QKDApps Statistics"]["Bytes Received"] = 0;
659 output[type][nodes]["QKDApps Statistics"]["Packets Sent"] = 0;
660 output[type][nodes]["QKDApps Statistics"]["Packets Received"] = 0;
661 output[type][nodes]["QKDApps Statistics"]["Missed send packet calls"] = 0;
662 output[type][nodes]["QKDApps Statistics"]["Key/Data utilization (%)"] = 0;
663
664 output[type][nodes]["QKDApps Statistics"]["Encryption"] = 0;
665 output[type][nodes]["QKDApps Statistics"]["Authentication"] = 0;
666 output[type][nodes]["QKDApps Statistics"]["AES Key Lifetime (bytes)"] = 0;
667 output[type][nodes]["QKDApps Statistics"]["Size of Key Buffer for Encryption"] = 0;
668 output[type][nodes]["QKDApps Statistics"]["Size of Key Buffer for Authentication"] = 0;
669 output[type][nodes]["QKDApps Statistics"]["Number of Keys to Fetch From KMS"] = 0;
670 output[type][nodes]["QKDApps Statistics"]["Packet Size (bytes)"] = 0;
671 output[type][nodes]["QKDApps Statistics"]["Traffic Rate (bit/sec)"] = 0;
672 output[type][nodes]["QKDApps Statistics"]["Start Time (sec)"] = 0;
673 output[type][nodes]["QKDApps Statistics"]["Stop Time (sec)"] = 0;
674
675 output[type][nodes]["Signaling Statistics"]["Bytes Sent"] = 0;
676 output[type][nodes]["Signaling Statistics"]["Bytes Received"] = 0;
677 output[type][nodes]["Signaling Statistics"]["Packets Sent"] = 0;
678 output[type][nodes]["Signaling Statistics"]["Packets Received"] = 0;
679
680 output[type][nodes]["QKDApps-KMS Statistics"]["Bytes Sent"] = 0;
681 output[type][nodes]["QKDApps-KMS Statistics"]["Bytes Received"] = 0;
682 output[type][nodes]["QKDApps-KMS Statistics"]["Packets Sent"] = 0;
683 output[type][nodes]["QKDApps-KMS Statistics"]["Packets Received"] = 0;
684
685 output[type][nodes]["Key Consumption Statistics"]["Key-pairs consumed"] = 0;
686 output[type][nodes]["Key Consumption Statistics"]["Key-pairs consumed (bits)"] = 0;
687 output[type][nodes]["Key Consumption Statistics"]["Average size of consumed key-pairs (bits)"] = 0;
688 }
689 }
690
691 //merge values from CPU results
692 std::vector<std::vector<std::pair<std::string, std::vector<uint32_t>>>> cpuValues;
693 for(uint32_t i = 0; i<cpuCounter; i++){
694 std::string tempStatsFile = "temp_stats_" + std::to_string(i);
695 std::vector<std::pair<std::string, std::vector<uint32_t>>> temp = read_csv(tempStatsFile);
696 cpuValues.push_back(temp);
697 remove(tempStatsFile.c_str());
698 }
699
700 //write merged values to JSON file
701 //for each cpu value
702 for(uint32_t i = 0; i<cpuValues.size(); i++)
703 {
704 //for each column in cpu value file
705 for(uint32_t j=0; j<cpuValues.at(i).size(); j++ )
706 {
707 if(i>0){
708 //for each value in column
709 for(uint32_t k=1; k<cpuValues.at(i).at(j).second.size(); k++ ){
710 cpuValues.at(0).at(j).second.at(k) += cpuValues.at(i).at(j).second.at(k);
711 }
712 }
713
714 if(i+1 == cpuValues.size()){
715 std::string type = "qkd_links";
716 std::string nodes = cpuValues.at(i).at(j).first;
717
718 if(cpuValues.at(i).at(j).second.at(0) == 1) {
719 type = "etsi_004";
720 }else if(cpuValues.at(i).at(j).second.at(0) == 2){
721 type = "etsi_014";
722 }
723
724 std::cout << "********************************** \n\n";
725
726 if(type == "qkd_links"){
727 output[type][nodes]["Link distance (meters)"] = cpuValues.at(0).at(j).second.at(1);
728 output[type][nodes]["Key rate (bit/sec)"] = cpuValues.at(0).at(j).second.at(2);
729 output[type][nodes]["Key-pairs generated"] = cpuValues.at(0).at(j).second.at(3);
730 output[type][nodes]["Key-pairs generated (bits)"] = cpuValues.at(0).at(j).second.at(4);
731 output[type][nodes]["Key-pairs consumed"] = cpuValues.at(0).at(j).second.at(5);
732 output[type][nodes]["Key-pairs consumed (bits)"] = cpuValues.at(0).at(j).second.at(6);
733 output[type][nodes]["Key-pairs relayed"] = cpuValues.at(0).at(j).second.at(36);
734 output[type][nodes]["Key-pairs relayed (bits)"] = cpuValues.at(0).at(j).second.at(37);
735 //output[type][nodes]["Key-pairs wasted"] = cpuValues.at(0).at(j).second.at(38);
736 //output[type][nodes]["Key-pairs wasted (bits)"] = cpuValues.at(0).at(j).second.at(39);
737 output[type][nodes]["Average size of generated key-pairs (bits)"] = cpuValues.at(0).at(j).second.at(7);
738 output[type][nodes]["Average size of consumed key-pairs (bits)"] = cpuValues.at(0).at(j).second.at(8);
739 output[type][nodes]["QKDBuffer Capacity (bits)"] = cpuValues.at(0).at(j).second.at(9);
740 output[type][nodes]["Start Time (sec)"] = cpuValues.at(0).at(j).second.at(23);
741 output[type][nodes]["Stop Time (sec)"] = cpuValues.at(0).at(j).second.at(24);
742
743
744 std::cout << "QKD LINK: " << nodes << "\n"
745 << "\nQKDBuffer Capacity (bits):\t" << output[type][nodes]["QKDBuffer Capacity (bits)"]
746 << "\nLink distance (meters):\t\t" << output[type][nodes]["Link distance (meters)"]
747 << "\nKey rate (bit/sec):\t\t" << output[type][nodes]["Key rate (bit/sec)"]
748 << "\nKey-pairs generated:\t" << output[type][nodes]["Key-pairs generated"]
749 << "\tKey-pairs generated (bits):\t" << output[type][nodes]["Key-pairs generated (bits)"]
750 << "\nKey-pairs consumed:\t" << output[type][nodes]["Key-pairs consumed"]
751 << "\tKey-pairs consumed (bits):\t" << output[type][nodes]["Key-pairs consumed (bits)"]
752 << "\nKey-pairs relayed:\t" << output[type][nodes]["Key-pairs relayed"]
753 << "\tKey-pairs relayed (bits):\t" << output[type][nodes]["Key-pairs relayed (bits)"]
754 //<< "\nKey-pairs wasted:\t" << output[type][nodes]["Key-pairs wasted"]
755 //<< "\tKey-pairs wasted (bits):\t" << output[type][nodes]["Key-pairs wasted (bits)"]
756 << "\nAvg size of generated keys (bits):\t" << output[type][nodes]["Average size of generated key-pairs (bits)"]
757 << "\nAvg size of consumed keys (bits):\t" << output[type][nodes]["Average size of consumed key-pairs (bits)"]
758 << "\nStart Time (sec):\t\t" << output[type][nodes]["Start Time (sec)"]
759 << "\nStop Time (sec):\t\t" << output[type][nodes]["Stop Time (sec)"]
760 << "\n\n";
761
762 }else{
763 output[type][nodes]["QKDApps Statistics"]["Bytes Sent"] = cpuValues.at(0).at(j).second.at(10);
764 output[type][nodes]["QKDApps Statistics"]["Bytes Received"] = cpuValues.at(0).at(j).second.at(11);
765 output[type][nodes]["QKDApps Statistics"]["Packets Sent"] = cpuValues.at(0).at(j).second.at(12);
766 output[type][nodes]["QKDApps Statistics"]["Packets Received"] = cpuValues.at(0).at(j).second.at(13);
767 output[type][nodes]["QKDApps Statistics"]["Missed send packet calls"] = cpuValues.at(0).at(j).second.at(14);
768
769 double utilization = 0;
770 if(cpuValues.at(0).at(j).second.at(12) && cpuValues.at(0).at(j).second.at(14)){
771 utilization = (double) cpuValues.at(0).at(j).second.at(12) / (double) (cpuValues.at(0).at(j).second.at(12) + cpuValues.at(0).at(j).second.at(14));
772 utilization *= 100;
773 utilization = std::ceil(utilization * 100.0) / 100.0;
774 }
775 output[type][nodes]["QKDApps Statistics"]["Key/Data utilization (%)"] = utilization;
776
777 output[type][nodes]["QKDApps Statistics"]["Encryption"] = cpuValues.at(0).at(j).second.at(15);
778 if(output[type][nodes]["QKDApps Statistics"]["Encryption"] == 0){
779 output[type][nodes]["QKDApps Statistics"]["Encryption"] = "Unencrypted";
780 }else if(output[type][nodes]["QKDApps Statistics"]["Encryption"] == 1){
781 output[type][nodes]["QKDApps Statistics"]["Encryption"] = "OTP";
782 }else if(output[type][nodes]["QKDApps Statistics"]["Encryption"] == 2){
783 output[type][nodes]["QKDApps Statistics"]["Encryption"] = "AES-256";
784 output[type][nodes]["QKDApps Statistics"]["AES Key Lifetime (bytes)"] = cpuValues.at(0).at(j).second.at(17);
785 }
786
787 output[type][nodes]["QKDApps Statistics"]["Authentication"] = cpuValues.at(0).at(j).second.at(16);
788 if(output[type][nodes]["QKDApps Statistics"]["Authentication"] == 0){
789 output[type][nodes]["QKDApps Statistics"]["Authentication"] = "Unauthenticated";
790 }else if(output[type][nodes]["QKDApps Statistics"]["Authentication"] == 1){
791 output[type][nodes]["QKDApps Statistics"]["Authentication"] = "VMAC";
792 }else{
793 output[type][nodes]["QKDApps Statistics"]["Authentication"] = "SHA-1";
794 }
795
796 output[type][nodes]["QKDApps Statistics"]["Packet Size (bytes)"] = cpuValues.at(0).at(j).second.at(18);
797 output[type][nodes]["QKDApps Statistics"]["Traffic Rate (bit/sec)"] = cpuValues.at(0).at(j).second.at(19);
798
799 if(type == "etsi_004"){
800 output[type][nodes]["QKDApps Statistics"]["Size of Key Buffer for Encryption"] = cpuValues.at(0).at(j).second.at(20);
801 output[type][nodes]["QKDApps Statistics"]["Size of Key Buffer for Authentication"] = cpuValues.at(0).at(j).second.at(21);
802 }else{
803 output[type][nodes]["QKDApps Statistics"]["Number of Keys to Fetch From KMS"] = cpuValues.at(0).at(j).second.at(22);
804 }
805
806 output[type][nodes]["QKDApps Statistics"]["Start Time (sec)"] = cpuValues.at(0).at(j).second.at(23);
807 output[type][nodes]["QKDApps Statistics"]["Stop Time (sec)"] = cpuValues.at(0).at(j).second.at(24);
808
809 output[type][nodes]["Signaling Statistics"]["Bytes Sent"] = cpuValues.at(0).at(j).second.at(25);
810 output[type][nodes]["Signaling Statistics"]["Bytes Received"] = cpuValues.at(0).at(j).second.at(26);
811 output[type][nodes]["Signaling Statistics"]["Packets Sent"] = cpuValues.at(0).at(j).second.at(27);
812 output[type][nodes]["Signaling Statistics"]["Packets Received"] = cpuValues.at(0).at(j).second.at(28);
813
814 output[type][nodes]["QKDApps-KMS Statistics"]["Bytes Sent"] = cpuValues.at(0).at(j).second.at(29);
815 output[type][nodes]["QKDApps-KMS Statistics"]["Bytes Received"] = cpuValues.at(0).at(j).second.at(30);
816 output[type][nodes]["QKDApps-KMS Statistics"]["Packets Sent"] = cpuValues.at(0).at(j).second.at(31);
817 output[type][nodes]["QKDApps-KMS Statistics"]["Packets Received"] = cpuValues.at(0).at(j).second.at(32);
818
819 output[type][nodes]["Key Consumption Statistics"]["Key-pairs consumed"] = cpuValues.at(0).at(j).second.at(5);
820 output[type][nodes]["Key Consumption Statistics"]["Key-pairs consumed (bits)"] = cpuValues.at(0).at(j).second.at(6);
821 output[type][nodes]["Key Consumption Statistics"]["Average size of consumed key-pairs (bits)"] = cpuValues.at(0).at(j).second.at(8);
822
823 std::cout << "QKDApps " << type << ": " << nodes << "\n\n"
824 << "Encryption:\t" << output[type][nodes]["QKDApps Statistics"]["Encryption"];
825 if(output[type][nodes]["QKDApps Statistics"]["Encryption"] == "AES-256"){
826 std::cout << "\nAES Key Lifetime (bytes):\t" << output[type][nodes]["QKDApps Statistics"]["AES Key Lifetime (bytes)"];
827 }
828 std::cout
829 << "\nAuthentication:\t" << output[type][nodes]["QKDApps Statistics"]["Authentication"]
830 << "\nPacket Size (bytes):\t" << output[type][nodes]["QKDApps Statistics"]["Packet Size (bytes)"]
831 << "\nTraffic Rate (bit/sec):\t" << output[type][nodes]["QKDApps Statistics"]["Traffic Rate (bit/sec)"];
832
833 if(type == "etsi_004"){
834 std::cout
835 << "\nSize of Key Buffer for Encryption:\t" << output[type][nodes]["QKDApps Statistics"]["Size of Key Buffer for Encryption"]
836 << "\nSize of Key Buffer for Authentication:\t" << output[type][nodes]["QKDApps Statistics"]["Size of Key Buffer for Authentication"];
837 }else{
838 std::cout
839 << "\nNumber of Keys to Fetch From KMS:\t" << output[type][nodes]["QKDApps Statistics"]["Number of Keys to Fetch From KMS"];
840 }
841
842 std::cout
843 << "\nMissed send packet calls:\t" << output[type][nodes]["QKDApps Statistics"]["Missed send packet calls"]
844 << "\nSent (bytes):\t" << output[type][nodes]["QKDApps Statistics"]["Bytes Sent"]
845 << "\tReceived (bytes):\t" << output[type][nodes]["QKDApps Statistics"]["Bytes Received"]
846 << "\nSent (Packets):\t" << output[type][nodes]["QKDApps Statistics"]["Packets Sent"]
847 << "\tReceived (Packets):\t" << output[type][nodes]["QKDApps Statistics"]["Packets Received"]
848 << "\nKey/Data utilization (%):\t" << output[type][nodes]["QKDApps Statistics"]["Key/Data utilization (%)"]
849
850 << "\nRatio (bytes):\t" << (float)output[type][nodes]["QKDApps Statistics"]["Bytes Received"]/(float)output[type][nodes]["QKDApps Statistics"]["Bytes Sent"]
851 << "\tRatio (packets):\t" << (float)output[type][nodes]["QKDApps Statistics"]["Packets Received"]/(float)output[type][nodes]["QKDApps Statistics"]["Packets Sent"]
852 << "\nStart Time (sec):\t" << output[type][nodes]["QKDApps Statistics"]["Start Time (sec)"]
853 << "\nStop Time (sec):\t" << output[type][nodes]["QKDApps Statistics"]["Stop Time (sec)"]
854 << "\n"
855
856 << "\n- Signaling stats:"
857 << "\nSent (bytes):\t" << output[type][nodes]["Signaling Statistics"]["Bytes Sent"]
858 << "\tReceived (bytes):\t" << output[type][nodes]["Signaling Statistics"]["Bytes Received"]
859 << "\nSent (Packets):\t" << output[type][nodes]["Signaling Statistics"]["Packets Sent"]
860 << "\tReceived (Packets):\t" << output[type][nodes]["Signaling Statistics"]["Packets Received"]
861 << "\n";
862
863 std::cout << "\n- QKDApps to KMS stats:"
864 << "\nSent (bytes):\t" << output[type][nodes]["QKDApps-KMS Statistics"]["Bytes Sent"]
865 << "\tReceived (bytes):\t" << output[type][nodes]["QKDApps-KMS Statistics"]["Bytes Received"]
866 << "\nSent (Packet):\t" << output[type][nodes]["QKDApps-KMS Statistics"]["Packets Sent"]
867 << "\tReceived (Packet):\t" << output[type][nodes]["QKDApps-KMS Statistics"]["Packets Received"]
868 << "\n";
869
870 std::cout << "\n- Key Consumption Statistics:"
871 << "\nKey-pairs consumed:\t" << output[type][nodes]["Key Consumption Statistics"]["Key-pairs consumed"]
872 << "\nKey-pairs consumed (bits):\t" << output[type][nodes]["Key Consumption Statistics"]["Key-pairs consumed (bits)"]
873 << "\nAverage size of consumed key-pairs (bits):\t" << output[type][nodes]["Key Consumption Statistics"]["Average size of consumed key-pairs (bits)"]
874 << "\n\n";
875 }
876 }
877
878 }
879 }
880
881 std::ofstream statFile;
882 statFile.open(outputStatsName, std::ofstream::out | std::ofstream::trunc);
883 statFile << output.dump();
884}
885
886std::string
888
889 return "2ms";
890 //distance in meter
891 double distance = distanceInMeters;
892 //distance in kilometer
893 distance = distance / 1000;
894 //apply ITU-T Rec. M.2301 (07/2002) - Table 6 (page 15)
895 if(distance < 1000) {
896 distance *= 1.5;
897 }else if(distance > 1000 && distance < 1200) {
898 distance = 1500;
899 }else{
900 distance *= 1.2;
901 }
902 uint32_t avgDelay = 1;
903 if(distance > 5){
904 avgDelay = ceil((double)distance/5.0);
905 }
906 std::string delayString = std::to_string(avgDelay) + "us";
907 return delayString;
908}
909
910int main (int argc, char *argv[])
911{
912 uint64_t execTime;
913 struct timespec tick, tock;
915
916 // Sequential fallback values
917 uint32_t systemId = 0;
919
923
924 std::cout << "SystemId: " << systemId << std::endl;
925 GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::DistributedSimulatorImpl"));
926
927 NS_LOG_INFO ("Create nodes.");
931 double appHoldTime = 0.5;
932 uint16_t simulationTime = 150;
933 uint32_t encryptionType = 1; //0-unencrypted, 1-OTP, 2-AES256
935 uint32_t aesLifetime = 10000; //In bytes! 64GB = 68719476736B
937 uint32_t authenticationType = 1; //0-unauthenticated, 1-VMAC, 2-SHA1
940
941 uint32_t appRate = 100000; //In bps
942 uint32_t appPacketSize = 800; //In bytes
943 uint32_t ppKeyRate = 10000; //In bps
944 uint32_t ppKeySize = 8192; //In bytes
945 uint32_t ppPacketSize = 100; //In bytes
946 uint32_t ppRate = 1000;
947
948 std::string outputFileName ("output.json");
949 std::string outputStatsName("stats.json");
950 std::string inputFileName("input.json");
951 std::string srcNodeId;
952 std::string dstNodeId;
953
954 bool trace = false;
960 uint32_t seedValue = 0;
961 double startTime = 0;
962 double stopTime = 0;
963 std::string linkName;
964
965 // Configure command line parameters
967 cmd.AddValue ("showKeyServed", "Show trace when a key is served from KMS", showKeyServed);
968 cmd.AddValue ("showKeyAdded", "Show trace when a key is generated", showKeyAdded);
969 cmd.AddValue ("simTime", "Simulation time (seconds)", simulationTime);
970 cmd.AddValue ("useCrypto", "Perform crypto functions?", useCrypto);
971 cmd.AddValue ("trace", "Enable datapath stats and pcap traces", trace);
972 cmd.AddValue ("outputFile", "Name of the output file", outputFileName);
973 cmd.AddValue ("outputType", "Type of the output file", outputFileType);
974 cmd.AddValue ("inputFile", "Type of the input file", inputFileName);
975 cmd.AddValue ("statsFile", "Name of the output json stats file", outputStatsName);
976 cmd.AddValue ("seed", "Random Seed Value", seedValue);
977 cmd.Parse (argc, argv);
978
979 GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::DistributedSimulatorImpl"));
980
983 uint32_t systemID2 = 2;
984
985 if(systemCount == 1){
986 systemID0 = 0;
987 systemID1 = 0;
988 systemID2 = 0;
989 }else if(systemCount == 2){
990 systemID0 = 0;
991 systemID1 = 1;
992 systemID2 = 0;
993 }else if(systemCount == 3){
994 systemID0 = 0;
995 systemID1 = 1;
996 systemID2 = 2;
997 }
998
999 // read a JSON file
1000 nlohmann::json inputParams;
1001 try {
1002 std::ifstream inputValues(inputFileName);
1004 numberOfQKDLinks = inputParams["qkd_links"].size();
1005 numberOfETSI004ApplicationLinks = inputParams["etsi_004"].size();
1006 numberOfETSI014ApplicationLinks = inputParams["etsi_014"].size();
1007 } catch(...) {
1008 NS_LOG_FUNCTION( "JSON parse error!");
1009 }
1010
1011 if(systemId == systemID0){
1012 logFile.open(outputFileName, std::ofstream::out | std::ofstream::trunc);
1013 if(outputFileType == "json" && (showKeyAdded || showKeyServed)) logFile << '[';
1014 }
1015
1016 //FILTER QKD NODES - make them unique
1017 std::vector<std::string> qkdNodesIDs;
1018 for(uint32_t a=0; a<numberOfQKDLinks;a++)
1019 {
1020 srcNodeId = inputParams["qkd_links"][a]["srcNodeId"].dump();
1021 dstNodeId = inputParams["qkd_links"][a]["dstNodeId"].dump();
1022 qkdNodesIDs.push_back(srcNodeId);
1023 qkdNodesIDs.push_back(dstNodeId);
1024 }
1025 //fetch unique list of QKD nodes
1026 std::sort(qkdNodesIDs.begin(), qkdNodesIDs.end());
1027 auto last = std::unique(qkdNodesIDs.begin(), qkdNodesIDs.end());
1028 qkdNodesIDs.erase(last, qkdNodesIDs.end());
1029
1031 if(systemId == systemID0){
1032 std::cout << "Unique size of QKDNodes: " << qkdNodesIDs.size() << "\n";
1033 }
1034
1035 //FILTER ETSI014 NODES
1037 {
1038 srcNodeId = inputParams["etsi_004"][a]["srcNodeId"].dump();
1039 dstNodeId = inputParams["etsi_004"][a]["dstNodeId"].dump();
1040
1041 if (std::find(qkdNodesIDs.begin(), qkdNodesIDs.end(),srcNodeId)==qkdNodesIDs.end())
1042 NS_FATAL_ERROR ( "Independent application nodes are not supported! " << srcNodeId);
1043 if (std::find(qkdNodesIDs.begin(), qkdNodesIDs.end(),dstNodeId)==qkdNodesIDs.end())
1044 NS_FATAL_ERROR ( "Idependent application nodes are not supported! " << dstNodeId);
1045 }
1046
1047 //FILTER ETSI014 NODES
1048 std::vector<std::string> etsi004nodes;
1050 {
1051 srcNodeId = inputParams["etsi_004"][a]["srcNodeId"].dump();
1052 dstNodeId = inputParams["etsi_004"][a]["dstNodeId"].dump();
1053
1054 if (std::find(qkdNodesIDs.begin(), qkdNodesIDs.end(),srcNodeId)==qkdNodesIDs.end())
1055 NS_FATAL_ERROR ( "Independent application nodes are not supported! " << srcNodeId);
1056 if (std::find(qkdNodesIDs.begin(), qkdNodesIDs.end(),dstNodeId)==qkdNodesIDs.end())
1057 NS_FATAL_ERROR ( "Independent application nodes are not supported! " << dstNodeId);
1058 }
1059
1062 srand( seedValue ); //seeding for the first time only!
1063
1064 //In input.json nodes counter start from one while
1066 n.Add (zeroNode);
1068 KMSNodes.Add(zeroNode);
1069
1070 //For each QKDNode, we have additional QKDControl and LKMS
1071 //Thus, for n QKD nodes, we have n*3 nodes (QKDnode + QKDControl + LKMS)
1073
1074 for(uint32_t i=1; i<=numberOfQKDNodes; i++){
1075 //QKDnode
1077 n.Add (node1);
1078 }
1079 for(uint32_t i=1; i<=numberOfQKDNodes; i++){
1080 //LKMS
1082 n.Add (node3);
1083 QControlNodes.Add(node3);
1084 }
1085 for(uint32_t i=1; i<=numberOfQKDNodes; i++){
1086 //QKDControl
1088 n.Add (node2);
1089 KMSNodes.Add(node2);
1090 }
1091
1092
1093 if(systemId == systemID0) {
1094 std::cout << "Number of CPUs:\t" << systemCount << "\n";
1095 std::cout << "Number of QKD Nodes:\t" << numberOfQKDNodes << "\n";
1096 std::cout << "Number of QKD Links:\t" << numberOfQKDLinks << "\n";
1097 std::cout << "Number of ETSI 004 Application Links:\t" << numberOfETSI004ApplicationLinks << "\n";
1098 std::cout << "Number of ETSI 014 Application Links:\t" << numberOfETSI014ApplicationLinks << "\n";
1099 std::cout << "Number of Nodes:\t" << numberOfNodes << "\n\n";
1100 }
1101
1102 //install QKD Control the node (numberOfQKDNodes+i)
1105 std::vector<Ptr<QKDControl> > m_qkdControl;
1106 for(uint32_t i=1; i<=numberOfQKDNodes;i++){
1107 Ptr<QKDControl> control = QLinkHelper.InstallQKDNController ( QControlNodes.Get(i) );
1108 m_qkdControl.push_back(control);
1109 if(systemId == systemID0) {
1110 std::cout << "Install QKDNControl on node: " << QControlNodes.Get(i)->GetId() << "\n";
1111 }
1112 }
1113 QLinkHelper.ConfigureQBuffers ( //Configure Q-Buffers
1114 {m_qkdControl},
1115 1024, //min
1116 51200, //thr
1117 500000000, //max
1118 0, //current
1119 512 //default key size in bits
1120 );
1121 QLinkHelper.ConfigureRSBuffers ( //Configure S-Buffers for relay (RBuffers)!
1122 {m_qkdControl},
1123 0,
1124 16000, //Treshold
1125 64000, //Mmax
1126 0,
1127 512
1128 );
1129
1131 internet.Install (n);
1132
1133 // Set Mobility for all nodes
1135 mobility.SetPositionAllocator ("ns3::RandomRectanglePositionAllocator",
1136 "X", StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1000.0]"),
1137 "Y", StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1000.0]"));
1138 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1139 mobility.Install(n);
1140
1141 // We create the channels first without any IP addressing information
1142 NS_LOG_INFO ("Create channels.");
1143 std::string p2pDataRate = "100Mbps";
1145 p2p.SetDeviceAttribute ("DataRate", StringValue (p2pDataRate));
1146 p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
1147
1148
1149 //
1150 // We've got the "hardware" in place. Now we need to add IP addresses.
1151 //
1152 NS_LOG_INFO ("Assign IP Addresses.");
1154 ipv4.SetBase ("10.1.0.0", "255.255.255.0");
1155
1156 if(systemId == systemID0)
1157 std::cout << "\n*********\n*** KMS Configuration\n*********\n";
1158
1159 uint32_t maximalKeysPerRequest = 10;// inputParams["kms_nodes"]["maximalKeysPerRequest"];
1160 uint32_t minimalKeySize = 32;//inputParams["kms_nodes"]["minimalKeySize"];
1161 uint32_t maximalKeySize = 8192;//inputParams["kms_nodes"]["maximalKeySize"];
1162
1163 Config::SetDefault ("ns3::QKDKeyManagerSystemApplication::MaximalKeySize", UintegerValue (maximalKeySize));
1164 Config::SetDefault ("ns3::QKDKeyManagerSystemApplication::MinimalKeySize", UintegerValue (minimalKeySize));
1165 Config::SetDefault ("ns3::QKDKeyManagerSystemApplication::MaximalKeysPerRequest", UintegerValue (maximalKeysPerRequest));
1166
1167 if(systemId == systemID0)
1168 {
1169 std::cout << "MaximalKeySize: " << maximalKeySize << std::endl;
1170 std::cout << "MinimalKeySize: " << minimalKeySize << std::endl;
1171 std::cout << "MaximalKeysPerRequest: " << maximalKeysPerRequest << std::endl;
1172 }
1173
1174 for(uint32_t i=1; i<=numberOfQKDNodes; i++){
1175
1176 //create p2p link qkdnode<->KMS
1178 linkName = std::to_string(n.Get(i)->GetId()) + "_" + std::to_string(KMSNodes.Get(i)->GetId());
1180
1183 std::string ipV4Base = "10.1." + std::to_string(m_interfaces.size()+1) + ".0";
1184 ipv4.SetBase(ipV4Base.c_str(), "255.255.255.0");
1186 m_interfaces.insert( std::make_pair( linkName , interfacesBetweenQNodeKMS) );
1187
1188 std::cout
1189 << "Create link QKDNode-KMS: " << n.Get(i)->GetId() << "(" << interfacesBetweenQNodeKMS.GetAddress(0) << ")"
1190 << "-"
1191 << KMSNodes.Get(i)->GetId() << "(" << interfacesBetweenQNodeKMS.GetAddress(1) << ")"
1192 << "\n";
1193
1194 if( !KMSNodes.Get(i)->GetObject<QKDKeyManagerSystemApplication>() ){
1195
1196 if(systemId == systemID0) {
1197 std::cout << "Install KMS on node " << KMSNodes.Get(i)->GetId() << " with IP address: " << interfacesBetweenQNodeKMS.GetAddress(1) << std::endl;
1198 }
1199
1200 //install KMs
1201 QAHelper.InstallKeyManager(//Install key manager for site A
1202 KMSNodes.Get(i),//Node KM-A
1203 interfacesBetweenQNodeKMS.GetAddress(1), //IP address KM-A
1204 80, //Port
1205 m_qkdControl[i-1] //Assigned controller A
1206 );
1207 }
1208 }
1209
1210 }
1211
1212
1213
1214 if(systemId == systemID0)
1215 std::cout << "\n*********\n*** Post-Processing Configuration\n*********\n";
1216
1217
1218 for(uint32_t i=0; i<KMSNodes.GetN();i++){
1219 std::cout << "KMSNode: " << KMSNodes.Get(i)->GetId() << "\n";
1220 }
1221
1222
1223 //////////////////////////////////////
1224 // QKD LINKS
1225 //////////////////////////////////////
1226 std::vector<uint32_t> keySizes = {1024, 2048, 4096, 8192}; //, 16384};
1227 std::vector<uint32_t> keyRates = {5000, 10000, 15000}; //, 20000};
1228 std::vector<uint32_t> ppPacketSizes = {100,150,200,250,300,350};
1229 std::vector<uint32_t> ppRates = {1000, 1500, 2000, 2500, 3000};
1230 uint32_t maxBufferCapacity = 50000000;
1231 for(uint32_t a=0; a<numberOfQKDLinks;a++)
1232 {
1233 srcNodeId = inputParams["qkd_links"][a]["srcNodeId"].dump();
1234 dstNodeId = inputParams["qkd_links"][a]["dstNodeId"].dump();
1235
1236 int i=std::stoi(srcNodeId);
1237 int j=std::stoi(dstNodeId);
1238
1239 //std::string ipV4Base = "10.1." + std::to_string(i+1) + ".0";
1240 //Ipv4Address addressBase;
1241 //addressBase.Set(ipV4Base.c_str());
1242
1243 //Create p2p connection between QKD nodes
1245 linkName = std::to_string(n.Get(i)->GetId()) + "_" + std::to_string(n.Get(j)->GetId());
1246 if(!DoesLinkExist(linkName, interfaces)){
1247
1248 //distance SrcToDst in meter
1249 p2p.SetDeviceAttribute ("DataRate", StringValue (p2pDataRate));
1250 p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
1251
1254 std::string ipV4Base = "10.1." + std::to_string(m_interfaces.size()+1) + ".0";
1255 ipv4.SetBase(ipV4Base.c_str(), "255.255.255.0");
1256 interfaces = ipv4.Assign (devicesToApp);
1257 m_interfaces.insert( std::make_pair( linkName , interfaces) );
1258
1259 std::cout
1260 << "Create link QKDNode-QKDNode: " << n.Get(i)->GetId() << "(" << interfaces.GetAddress(0) << ")"
1261 << "-"
1262 << n.Get(j)->GetId() << "(" << interfaces.GetAddress(1) << ")"
1263 << "\n";
1264 }
1265
1267 linkName = std::to_string(KMSNodes.Get(i)->GetId()) + "_" + std::to_string(KMSNodes.Get(j)->GetId());
1269
1270 //distance SrcToDst in meter
1271 p2p.SetDeviceAttribute ("DataRate", StringValue (p2pDataRate));
1272 p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
1273
1276 std::string ipV4Base = "10.1." + std::to_string(m_interfaces.size()+1) + ".0";
1277 ipv4.SetBase(ipV4Base.c_str(), "255.255.255.0");
1279 m_interfaces.insert( std::make_pair( linkName , interfacesBetweenKMSs) );
1280
1281 std::cout
1282 << "Create link KMSNode-KMSNode: " << KMSNodes.Get(i)->GetId() << "(" << interfacesBetweenKMSs.GetAddress(0) << ")"
1283 << "-"
1284 << KMSNodes.Get(j)->GetId() << "(" << interfacesBetweenKMSs.GetAddress(1) << ")"
1285 << "\n";
1286 }
1287
1288 ppKeySize = inputParams["qkd_links"][a]["keySize"];
1289 ppKeyRate = inputParams["qkd_links"][a]["keyRate"];
1290 ppPacketSize = inputParams["qkd_links"][a]["ppPacketSize"];
1291 ppRate = inputParams["qkd_links"][a]["ppRate"];
1292 startTime = inputParams["qkd_links"][a]["startTime"];
1293 stopTime = inputParams["qkd_links"][a]["stopTime"];
1294
1296 //linkD->nodes = std::to_string(n.Get(i)->GetId()) + "-" + std::to_string(n.Get(j)->GetId());
1297 linkD->nodes = srcNodeId + "-" + dstNodeId;
1298 linkD->title = "QKD link: " + linkD->nodes;
1299 linkD->type = 0;
1300 linkD->m_avgSizeOfGeneratedKeys = 0;
1301 linkD->m_avgSizeOfConsumedKeys = 0;
1302 linkD->m_keyRate = ppKeyRate;
1303 linkD->m_linkDistance = inputParams["qkd_links"][a]["srcDstDistance"];
1304 linkD->m_startTime = startTime;
1305 linkD->m_stopTime = stopTime;
1306 linkD->m_bufferCapacityBits = maxBufferCapacity;
1307 linkD->srcNodeId = std::stoi(srcNodeId);
1308 linkD->dstNodeId = std::stoi(dstNodeId);
1309 linkD->srcKMSNodeId = KMSNodes.Get(i)->GetId();
1310 linkD->dstKMSNodeId = KMSNodes.Get(j)->GetId();
1311
1312 if(systemId == systemID0) {
1313 std::cout << linkD->title << std::endl;
1314 std::cout << "SrcNode: " << n.Get(i)->GetId() << " Source IP address: " << interfaces.GetAddress(0) << std::endl;
1315 std::cout << "DstNode: " << n.Get(j)->GetId() << " Destination IP address: " << interfaces.GetAddress(1) << std::endl;
1316 std::cout << "Src controller: " << n.Get(numberOfQKDNodes+a)->GetId() << " Interface to Alice controller IP address: " << interfaces.GetAddress(0) << std::endl;
1317 std::cout << "Dst controller: " << n.Get(numberOfQKDNodes+a+1)->GetId() << " Interface to Bob controller IP address: " << interfaces.GetAddress(1) << std::endl;
1318 std::cout << "ppKeySize: " << ppKeySize << std::endl;
1319 std::cout << "ppKeyRate: " << ppKeyRate << std::endl;
1320 std::cout << "ppPacketSize: " << ppPacketSize << std::endl;
1321 std::cout << "ppRate: " << ppRate << std::endl;
1322 }
1323
1324 //Create APP to generate keys
1327 QAHelper.InstallPostProcessing(
1328 n.Get(i), //QKD module A
1329 n.Get(j), //QKD module B
1330 InetSocketAddress (interfaces.GetAddress(0), 102+a),
1331 InetSocketAddress (interfaces.GetAddress(1), 102+a),
1332 QControlNodes.Get(i), //Controller-A
1333 QControlNodes.Get(j), //Controller-B
1334 ppKeySize, //size of key to be added to QKD buffer
1335 DataRate (ppKeyRate), //average QKD key rate
1336 ppPacketSize, //average data packet size
1337 DataRate (ppRate) //average data traffic rate
1338 )
1339 );
1340
1341 postprocessingApplications.Start (Seconds (startTime));
1343
1345 m_nodePairs.insert( std::make_pair( ppA->GetId(), linkD) );
1346
1347 uint32_t temp = linkD->srcNodeId;
1348 linkD->srcNodeId = linkD->dstNodeId;
1349 linkD->dstNodeId = temp;
1350
1352 m_nodePairs.insert( std::make_pair( ppB->GetId(), linkD) );
1353
1354 if(systemId == systemID0) {
1355 std::cout << "startTime: " << startTime << std::endl;
1356 std::cout << "stopTime: " << stopTime << std::endl;
1357 std::cout << "\n";
1358 }
1359
1360 }
1361
1362 if(systemId == systemID0)
1363 std::cout << "\n";
1364
1365 //////////////////////////////////////
1366 // QKD APP ETSI 004
1367 //////////////////////////////////////
1368
1369 if(systemId == systemID0)
1370 std::cout << "\n*********\n*** ETSI 004 Configuration\n*********\n";
1371
1372 //Set default values for applications created below
1373 Config::SetDefault ("ns3::QKDApp004::UseCrypto", UintegerValue (useCrypto));
1374
1375 std::vector<uint32_t> keyBufferLengthEncryptionValues = {1,3,5,10,15,20};
1376 std::vector<uint32_t> keyBufferLengthAuthenticationValues = {6,10,15,20,50};
1377
1378 std::vector<uint32_t> AuthenticationTypes = {0,1,2};
1379 std::vector<uint32_t> EncryptionTypes = {0,1,2};
1380 std::vector<uint32_t> AESLifetimes = {10000, 20000, 100000,200000,300000,400000,500000};
1381
1382 std::vector<uint32_t> appPacketSizes = {100,300,500,800,1100};
1383 std::vector<uint32_t> appRates = {20000, 30000, 50000, 100000, 150000}; //, 200000, 250000, 500000};
1384
1385
1387 {
1388 appRate = inputParams["etsi_004"][a]["appRate"];
1389 appPacketSize = inputParams["etsi_004"][a]["appPacketSize"];
1390 authenticationType = inputParams["etsi_004"][a]["authenticationType"];
1391 encryptionType = inputParams["etsi_004"][a]["encryptionType"];
1392 keyBufferLengthEncryption = inputParams["etsi_004"][a]["keyBufferLengthEncryptionValue"];
1393 keyBufferLengthAuthentication = inputParams["etsi_004"][a]["keyBufferLengthAuthenticationValues"];
1394
1395 if (*find(appRates.begin(), appRates.end(), appRate) != appRate)
1396 NS_FATAL_ERROR ( "appRate (" << appRate << ") is not supported!");
1397
1398 if (*find(appPacketSizes.begin(), appPacketSizes.end(), appPacketSize) != appPacketSize)
1399 NS_FATAL_ERROR ( "appPacketSize (" << appPacketSize << ") is not supported!");
1400
1402 NS_FATAL_ERROR ( "authenticationType (" << authenticationType << ") is not supported!");
1403
1404 if (*find(EncryptionTypes.begin(), EncryptionTypes.end(), encryptionType) != encryptionType)
1405 NS_FATAL_ERROR ( "encryptionType (" << encryptionType << ") is not supported!");
1406
1408 NS_FATAL_ERROR ( "keyBufferLengthEncryption (" << keyBufferLengthEncryption << ") is not supported!");
1409
1411 NS_FATAL_ERROR ( "keyBufferLengthAuthentication (" << keyBufferLengthAuthentication << ") is not supported!");
1412
1413 if(encryptionType == 2){
1414 aesLifetime = inputParams["etsi_004"][a]["aesLifetime"];
1415 if (*find(AESLifetimes.begin(), AESLifetimes.end(), aesLifetime) != aesLifetime)
1416 NS_FATAL_ERROR ( "aesLifetime (" << aesLifetime << ") is not supported!");
1417 }
1418
1419 startTime = inputParams["etsi_004"][a]["startTime"];
1420 stopTime = inputParams["etsi_004"][a]["stopTime"];
1421
1422 //Set default values for applications created below
1423 Config::SetDefault ("ns3::QKDApp004::LengthOfKeyBufferForEncryption", UintegerValue (keyBufferLengthEncryption));
1424 Config::SetDefault ("ns3::QKDApp004::LengthOfKeyBufferForAuthentication", UintegerValue (keyBufferLengthAuthentication));
1425
1426 Config::SetDefault ("ns3::QKDApp004::AuthenticationType", UintegerValue (authenticationType)); //(0-unauthenticated, 1-VMAC, 2-SHA1)
1427 Config::SetDefault ("ns3::QKDApp004::EncryptionType", UintegerValue (encryptionType)); //(0-unencrypted, 1-OTP, 2-AES)
1428
1429 if(encryptionType == 2){
1430 Config::SetDefault ("ns3::QKDApp004::AESLifetime", UintegerValue (aesLifetime));
1431 }
1432
1433 srcNodeId = inputParams["etsi_004"][a]["srcNodeId"].dump();
1434 dstNodeId = inputParams["etsi_004"][a]["dstNodeId"].dump();
1435
1436 int i=std::stoi(srcNodeId);
1437 int j=std::stoi(dstNodeId);
1438
1440 linkName = std::to_string(n.Get(i)->GetId()) + "_" + std::to_string(n.Get(j)->GetId());
1442 //distance SrcToDst in meter
1443 std::string delayStringSrcDst = CalculateAverageDelayBasedOnDistance(inputParams["etsi_004"][a]["srcDstDistance"]);
1444 p2p.SetDeviceAttribute ("DataRate", StringValue (p2pDataRate));
1445 p2p.SetChannelAttribute ("Delay", StringValue (delayStringSrcDst));
1446
1447 std::cout << "Create link node-node: " << n.Get(i)->GetId() << "\t" << n.Get(j)->GetId() << "\n";
1450 std::string ipV4Base = "10.1." + std::to_string(m_interfaces.size()+1) + ".0";
1451 ipv4.SetBase(ipV4Base.c_str(), "255.255.255.0");
1453 m_interfaces.insert( std::make_pair( linkName , interfacesToApp) );
1454 }
1455
1457 linkName = std::to_string(n.Get(i)->GetId()) + "_" + std::to_string(KMSNodes.Get(i)->GetId());
1459 p2p.SetDeviceAttribute ("DataRate", StringValue (p2pDataRate));
1460 p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
1461
1462 std::cout << "Create link node-KMSA: " << n.Get(i)->GetId() << "\t" << KMSNodes.Get(i)->GetId() << "\n";
1465 std::string ipV4Base = "10.1." + std::to_string(m_interfaces.size()+1) + ".0";
1466 ipv4.SetBase(ipV4Base.c_str(), "255.255.255.0");
1468 m_interfaces.insert( std::make_pair( linkName , interfacesToKMSA) );
1469 }
1470
1472 linkName = std::to_string(n.Get(j)->GetId()) + "_" + std::to_string(KMSNodes.Get(j)->GetId());
1474 p2p.SetDeviceAttribute ("DataRate", StringValue (p2pDataRate));
1475 p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
1476
1477 std::cout << "Create link node-KMSB: " << n.Get(j)->GetId() << "\t" << KMSNodes.Get(j)->GetId() << "\n";
1480 std::string ipV4Base = "10.1." + std::to_string(m_interfaces.size()+1) + ".0";
1481 ipv4.SetBase(ipV4Base.c_str(), "255.255.255.0");
1483 m_interfaces.insert( std::make_pair( linkName , interfacesToKMSB) );
1484 }
1485
1486
1488 //linkD->nodes = std::to_string(n.Get(i)->GetId()) + "-" + std::to_string(n.Get(j)->GetId());
1489 linkD->nodes = srcNodeId + "-" + dstNodeId;
1490 linkD->title = "ETSI 004 Connection: " + linkD->nodes;
1491 linkD->type = 1;
1492 linkD->m_encryptionType = encryptionType;
1493 linkD->m_authenticationType = authenticationType;
1494 linkD->m_aesLifeTime = aesLifetime;
1495 linkD->m_packetSize = appPacketSize;
1496 linkD->m_trafficRate = appRate;
1497 linkD->m_sizeOfKeyBufferForEncryption = keyBufferLengthEncryption;
1498 linkD->m_sizeOfKeyBufferForAuthentication = keyBufferLengthAuthentication;
1499 linkD->m_startTime = startTime;
1500 linkD->m_stopTime = stopTime;
1501
1502 if(systemId == systemID0) {
1503 std::cout << linkD->title << "\n";
1504 std::cout << "Alice NodeId: " << n.Get(i)->GetId() << " Alice App IP: " << interfacesToApp.GetAddress(0) << std::endl;
1505 std::cout << "Bob NodeId: " << n.Get(j)->GetId() << " Bob App IP: " << interfacesToApp.GetAddress(1) << std::endl;
1506 std::cout << "EncryptionType: " << encryptionType << std::endl;
1507 std::cout << "AuthenticationType: " << authenticationType << std::endl;
1508 if(encryptionType == 2){
1509 std::cout << "AESLifetime: " << aesLifetime << std::endl;
1510 }
1511 std::cout << "AppRate: " << appRate << std::endl;
1512 std::cout << "AppPacketSize: " << appPacketSize << std::endl;
1513 std::cout << "LengthOfKeyBufferForEncryption: " << keyBufferLengthEncryption << std::endl;
1514 std::cout << "LengthOfKeyBufferForAuthentication: " << keyBufferLengthAuthentication << std::endl;
1515
1516 std::cout << "startTime: " << startTime << std::endl;
1517 std::cout << "stopTime: " << stopTime << std::endl;
1518 }
1519
1520 //Set default values for applications created below
1521 Config::SetDefault ("ns3::QKDApp004::AuthenticationType", UintegerValue (authenticationType)); //(0-unauthenticated, 1-VMAC, 2-SHA1)
1522 Config::SetDefault ("ns3::QKDApp004::EncryptionType", UintegerValue (encryptionType)); //(0-unencrypted, 1-OTP, 2-AES)
1523 Config::SetDefault ("ns3::QKDApp004::AESLifetime", UintegerValue (aesLifetime));
1524 Config::SetDefault ("ns3::QKDApp004::UseCrypto", UintegerValue (useCrypto));
1525 Config::SetDefault ("ns3::QKDApp004::LengthOfKeyBufferForEncryption", UintegerValue (keyBufferLengthEncryption));
1526 Config::SetDefault ("ns3::QKDApp004::LengthOfKeyBufferForAuthentication", UintegerValue (keyBufferLengthAuthentication));
1527 Config::SetDefault ("ns3::QKDApp004::SocketToKMSHoldTime", TimeValue (Seconds (appHoldTime)));
1528
1529 Config::SetDefault ("ns3::TcpSocket::TcpNoDelay", BooleanValue (true));
1530 Config::SetDefault ("ns3::TcpSocketState::EnablePacing", BooleanValue (false));
1531
1532 uint16_t communicationPort = 8081+a;
1535 QAHelper.InstallQKDApplication(
1536 n.Get(i), //Source Node
1537 n.Get(j), //Destination Node
1538 InetSocketAddress (interfacesToApp.GetAddress(0), communicationPort), //Source address
1539 InetSocketAddress (interfacesToApp.GetAddress(1), communicationPort), //Destination address
1540 QControlNodes.Get(i), //Controller 1
1541 QControlNodes.Get(j), //Controller 2
1542 "tcp", //Connection type
1543 appPacketSize, //Payload size
1544 DataRate (appRate), //Data rate
1545 "etsi004" //Application type
1546 )
1547 );
1548 cryptographicApplications.Start (Seconds (startTime));
1550
1551 if(systemId == systemID0)
1552 std::cout << "\n";
1553
1555 m_nodePairs.insert( std::make_pair( CA->GetId(), linkD) );
1557 m_nodePairs.insert( std::make_pair( CB->GetId(), linkD) );
1558 }
1559
1560
1561 //////////////////////////////////////
1562 // QKD APP ETSI 014
1563 //////////////////////////////////////
1564
1565 if(systemId == systemID0)
1566 std::cout << "\n*********\n*** ETSI 014 Configuration\n*********\n";
1567
1568 //Set default values for applications created below
1569 Config::SetDefault ("ns3::QKDApp014::UseCrypto", UintegerValue (useCrypto));
1570
1571 std::vector<uint32_t> numberOfKeyToFetchFromKMSOptions = {3,5,8,10,15,20};
1572 std::vector<double> appHoldPenaltyTimeValues = {1, 3, 5};
1573
1575 {
1576 appRate = inputParams["etsi_014"][a]["appRate"];
1577 appPacketSize = inputParams["etsi_014"][a]["appPacketSize"];
1578 authenticationType = inputParams["etsi_014"][a]["authenticationType"];
1579 encryptionType = inputParams["etsi_014"][a]["encryptionType"];
1580 numberOfKeyToFetchFromKMS = inputParams["etsi_014"][a]["numberOfKeyToFetchFromKMSOptions"];
1581 appHoldTime = 3; //inputParams["etsi_014"][a]["appHoldTimeValue"];
1582
1583 if (*find(appRates.begin(), appRates.end(), appRate) != appRate)
1584 NS_FATAL_ERROR ( "appRate (" << appRate << ") is not supported!");
1585
1586 if (*find(appPacketSizes.begin(), appPacketSizes.end(), appPacketSize) != appPacketSize)
1587 NS_FATAL_ERROR ( "appPacketSize (" << appPacketSize << ") is not supported!");
1588
1590 NS_FATAL_ERROR ( "authenticationType (" << authenticationType << ") is not supported!");
1591
1592 if (*find(EncryptionTypes.begin(), EncryptionTypes.end(), encryptionType) != encryptionType)
1593 NS_FATAL_ERROR ( "encryptionType (" << encryptionType << ") is not supported!");
1594
1595 if(encryptionType == 2){
1596 aesLifetime = inputParams["etsi_014"][a]["aesLifetime"];
1597 if (*find(AESLifetimes.begin(), AESLifetimes.end(), aesLifetime) != aesLifetime)
1598 NS_FATAL_ERROR ( "aesLifetime (" << aesLifetime << ") is not supported!");
1599 }
1600
1602 NS_FATAL_ERROR ( "numberOfKeyToFetchFromKMS (" << numberOfKeyToFetchFromKMS << ") is not supported!");
1603
1605 NS_FATAL_ERROR ( "appHoldTime (" << appHoldTime << ") is not supported!");
1606
1607 startTime = inputParams["etsi_014"][a]["startTime"];
1608 stopTime = inputParams["etsi_014"][a]["stopTime"];
1609
1610 //Set default values for applications created below
1611 Config::SetDefault ("ns3::QKDApp014::NumberOfKeyToFetchFromKMS", UintegerValue (numberOfKeyToFetchFromKMS));//Number of keys to obtain per request!
1612 Config::SetDefault ("ns3::QKDApp014::AuthenticationType", UintegerValue (authenticationType)); //(0-unauthenticated, 1-VMAC, 2-SHA1)
1613 Config::SetDefault ("ns3::QKDApp014::EncryptionType", UintegerValue (encryptionType)); //(0-unencrypted, 1-OTP, 2-AES)
1614 Config::SetDefault ("ns3::QKDApp014::WaitInsufficient", TimeValue (Seconds (appHoldTime)));
1615
1616 if(encryptionType == 2){
1617 Config::SetDefault ("ns3::QKDApp014::AESLifetime", UintegerValue (aesLifetime));
1618 }
1619
1620 srcNodeId = inputParams["etsi_014"][a]["srcNodeId"].dump();
1621 dstNodeId = inputParams["etsi_014"][a]["dstNodeId"].dump();
1622
1623 int i=std::stoi(srcNodeId);
1624 int j=std::stoi(dstNodeId);
1625
1627 linkName = std::to_string(n.Get(i)->GetId()) + "_" + std::to_string(n.Get(j)->GetId());
1629 //distance SrcToDst in meter
1630 std::string delayStringSrcDst = CalculateAverageDelayBasedOnDistance(inputParams["etsi_014"][a]["srcDstDistance"]);
1631 p2p.SetDeviceAttribute ("DataRate", StringValue (p2pDataRate));
1632 p2p.SetChannelAttribute ("Delay", StringValue (delayStringSrcDst));
1633
1634 std::cout << "Create link node-node: " << n.Get(i)->GetId() << "\t" << n.Get(j)->GetId() << "\n";
1637 std::string ipV4Base = "10.1." + std::to_string(m_interfaces.size()+1) + ".0";
1638 ipv4.SetBase(ipV4Base.c_str(), "255.255.255.0");
1640 m_interfaces.insert( std::make_pair( linkName , interfacesToApp) );
1641 }
1642
1644 linkName = std::to_string(n.Get(i)->GetId()) + "_" + std::to_string(KMSNodes.Get(i)->GetId());
1646 p2p.SetDeviceAttribute ("DataRate", StringValue (p2pDataRate));
1647 p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
1648
1649 std::cout << "Create link node-KMSA: " << n.Get(i)->GetId() << "\t" << KMSNodes.Get(i)->GetId() << "\n";
1652 std::string ipV4Base = "10.1." + std::to_string(m_interfaces.size()+1) + ".0";
1653 ipv4.SetBase(ipV4Base.c_str(), "255.255.255.0");
1655 m_interfaces.insert( std::make_pair( linkName , interfacesToKMSA) );
1656 }
1657
1659 linkName = std::to_string(n.Get(j)->GetId()) + "_" + std::to_string(KMSNodes.Get(j)->GetId());
1661 p2p.SetDeviceAttribute ("DataRate", StringValue (p2pDataRate));
1662 p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
1663
1664 std::cout << "Create link node-KMSB: " << n.Get(j)->GetId() << "\t" << KMSNodes.Get(j)->GetId() << "\n";
1667 std::string ipV4Base = "10.1." + std::to_string(m_interfaces.size()+1) + ".0";
1668 ipv4.SetBase(ipV4Base.c_str(), "255.255.255.0");
1670 m_interfaces.insert( std::make_pair( linkName , interfacesToKMSB) );
1671 }
1672
1674 //linkD->nodes = std::to_string(n.Get(i)->GetId()) + "-" + std::to_string(n.Get(j)->GetId());
1675 linkD->nodes = srcNodeId + "-" + dstNodeId;
1676 linkD->title = "ETSI 014 Connection: " + linkD->nodes;
1677 linkD->type = 2;
1678 linkD->m_encryptionType = encryptionType;
1679 linkD->m_authenticationType = authenticationType;
1680 linkD->m_aesLifeTime = aesLifetime;
1681 linkD->m_packetSize = appPacketSize;
1682 linkD->m_trafficRate = appRate;
1683 linkD->m_numberOfKeysToFetchFromKMS = numberOfKeyToFetchFromKMS;
1684 linkD->m_startTime = startTime;
1685 linkD->m_stopTime = stopTime;
1686
1687 if(systemId == systemID0){
1688 std::cout << linkD->title << "\n";
1689 std::cout << "Alice NodeId: " << n.Get(i)->GetId() << " Alice App IP: " << interfacesToApp.GetAddress(0) << std::endl;
1690 std::cout << "Bob NodeId: " << n.Get(j)->GetId() << " Bob App IP: " << interfacesToApp.GetAddress(1) << std::endl;
1691 std::cout << "EncryptionType: " << encryptionType << std::endl;
1692 std::cout << "AuthenticationType: " << authenticationType << std::endl;
1693 if(encryptionType == 2){
1694 std::cout << "AESLifetime: " << aesLifetime << std::endl;
1695 }
1696 std::cout << "AppRate: " << appRate << std::endl;
1697 std::cout << "AppPacketSize: " << appPacketSize << std::endl;
1698 std::cout << "NumberOfKeyToFetchFromKMS: " << numberOfKeyToFetchFromKMS << std::endl;
1699 std::cout << "AppHoldTime: " << appHoldTime << std::endl;
1700 std::cout << "startTime: " << startTime << std::endl;
1701 std::cout << "stopTime: " << stopTime << std::endl;
1702 }
1703
1704 //Set default values for applications created below
1705 Config::SetDefault ("ns3::QKDApp014::NumberOfKeyToFetchFromKMS", UintegerValue (numberOfKeyToFetchFromKMS));//Number of keys to obtain per request!
1706 Config::SetDefault ("ns3::QKDApp014::AuthenticationType", UintegerValue (authenticationType)); //(0-unauthenticated, 1-VMAC, 2-SHA1)
1707 Config::SetDefault ("ns3::QKDApp014::EncryptionType", UintegerValue (encryptionType)); //(0-unencrypted, 1-OTP, 2-AES)
1708 Config::SetDefault ("ns3::QKDApp014::AESLifetime", UintegerValue (aesLifetime));
1709 Config::SetDefault ("ns3::QKDApp014::UseCrypto", UintegerValue (useCrypto));
1710
1711 uint16_t communicationPort = 9081+a;
1714 QAHelper.InstallQKDApplication(
1715 n.Get(i), //Source Node
1716 n.Get(j), //Destination Node
1717 InetSocketAddress (interfacesToApp.GetAddress(0), communicationPort), //Source address
1718 InetSocketAddress (interfacesToApp.GetAddress(1), communicationPort), //Destination address
1719 QControlNodes.Get(i), //Controller 1
1720 QControlNodes.Get(j), //Controller 2
1721 "tcp", //Connection type
1722 appPacketSize, //Payload size
1723 DataRate (appRate), //Data rate
1724 "etsi014" //Application type
1725 )
1726 );
1727 cryptographicApplications.Start (Seconds (startTime));
1729
1731 m_nodePairs.insert( std::make_pair( CA->GetId(), linkD) );
1733 m_nodePairs.insert( std::make_pair( CB->GetId(), linkD) );
1734 }
1735
1737
1738 QLinkHelper.CreateTopologyGraph({m_qkdControl});
1739 QLinkHelper.PopulateRoutingTables();
1740
1741 if(systemId == systemID0){
1742 std::cout << "\n";
1743 }
1744
1745 //////////////////////////////////////
1746 //// STATISTICS
1747 //////////////////////////////////////
1748
1749
1751 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp004/Tx", MakeCallback(&SentPacket));
1752 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp004/Rx", MakeCallback(&ReceivedPacket));
1753 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp004/Mx", MakeCallback(&MissedSendPacketCall));
1754 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp004/TxSig", MakeCallback(&SentPacketSig));
1755 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp004/RxSig", MakeCallback(&ReceivedPacketSig));
1756 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp004/TxKMS", MakeCallback(&SentPacketToKMS));
1757 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp004/RxKMS", MakeCallback(&ReceivedPacketFromKMS));
1758 }
1759
1761 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp014/Tx", MakeCallback(&SentPacket));
1762 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp014/Rx", MakeCallback(&ReceivedPacket));
1763 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp014/Mx", MakeCallback(&MissedSendPacketCall));
1764 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp014/TxSig", MakeCallback(&SentPacketSig));
1765 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp014/RxSig", MakeCallback(&ReceivedPacketSig));
1766 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp014/TxKMS", MakeCallback(&SentPacketToKMS));
1767 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDApp014/RxKMS", MakeCallback(&ReceivedPacketFromKMS));
1768 }
1769
1770 //Connect Traces for KM key statistics
1771 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDKeyManagerSystemApplication/KeyServed", MakeCallback(&KeyServed));
1772 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDKeyManagerSystemApplication/KeyConsumedLink", MakeCallback(&KeyConsumedLink));
1773 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDKeyManagerSystemApplication/QKDKeyGenerated", MakeCallback(&KeyGenerated));
1774 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDKeyManagerSystemApplication/RelayConsumption", MakeCallback(&RelayKeyTrace));
1775 //Config::Connect("/NodeList/*/ApplicationList/*/$ns3::QKDKeyManagerSystemApplication/WasteRelay", MakeCallback(&WasteKeyTrace));
1776
1777 //@toDo: disable after debuging
1778 if(trace){
1779 //if we need we can create pcap files
1781 p2p.EnableAsciiAll (ascii.CreateFileStream ("qkd_etis004.tr"));
1782 p2p.EnablePcapAll ("qkd_etis004");
1783 AnimationInterface anim ("qkd_etsi_combined.xml"); // where "animation.xml" is any arbitrary filename
1784 }
1785
1786 Simulator::Stop (Seconds (simulationTime));
1787 Simulator::Run ();
1788
1789 //Finally print the graphs
1790 //QLinkHelper.PrintGraphs();
1791
1792 if(systemId == systemID0){
1793 std::cout << "simTime:\t" << simulationTime << "\n";
1794 std::cout << "useCrypto:\t" << useCrypto << "\n";
1795 std::cout << "trace:\t" << trace << "\n";
1796 }
1797
1798 //Finally print the graphs
1799 //QLinkHelper.PrintGraphs();
1800
1801 if(systemId == systemID0){
1803 if(outputFileType == "json") logFile << ']';
1804 }
1805 }
1806
1807 std::string tempStatsFile = "temp_stats_" + std::to_string(systemId);
1809
1810 if(systemId == systemID0){
1812 }
1813
1816
1818
1819 execTime = 1000000000 * (tock.tv_sec - tick.tv_sec) + tock.tv_nsec - tick.tv_nsec;
1820 printf("elapsed process CPU time = %llu nanoseconds\n", (long long unsigned int) execTime);
1821
1822 return 0;
1823}
Interface to network animator.
holds a vector of ns3::Application pointers.
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container.
Manage ASCII trace files for device models.
AttributeValue implementation for Boolean.
Definition boolean.h:26
Parse command-line arguments.
Class for representing data rates.
Definition data-rate.h:78
static void Bind(std::string name, const AttributeValue &value)
Iterate over the set of GlobalValues until a matching name is found and then set its value with Globa...
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
static void PopulateRoutingTables()
Build a routing database and initialize the routing tables of the nodes in the simulation.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Helper class used to assign positions and mobility models to nodes.
static uint32_t GetSystemId()
Get the id number of this rank.
static uint32_t GetSize()
Get the number of ranks used by ns-3.
static void Disable()
Clean up the ns-3 parallel communications interface.
static void Enable(int *pargc, char ***pargv)
Setup the parallel communication interface.
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
void Add(const NodeContainer &nc)
Append the contents of another NodeContainer to the end of this container.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t GetId() const
Definition node.cc:106
Build a set of PointToPointNetDevice objects.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
A helper to make it easier to instantiate an ns3::QKDAppApplication on a set of nodes.
QKDNetSim implements Key Management System(KMS) as an application that listens on TCP port 80.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Hold variables of type string.
Definition string.h:45
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
AttributeValue implementation for Time.
Definition nstime.h:1431
Hold an unsigned integer type.
Definition uinteger.h:34
Time stopTime
void Ratio()
void SentPacket(std::string context, const std::string &appId, Ptr< const Packet > p)
void MissedSendPacketCall(std::string context, const std::string &appId, Ptr< const Packet > p)
void SentPacketToKMS(std::string context, const std::string &appId, Ptr< const Packet > p)
void KeyGenerated(std::string context, const std::string &appId, const std::string &keyId, const uint32_t &amountInBits)
std::ofstream logFile
void SentPacketSig(std::string context, const std::string &appId, Ptr< const Packet > p)
nlohmann::json outputLogFile
void RelayKeyTrace(std::string context, const uint32_t &nodeId, const uint32_t &srcNodeId, const uint32_t &dstNodeId, const uint32_t &amountInBits)
std::string CalculateAverageDelayBasedOnDistance(uint32_t distanceInMeters)
bool DoesLinkExist(std::string linkName, Ipv4InterfaceContainer &interfacesToApp)
void CreateOutputForCPU(std::string outputStatsName)
void ReceivedPacketFromKMS(std::string context, const std::string &appId, Ptr< const Packet > p)
void KeyServed(std::string context, const std::string &appId, const std::string &keyId, const uint32_t &amountInBits)
Keys served from KMS to end-user application.
void ReceivedPacketSig(std::string context, const std::string &appId, Ptr< const Packet > p)
void ReceivedPacket(std::string context, const std::string &appId, Ptr< const Packet > p)
void KeyConsumedLink(std::string context, const uint32_t &srcNodeId, const uint32_t &dstNodeId, const uint32_t &amountInBits)
Keys fetched from qkdBuffers for transformation before delivery to end-user application.
std::string outputFileType("json")
void write_csv(std::string filename, std::vector< std::pair< std::string, std::vector< uint32_t > > > dataset)
std::map< std::string, Ipv4InterfaceContainer > m_interfaces
std::map< std::string, LinkDetails * > m_nodePairs
std::vector< std::pair< std::string, std::vector< uint32_t > > > read_csv(std::string filename)
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:967
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
AnimationInterface * anim
NodeContainer nodes
interfaces
Definition first.py:39
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
mobility
Definition third.py:92