A Discrete-Event Network Simulator
API
qkd-buffer.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 DOTFEESA 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  * Author: Miralem Mehic <miralem.mehic@ieee.org>
19  */
20 
21 
22 #include <algorithm>
23 #include <numeric>
24 #include "ns3/packet.h"
25 #include "ns3/simulator.h"
26 #include "ns3/log.h"
27 #include "ns3/boolean.h"
28 #include "ns3/double.h"
29 #include "ns3/uinteger.h"
30 
31 #include "qkd-buffer.h"
32 
33 namespace ns3 {
34 
35 NS_LOG_COMPONENT_DEFINE ("QKDBuffer");
36 
37 NS_OBJECT_ENSURE_REGISTERED (QKDBuffer);
38 
39 TypeId
41 {
42  static TypeId tid = TypeId ("ns3::QKDBuffer")
43  .SetParent<Object> ()
44  .AddConstructor<QKDBuffer> ()
45  .AddAttribute ("Minimal",
46  "The minimal amount of key material in QKD storage (bits)",
47  UintegerValue (1000000), //1Mb
49  MakeUintegerChecker<uint32_t> ())
50  .AddAttribute ("Maximal",
51  "The maximal amount of key material in QKD storage (bits)",
52  UintegerValue (1000000000), //1Gb
54  MakeUintegerChecker<uint32_t> ())
55  .AddAttribute ("Threshold",
56  "The threshold amount of key material in QKD (bits)",
57  UintegerValue (2000000), //2Mb
59  MakeUintegerChecker<uint32_t> ())
60  .AddAttribute ("Current",
61  "The current amount of key material in QKD storage (bits)",
62  UintegerValue (5000000), //5Mb
64  MakeUintegerChecker<uint32_t> ())
65 
66  .AddAttribute ("CalculationTimePeriod",
67  "The period of time (in seconds) to calculate average amount of the key in the buffer",
68  UintegerValue (5), // in seconds
70  MakeUintegerChecker<uint32_t> ())
71  .AddAttribute ("MaxNumberOfRecordedKeyCharingTimePeriods",
72  "The maximal number of values which are stored for calculation of average key charging rate",
73  UintegerValue (5),
75  MakeUintegerChecker<uint32_t> ())
76  .AddAttribute ("MaxNumberOfRecordedKeyConsumptionTimePeriods",
77  // It should be larger then numberOfKeyToFetchFromKMS within ETSI014 app to fetch long-term statistics.
78  //If the value is too small then the it will reflect only burst ETSI 014 calls for keys
79  "The maximal number of values which are stored for calculation of average key consumption rate.",
80  UintegerValue (49),
82  MakeUintegerChecker<uint32_t> ())
83  .AddAttribute ("DefaultKeySize",
84  "The default key size",
85  UintegerValue (512),
87  MakeUintegerChecker<uint32_t> ())
88  .AddAttribute ("MinimalKeyCount",
89  "The minimal number of keys to be stored in the buffer (count of keys)",
90  UintegerValue (50),
92  MakeUintegerChecker<uint32_t> ())
93  .AddAttribute ("MaximalKeyCount",
94  "The maximal number of keys to be stored in the buffer (count of keys)",
95  UintegerValue (50000),
97  MakeUintegerChecker<uint32_t> ())
98 
99  .AddTraceSource ("ThresholdChange",
100  "The change trace for threshold amount of key material in QKD storage",
102  "ns3::QKDBuffer::ThresholdChange")
103 
104  .AddTraceSource ("ThresholdIncrease",
105  "The increase trace for threshold amount of key material in QKD storage",
107  "ns3::QKDBuffer::ThresholdIncrease")
108 
109  .AddTraceSource ("ThresholdDecrease",
110  "The decrease trace for threshold amount of key material in QKD storage",
112  "ns3::QKDBuffer::ThresholdDecrease")
113 
114  .AddTraceSource ("CurrentChange",
115  "The change trace for current amount of key material in QKD storage",
117  "ns3::QKDBuffer::CurrentChange")
118 
119  .AddTraceSource ("CurrentIncrease",
120  "The increase trace for current amount of key material in QKD storage",
122  "ns3::QKDBuffer::CurrentIncrease")
123 
124  .AddTraceSource ("CurrentDecrease",
125  "The decrease trace for current amount of key material in QKD storage",
127  "ns3::QKDBuffer::CurrentDecrease")
128 
129  .AddTraceSource ("StatusChange",
130  "The change trace for current status of QKD storage",
132  "ns3::QKDBuffer::StatusChange")
133  .AddTraceSource ("CMetricChange",
134  "The change trace for current status of QKD storage",
136  "ns3::QKDBuffer::CMetricChange")
137  .AddTraceSource ("AverageKeyGenerationRate",
138  "The average key rate of the QKD storage",
140  "ns3::QKDBuffer::AverageKeyGenerationRate")
141  .AddTraceSource ("AverageKeyConsumptionRate",
142  "The average key rate of the QKD storage",
144  "ns3::QKDBuffer::AverageKeyConsumptionRate")
145 
146  .AddTraceSource ("NewKeyAdded",
147  "The trace to monitor adding new key material to the buffer",
149  "ns3::QKDBuffer::NewKeyAdded")
150  .AddTraceSource ("TransformedKeyAdded",
151  "The trace to monitor adding transformed key material to the buffer",
153  "ns3::QKDBuffer::TransformedKeyAdded")
154  .AddTraceSource ("KeyServed",
155  "The trace to monitor key usage",
157  "ns3::QKDBuffer::KeyServed")
158  .AddTraceSource ("KeyReserved",
159  "The trace to monitor key reservation",
161  "ns3::QKDBuffer::KeyReserved")
162  ;
163  return tid;
164 }
165 
167 {
168  NS_LOG_FUNCTION(this);
169 }
170 
171 void
173  Ptr<Node> srcNode,
174  Ptr<Node> dstNode,
175  uint32_t Mmin,
176  uint32_t Mthr,
177  uint32_t Mmax,
178  uint32_t Mcurrent,
179  bool useRealStorages
180 )
181 {
182  NS_LOG_FUNCTION(this << srcNode << dstNode);
183  m_srcNode = srcNode;
184  m_dstNode = dstNode;
185  m_nextKeyID = 0;
186  m_minKeyBit = Mmin;
187  m_thresholdKeyBit = Mmin;
188  m_maxKeyBit = Mmax;
189  m_currentKeyBit = Mcurrent;
191  m_currentReadyKeyBit = Mcurrent;
193  m_useRealStorages = useRealStorages;
194 
195  m_bufferID = ++nBuffers;
197  m_noEntry = 0;
198  m_period = 5;
199  m_noAddNewValue = 0;
200 
203  m_previousStatus = 0;
204 
207 
210 
213 
214 }
215 
216 uint32_t QKDBuffer::nBuffers = 0;
217 
218 
220 {
221  NS_LOG_FUNCTION (this);
222  m_keys.clear();
223  m_destinations.clear();
224  m_targetSizeSet.clear();
225 }
226 
227 void
229 {
230  NS_LOG_FUNCTION (this);
232 }
233 
234 uint32_t
236  return m_defaultKeySize;
237 }
238 
240 {
241  return a.value > b.value;
242 }
243 
244 void
246 {
247  NS_LOG_FUNCTION (this);
248  //This function is used to define whether curve is going up or down (QKDGraphs)
249  //This info is needed to define the state of the buffer (charging or warning)
250 
252 
253  struct QKDBuffer::data q;
255  q.position = m_noEntry;
256 
257  while( m_previousValues.size () > m_period ) m_previousValues.pop_back();
258  m_previousValues.insert( m_previousValues.begin() ,q);
259 
260  //sort elements in descending order, first element has the maximum value
261  std::sort(m_previousValues.begin(), m_previousValues.end(), compareByData);
262 
263  /*
264  * If maximal value is on the current location then it means that the current value is the highest in the period => function is rising
265  * Otherwise, function is going down
266  */
267  m_isRisingCurve = (m_previousValues[0].position == m_noEntry);
268  CheckState();
269 
270  m_noEntry++;
271 }
272 
273 
274 uint32_t
276  return m_keys.size();
277 }
278 uint32_t
280  return m_minimalKeyCount;
281 }
282 uint32_t
284  return m_maximalKeyCount;
285 }
286 
287 uint64_t
289  return m_currentKeyBit;
290 }
291 
292 uint64_t
294  return m_currentReadyKeyBit;
295 }
296 
297 uint64_t
299  return m_currentTargetKeyBit;
300 }
301 
302 uint64_t
304  return m_minKeyBit;
305 }
306 uint64_t
308  return m_maxKeyBit;
309 }
310 
317 bool
318 QKDBuffer::AddNewKey(Ptr<QKDKey> key, uint32_t keyTransformed)
319 {
320  NS_LOG_FUNCTION ( this << key->GetId() << key->GetSizeInBits() << keyTransformed );
321  NS_LOG_FUNCTION ( this << key->ToString());
322 
323 
324  if((m_currentKeyBit + key->GetSizeInBits() >= m_maxKeyBit) && !keyTransformed) //It is expected to get transformed keys back to QKD buffer so we use m_currentKeyBit
325  {
326  NS_LOG_FUNCTION(this << "Buffer is full! Not able to add new "
327  << key->GetSizeInBits() << "bits, since the current is "
328  << m_currentKeyBit << " and max is " << m_maxKeyBit
329  );
332 
333  }else{
334 
335  m_keys.insert( std::make_pair( key->GetId() , key) );
336  m_currentKeyBit = m_currentKeyBit + key->GetSizeInBits();
338  m_currentReadyKeyBit += key->GetSizeInBits();
339  if(std::find(m_targetSizeSet.begin(), m_targetSizeSet.end(), key->GetSizeInBits()) != m_targetSizeSet.end()){
340  m_currentTargetKeyBit += key->GetSizeInBits();
341  }
343  m_currentKeyBitIncreaseTrace (key->GetSizeInBits());
344 
345  if(keyTransformed){
347  }else{
348  m_newKeyAddedTrace(key);
349  }
350  }
351 
352  /*
353  * CALCULATE AVERAGE TIME PERIOD OF KEY CHARGING VALUE
354  */
355 
356  if(keyTransformed == 0)
357  {
359  KeyCalculation();
360  }
361 
362  return true;
363 }
364 
365 double
367 
368  NS_LOG_FUNCTION(this);
369 
370  //delete records older then 5 seconds
371  int64_t currentTime = Simulator::Now ().GetSeconds();
372  for(uint32_t i=0; i<m_consumptionTimePeriods.size(); i++){
373  if(currentTime-m_consumptionTimePeriods[i] > 5){
375  }
376  }
377 
378  //here we define temp variables
379  double m_averageKeyConsumptionTimePeriodPeek = 0;
380  double m_averageKeyConsumptionRatePeek = 0;
381  std::vector < int64_t > m_consumptionTimePeriodsPeek = m_consumptionTimePeriods;
382 
383  //calculate average duration between key consumption requests (milliseconds) AND THE CURRENT TIME
384  //Key consumption rate decreases with time if no new requests are detected.
385  //That is, when ETSI004 transformKeys operations are completed, no additional requests for keys are generated
386  //If the ETSI004 connection is terminated, we need to calculate REAL consumption rate that depends on
387  //the time when the sample (GetAverageKeyConsumptionRate) is taken (called)
388  if(m_consumptionTimePeriods.size())
389  {
390  while( m_consumptionTimePeriodsPeek.size () > m_maxNumberOfRecordedKeyConsumptionTimePeriods ) m_consumptionTimePeriodsPeek.pop_back();
391 
392  for(uint32_t i=0; i<m_consumptionTimePeriods.size(); i++)
393  NS_LOG_FUNCTION(this << "m_consumptionTimePeriods["<<i<<"]:" << m_consumptionTimePeriods[i]);
394 
395  m_consumptionTimePeriodsPeek.insert( m_consumptionTimePeriodsPeek.begin(), currentTime );
396 
397  double sum = 0;
398  for(uint32_t i=0; i<m_consumptionTimePeriods.size(); i++)
399  sum += currentTime-m_consumptionTimePeriods[i];
400 
401  m_averageKeyConsumptionTimePeriodPeek = sum / m_consumptionTimePeriodsPeek.size();
402 
403  }else{
404  m_averageKeyConsumptionTimePeriodPeek = 0;
405  }
406  NS_LOG_DEBUG(this << " m_averageKeyConsumptionTimePeriodPeek (micro seconds): " << m_averageKeyConsumptionTimePeriodPeek );
407  NS_LOG_DEBUG(this << " m_consumptionTimePeriodsPeek.size(): " << m_consumptionTimePeriodsPeek.size() );
408 
409  //average keyConsumptionSize is the same since no keys have been requested.
410  //we only ask for INFO about the key consumption rate, but we do not ask for keys here.
411 
412  //calculate average key generation rate (bits per seconds)
413  if(m_averageKeyConsumptionSize && m_averageKeyConsumptionTimePeriodPeek){
414 
415  m_averageKeyConsumptionRatePeek = ((double) m_averageKeyConsumptionSize / (double) (m_averageKeyConsumptionTimePeriodPeek));
416 
417  NS_LOG_DEBUG (this << " m_averageKeyConsumptionSize (bits): " << m_averageKeyConsumptionSize );
418 
419  NS_LOG_DEBUG (this << " m_averageKeyConsumptionTimePeriod (seconds): " << m_averageKeyConsumptionTimePeriod);
420  NS_LOG_DEBUG (this << " m_averageKeyConsumptionTimePeriodPeek (seconds): " << m_averageKeyConsumptionTimePeriodPeek );
421 
422  NS_LOG_DEBUG (this << " m_averageKeyConsumptionRate (bps): " << m_averageKeyConsumptionRate);
423  NS_LOG_DEBUG (this << " m_averageKeyConsumptionRatePeek (bps): " << m_averageKeyConsumptionRatePeek);
424 
425  m_averageKeyConsumptionRate = m_averageKeyConsumptionRatePeek;
426  }
427  return round(m_averageKeyConsumptionRatePeek);
428 }
429 
430 double
432  NS_LOG_FUNCTION(this);
433  return round(m_averageKeyGenerationRate);
434 }
435 
436 uint32_t
439 }
440 
441 uint32_t
442 QKDBuffer::GetKeyCount (uint32_t keySize)
443 {
444  NS_LOG_FUNCTION( this << keySize );
445  uint32_t keyCount {0};
446  for(std::map<std::string, Ptr<QKDKey> >::const_iterator it = m_keys.begin(); it != m_keys.end(); ++it){
447  if(it->second->GetSizeInBits() == keySize && it->second->GetState() == QKDKey::READY)
448  keyCount++;
449  }
450 
451  return keyCount;
452 }
453 
454 bool
455 QKDBuffer::ProbeKeyStatus (std::string keyId, QKDKey::QKDKeyState_e keyState){
456  NS_LOG_FUNCTION( this << keyId );
457  std::map<std::string, Ptr<QKDKey> >::iterator it = m_keys.find (keyId);
458  if(it != m_keys.end()){
459  if(it->second->GetState() == keyState)
460  return true;
461  else
462  return false;
463  }else{
464  return false;
465  }
466 }
467 
475 QKDBuffer::FetchKeyBySize (const uint32_t& keySize)
476 {
477  NS_LOG_FUNCTION(this << keySize << m_currentKeyBit << m_currentKeyBitReally);
478 
479  Ptr<QKDKey> key = 0;
480  for(std::map<std::string, Ptr<QKDKey> >::iterator it = m_keys.begin(); it != m_keys.end(); ++it){
481  if(it->second->GetState() == QKDKey::READY && it->second->GetSizeInBits() == keySize){
482  key = it->second;
483  m_keys.erase (it); //Delete the key from the QKD buffer!
484 
486 
487  KeyCalculation();
488  break;
489  }
490  }
491  if(!key) //Check
492  NS_FATAL_ERROR( this << "Key of desired length is not available in the QKD buffer!");
493 
494  return key;
495 }
496 
498 QKDBuffer::FetchKeyByID (std::string keyID)
499 {
500  return FetchKeyByID (keyID, 0);
501 }
502 
503 //Note: Called even from the transform functions!
504 //Note: Function is allowed to return null value, processing left to the KMS.
506 QKDBuffer::FetchKeyByID (std::string keyID, uint32_t fillProcessActive)
507 {
508  NS_LOG_FUNCTION(this << keyID << m_currentKeyBit << m_currentKeyBitReally << fillProcessActive);
509 
510  Ptr<QKDKey> key = 0;
511  NS_LOG_FUNCTION(this << "Searching for the key " << keyID << " ...");
512  std::map<std::string, Ptr<QKDKey> >::iterator a = m_keys.find (keyID);
513  if(a != m_keys.end ()){
514  key = a->second;
515  NS_LOG_FUNCTION(this << "Key is found " << key->GetId() << key->GetSizeInBits());
516  m_keys.erase(a);
517  NS_LOG_FUNCTION(this << "Key has been erased from the QKDBuffer " << key->GetId());
518 
519  NS_LOG_FUNCTION(this << "Returning key " << key->GetId() << " as the funtion output ...");
520 
521  if(fillProcessActive == 0) UpdateKeyConsumptionStatistics(key);
522  else m_currentKeyBitReally -= key->GetSizeInBits();
523 
524  }else{
525  NS_LOG_FUNCTION(this << "Key is not found ... Returning NULL value ...");
526  }
527 
528  return key;
529 }
530 
531 void
533 {
534  NS_LOG_FUNCTION(this);
535 
536  //Fire traces
537  m_currentKeyBit -= key->GetSizeInBits();
538 
539  if(key->GetState() != QKDKey::RESERVED)
540  m_currentReadyKeyBit -= key->GetSizeInBits();
541 
542  if(std::find(m_targetSizeSet.begin(), m_targetSizeSet.end(), key->GetSizeInBits()) != m_targetSizeSet.end()
543  && key->GetState() != QKDKey::RESERVED)
544  m_currentTargetKeyBit -= key->GetSizeInBits();
545 
547  m_currentKeyBitDecreaseTrace(key->GetSizeInBits());
548  m_bitsUsedInTimePeriod -= key->GetSize();
549  m_keyServedTrace(key);
550 
551  //calculate average duration between key consumption requests (milliseconds)
552  int64_t currentTime = Simulator::Now ().GetSeconds();
553  if(m_consumptionTimePeriods.size())
554  {
555  double sum = 0;
556  for(uint32_t i=0; i<m_consumptionTimePeriods.size(); i++)
557  sum += currentTime-m_consumptionTimePeriods[i];
558 
560  }else{
562  }
563  NS_LOG_DEBUG(this << " m_averageKeyConsumptionTimePeriod (micro seconds): " << m_averageKeyConsumptionTimePeriod );
564  NS_LOG_DEBUG(this << " m_consumptionTimePeriods.size(): " << m_consumptionTimePeriods.size() );
566  m_consumptionTimePeriods.insert( m_consumptionTimePeriods.begin(), currentTime );
567 
568  int64_t tempPeriod = (m_consumptionTimePeriods.size() > 0) ? (currentTime - m_lastKeyConsumptionTimeStamp) : 1;
570  /*
571  for(uint32_t i=0; i<m_consumptionTimePeriods.size(); i++){
572  NS_LOG_FUNCTION(this << "m_consumptionTimePeriods["<<i<<"]:" << m_consumptionTimePeriods[i]);
573  }
574  */
575  //calculate average consumption key size (bits)
576  if(m_chargingTimePeriods.size())
577  {
578  m_averageKeyConsumptionSize = accumulate(
579  m_lastConsumedKeySizes.begin(),
580  m_lastConsumedKeySizes.end(), 0.0
581  ) / m_lastConsumedKeySizes.size();
582  }else{
584  }
585  NS_LOG_DEBUG(this << " m_averageKeyConsumptionSize: " << m_averageKeyConsumptionSize );
586  NS_LOG_DEBUG(this << " m_lastConsumedKeySizes.size(): " << m_lastConsumedKeySizes.size() );
588  m_lastConsumedKeySizes.insert( m_lastConsumedKeySizes.begin(), key->GetSizeInBits() );
589 
590  //calculate average key generation rate (bits per seconds)
594 
595  NS_LOG_DEBUG (this << " m_averageKeyConsumptionRate (bps): " << m_averageKeyConsumptionRate);
596  NS_LOG_DEBUG (this << " m_averageKeyConsumptionSize (bits): " << m_averageKeyConsumptionSize );
597  NS_LOG_DEBUG (this << " m_averageKeyConsumptionTimePeriod (seconds): " << m_averageKeyConsumptionTimePeriod );
598  }
599 
600  m_lastKeyConsumptionTimeStamp = currentTime;
601 }
602 
603 void
605 
606  NS_LOG_FUNCTION(this << key->GetId());
607 
608  //calculate average duration of key generation process (milliseconds)
609  if(m_chargingTimePeriods.size())
610  {
611  m_averageKeyChargingTimePeriod = accumulate(
612  m_chargingTimePeriods.begin(),
613  m_chargingTimePeriods.end(), 0.0
614  ) / m_chargingTimePeriods.size();
615  }else{
617  }
618  NS_LOG_DEBUG(this << " m_averageKeyChargingTimePeriod: " << m_averageKeyChargingTimePeriod );
619  NS_LOG_DEBUG(this << " m_chargingTimePeriods.size(): " << m_chargingTimePeriods.size() );
621  int64_t currentTime = Simulator::Now ().GetSeconds();
622  int64_t tempPeriod = (m_chargingTimePeriods.size() > 0) ? (currentTime - m_lastKeyChargingTimeStamp) : 1;
623  m_chargingTimePeriods.insert( m_chargingTimePeriods.begin(), tempPeriod );
624  m_lastKeyChargingTimeDuration = tempPeriod;
625  m_lastKeyChargingTimeStamp = currentTime;
626 
627  //calculate average generated key size (bits)
628  if(m_chargingTimePeriods.size())
629  {
630  m_averageKeyChargingSize = accumulate(
631  m_lastChargedKeySizes.begin(),
632  m_lastChargedKeySizes.end(), 0.0
633  ) / m_lastChargedKeySizes.size();
634  }else{
636  }
637  NS_LOG_DEBUG(this << " m_averageKeyChargingSize: " << m_averageKeyChargingSize );
638  NS_LOG_DEBUG(this << " m_lastChargedKeySizes.size(): " << m_lastChargedKeySizes.size() );
640  m_lastChargedKeySizes.insert( m_lastChargedKeySizes.begin(), key->GetSizeInBits() );
641 
642  //calculate average key generation rate (bits per seconds)
646  }
648 
649  NS_LOG_DEBUG (this << " m_averageKeyGenerationRate (bps): " << m_averageKeyGenerationRate);
650  NS_LOG_DEBUG (this << " m_averageKeyChargingSize (bits): " << m_averageKeyChargingSize );
651  NS_LOG_DEBUG (this << " m_averageKeyChargingTimePeriod (Seconds): " << m_averageKeyChargingTimePeriod );
652 
655 
656  NS_LOG_FUNCTION (this << "New key material added");
657 }
658 
659 
660 
661 /*
662  Transform
663  */
664 void
665 QKDBuffer::ReserveKey (std::string keyId)
666 {
667  NS_LOG_FUNCTION(this << "Reserving key " << keyId << " ...");
668  std::map<std::string, Ptr<QKDKey> >::iterator it = m_keys.find(keyId);
669 
670  if(it != m_keys.end()){
671 
672  NS_LOG_FUNCTION(this << "Reserving key " << keyId << " of size " << it->second->GetSizeInBits());
673 
674  if(it->second->GetState() == QKDKey::READY){
675  it->second->MarkReserved(); //@toDo include reservation_type!
676 
677  NS_LOG_FUNCTION(this << m_currentReadyKeyBit << it->second->GetSizeInBits());
678  m_currentReadyKeyBit -= it->second->GetSizeInBits();
679 
680  if(std::find(m_targetSizeSet.begin(), m_targetSizeSet.end(), it->second->GetSizeInBits()) != m_targetSizeSet.end())
681  m_currentTargetKeyBit -= it->second->GetSizeInBits();
682 
684 
685  m_keyReservedTrace(it->second);
686 
687  }else
688  NS_FATAL_ERROR(this << "Key reservation failed ... Error message: Key "
689  << keyId << " has been already reserved or served for another purpose.");
690  }else{
691  NS_FATAL_ERROR(this << "Key reservation failed ... Error message: Key "
692  << keyId << "cannot be found in the QKDBuffer.");
693  }
694 }
695 
696 void
697 QKDBuffer::ReleaseReservation (std::string keyId)
698 {
699  NS_LOG_FUNCTION(this << "Releasing reservation of the key" << keyId << " ...");
700  std::map<std::string, Ptr<QKDKey> >::iterator it = m_keys.find(keyId);
701  if(it != m_keys.end()){
702  if(it->second->GetState() == QKDKey::RESERVED){
703  it->second->MarkReady();
704  m_currentReadyKeyBit += it->second->GetSizeInBits();
705  NS_LOG_FUNCTION(this << "Reservation sucessfully released.");
706  }else
707  NS_FATAL_ERROR(this << "Release reservation failed ... Error message: Key "
708  << keyId << "has not been in the RESRVED state.");
709  }else{
710  NS_FATAL_ERROR(this << "Release reservation failed ... Error message: Key "
711  << keyId << "cannot be found in the QKDBuffer.");
712  }
713 }
714 
717 {
718  //@toDo optimal key should be a random key from a set of best matched keys <= 100 large, to improve on avoidance of collisions
719  NS_LOG_FUNCTION( this << "Searching optimal key to tranform " << targetSize << m_keys.size());
720 
721  Ptr<QKDKey> optimalKey {}, optimalKeySecond {};
722  std::map<std::string, Ptr<QKDKey> >::iterator it = m_keys.begin();
723  while(it != m_keys.end()){
724 
725  NS_LOG_FUNCTION (this << it->second->GetId() << it->second->GetSize() << it->second->GetSizeInBits() << it->second->GetState());
726 
727  if(
728  it->second->GetSizeInBits() >= targetSize &&
729  std::find(m_targetSizeSet.begin(), m_targetSizeSet.end(), it->second->GetSizeInBits()) == m_targetSizeSet.end() &&
730  it->second->GetState() == QKDKey::READY &&
731  optimalKey == NULL
732  ){
733  optimalKey = it->second; //The first match for optimal key
734  NS_LOG_FUNCTION(this << "Starting optimal key " << optimalKey->GetId());
735  }
736  else if(
737  it->second->GetSizeInBits() >= targetSize &&
738  std::find(m_targetSizeSet.begin(), m_targetSizeSet.end(), it->second->GetSizeInBits()) == m_targetSizeSet.end() &&
739  it->second->GetState() == QKDKey::READY &&
740  it->second->GetSizeInBits() < optimalKey->GetSizeInBits()
741  )
742  optimalKey = it->second;
743  if(
744  optimalKeySecond == NULL &&
745  std::find(m_targetSizeSet.begin(), m_targetSizeSet.end(), it->second->GetSizeInBits()) == m_targetSizeSet.end() &&
746  it->second->GetState() == QKDKey::READY
747  )
748  optimalKeySecond = it->second;
749  else if(
750  optimalKeySecond != NULL &&
751  optimalKeySecond->GetSizeInBits() < it->second->GetSizeInBits() &&
752  std::find(m_targetSizeSet.begin(), m_targetSizeSet.end(), it->second->GetSizeInBits()) == m_targetSizeSet.end() &&
753  it->second->GetState() == QKDKey::READY
754  )
755  optimalKeySecond = it->second; //Results in largest key in QKD Buffer
756 
757  ++it;
758  }
759 
760  if(!optimalKey){
761  NS_ASSERT(optimalKeySecond != NULL);
762  return optimalKeySecond;
763  }
764 
765  return optimalKey;
766 }
767 
768 void
770 {
771  NS_LOG_FUNCTION( this << size );
772  std::vector<uint32_t>::iterator it = std::find(m_targetSizeSet.begin(), m_targetSizeSet.end(), size);
773  if(it == m_targetSizeSet.end())
774  m_targetSizeSet.push_back(size);
775 }
776 
777 void
779 {
781 
783  NS_LOG_FUNCTION ("case 1");
785 
786  }else if(m_currentKeyBit < m_thresholdKeyBit && m_currentKeyBit > m_minKeyBit &&
788  ){
789  NS_LOG_FUNCTION ("case 2");
791 
792  }else if(m_currentKeyBit < m_thresholdKeyBit && m_currentKeyBit > m_minKeyBit &&
794  ){
795  NS_LOG_FUNCTION ("case 3");
797 
798  }else if(m_currentKeyBit <= m_minKeyBit){
799  NS_LOG_FUNCTION ("case 4");
801  }else{
803  }
804 
805  if(m_previousStatus != m_status){
806  NS_LOG_FUNCTION (this << "STATUS IS NOT EQUAL TO PREVIOUS STATUS" << m_previousStatus << m_status);
808 
812  }
813 }
814 
815 bool
817 {
818  return (this->m_bufferID == o.m_bufferID);
819 }
820 
821 
822 uint32_t
824  NS_LOG_FUNCTION (this << this->m_bufferID);
825  return this->m_bufferID ;
826 }
827 
828 void
830 
831  NS_LOG_FUNCTION (this);
832 
835 
836 }
837 
841 int64_t
843 
844  NS_LOG_FUNCTION (this);
846 }
847 
848 /*
849 * Return time difference between the current time and time at which
850 * last key charging process finished
851 */
852 int64_t
854 
855  NS_LOG_FUNCTION (this);
856  int64_t currentTime = Simulator::Now ().GetMilliSeconds();
857  return currentTime - m_lastKeyChargingTimeStamp;
858 }
859 
860 double
864 }
865 
866 uint32_t
868 {
869  NS_LOG_FUNCTION (this << m_status);
870  return m_status;
871 }
872 
873 uint32_t
875 {
877  return m_previousStatus;
878 }
879 
880 uint32_t
882 {
885 }
886 
887 uint32_t
888 QKDBuffer::GetMthr (void) const
889 {
891  return m_thresholdKeyBit;
892 }
893 void
894 QKDBuffer::SetMthr (uint32_t thr)
895 {
896  NS_LOG_FUNCTION (this << thr);
897 
898  if(thr > m_thresholdKeyBit){
900  }else{
902  }
903 
904  m_thresholdKeyBit = thr;
906 }
907 
908 void
910  m_srcNode = node;
911 }
912 Ptr<Node>
914  return m_srcNode;
915 }
916 
917 void
919  m_dstNode = node;
920 }
921 Ptr<Node>
923  return m_dstNode;
924 }
925 
926 void
927 QKDBuffer::SetIndex (uint32_t index){
928  m_srcNodeBufferListIndex = index;
929 }
930 uint32_t
933 }
934 
935 } // namespace ns3
A base class which provides memory management and object aggregation.
Definition: object.h:88
QKD buffer is a secure storage for QKD keys.
Definition: qkd-buffer.h:79
uint32_t m_srcNodeBufferListIndex
The index in the source node buffer list.
Definition: qkd-buffer.h:531
double m_averageKeyChargingTimePeriod
The average duration of the key charging time period.
Definition: qkd-buffer.h:511
double m_averageKeyConsumptionSize
The average key consumption size.
Definition: qkd-buffer.h:514
int64_t m_lastKeyChargingTimeStamp
The timestamp of a last key charging (when the new key material was added).
Definition: qkd-buffer.h:500
uint32_t m_noEntry
Help value used for graph ploting.
Definition: qkd-buffer.h:474
double m_averageKeyConsumptionRate
The average key consumption rate.
Definition: qkd-buffer.h:516
double m_averageKeyGenerationRate
The average key generation rate.
Definition: qkd-buffer.h:515
TracedCallback< Ptr< QKDKey > > m_keyReservedTrace
A trace for reserved keys.
Definition: qkd-buffer.h:521
static const uint32_t QKDSTATUS_WARNING
QKDStatus WARNING.
Definition: qkd-buffer.h:85
std::vector< int64_t > m_lastChargedKeySizes
The size of the several last generated keys.
Definition: qkd-buffer.h:506
bool m_useRealStorages
Definition: qkd-buffer.h:470
void UpdateKeyConsumptionStatistics(Ptr< QKDKey > key)
Update key consumption statistics.
Definition: qkd-buffer.cc:532
uint32_t m_bufferID
The unique buffer identifier.
Definition: qkd-buffer.h:302
bool operator==(QKDBuffer const &o) const
Define equal operator on the QKD buffer object.
Definition: qkd-buffer.cc:816
void UpdateKeyGenerationStatistics(Ptr< QKDKey > key)
Update key generation statistics.
Definition: qkd-buffer.cc:604
uint64_t GetMinKeySizeBit()
Get the minimum key size that can be served in bits.
Definition: qkd-buffer.cc:303
TracedCallback< double > m_CMetricChangeTrace
A trace of c metric changes.
Definition: qkd-buffer.h:526
TracedCallback< uint32_t > m_currentKeyBitDecreaseTrace
A trace of decrease in amount of key bits.
Definition: qkd-buffer.h:524
std::map< std::string, Ptr< QKDKey > > m_keys
The list of available keys with their identifiers.
Definition: qkd-buffer.h:472
uint32_t GetMaxKeyCount()
Get the maximum number of stored keys.
Definition: qkd-buffer.cc:283
uint32_t GetKeyCount()
Get the number of stored keys.
Definition: qkd-buffer.cc:275
uint32_t m_thresholdKeyBit
The threshold amount of key material in the QKD key storage.
Definition: qkd-buffer.h:487
int64_t FetchDeltaTime()
Definition: qkd-buffer.cc:853
Ptr< QKDKey > SearchOptimalKeyToTransform(uint32_t targetSize)
Serach for the optimal key to transform.
Definition: qkd-buffer.cc:716
uint32_t m_maxKeyBit
The maximal amount of key material in the QKD key storage.
Definition: qkd-buffer.h:486
double FetchAverageKeyChargingTimePeriod()
Get the average duration of key charging process in the long run.
Definition: qkd-buffer.cc:861
uint32_t m_maxNumberOfRecordedKeyChargingTimePeriods
The maximal number of values which are used for calculation of the average key charging time period.
Definition: qkd-buffer.h:504
uint32_t m_period
Help value used for graph ploting.
Definition: qkd-buffer.h:475
uint32_t m_minimalKeyCount
The minimal number of stored keys.
Definition: qkd-buffer.h:488
uint32_t m_status
The state of the Net Device transmit state machine.
Definition: qkd-buffer.h:510
Ptr< QKDKey > FetchKeyBySize(const uint32_t &keySize)
Get the key of a given size.
Definition: qkd-buffer.cc:475
uint32_t m_currentKeyBitReally
The current amount of key material used for real tracking of storage (transform!).
Definition: qkd-buffer.h:496
int64_t m_lastKeyChargingTimeDuration
The timestamp of a last key usage.
Definition: qkd-buffer.h:502
TracedCallback< uint32_t > m_thresholdKeyBitChangeTrace
A traceback for available key bits.
Definition: qkd-buffer.h:491
static const uint32_t QKDSTATUS_CHARGING
QKDStatus CHARGING.
Definition: qkd-buffer.h:87
std::vector< int64_t > m_lastConsumedKeySizes
The size of the several last consumed keys.
Definition: qkd-buffer.h:507
uint64_t GetMaxKeySizeBit()
Get the maximal key size that can be served in bits.
Definition: qkd-buffer.cc:307
virtual ~QKDBuffer()
Destructor.
Definition: qkd-buffer.cc:219
uint32_t GetIndex()
Get the index of the buffer per local node.
Definition: qkd-buffer.cc:931
Ptr< Node > GetSrcNode()
Get the QKD source node.
Definition: qkd-buffer.cc:913
double m_averageKeyConsumptionTimePeriod
The average duration of the key consumption time period.
Definition: qkd-buffer.h:512
Ptr< Node > GetDstNode()
Get the QKD destination node.
Definition: qkd-buffer.cc:922
TracedCallback< uint32_t > m_thresholdKeyBitDecreaseTrace
A traceback for consumed key bits.
Definition: qkd-buffer.h:493
double m_averageKeyChargingSize
The average key charging size.
Definition: qkd-buffer.h:513
uint32_t m_bitsUsedInTimePeriod
Help value used for graph ploting.
Definition: qkd-buffer.h:477
TracedCallback< uint32_t > m_currentKeyBitChangeTrace
A trace for current bit change.
Definition: qkd-buffer.h:522
int64_t m_lastKeyConsumptionTimeStamp
The timestamp of a last key consumption (when the last key material was fetched).
Definition: qkd-buffer.h:501
void Dispose(void)
Destroy a QKD buffer.
Definition: qkd-buffer.cc:228
bool AddNewKey(Ptr< QKDKey > key, uint32_t keyTransformed)
Add new key to the storage.
Definition: qkd-buffer.cc:318
uint32_t m_maximalKeyCount
The maximal number of stored keys.
Definition: qkd-buffer.h:489
std::vector< struct QKDBuffer::data > m_previousValues
Help vector used for graph ploting.
Definition: qkd-buffer.h:480
uint32_t m_maxNumberOfRecordedKeyConsumptionTimePeriods
The maximal number of values which are used for calculation of the average key consumption time perio...
Definition: qkd-buffer.h:505
uint32_t FetchPreviousState(void)
Get the previous state of the QKD buffer.
Definition: qkd-buffer.cc:874
bool ProbeKeyStatus(std::string keyId, QKDKey::QKDKeyState_e keyState)
Check if the state of the key equals to a given state.
Definition: qkd-buffer.cc:455
std::vector< int64_t > m_chargingTimePeriods
The durations of the serveral last charging time periods.
Definition: qkd-buffer.h:508
uint32_t m_defaultKeySize
The default key size as required by the ETSI QKD 014 interface details.
Definition: qkd-buffer.h:469
TracedCallback< Ptr< QKDKey > > m_newKeyAddedTrace
A trace of newly added keys.
Definition: qkd-buffer.h:518
void SetIndex(uint32_t)
Set the index of the buffer per local node.
Definition: qkd-buffer.cc:927
uint64_t GetTargetKeyCountBit()
Get tge amount of key material in bits that is ready to be served and belongs to a set of targeted ke...
Definition: qkd-buffer.cc:298
void KeyCalculation()
Help function used for ploting graphs.
Definition: qkd-buffer.cc:245
uint32_t m_currentKeyBit
The current amount of key material in the QKD key storage.
Definition: qkd-buffer.h:495
std::map< uint32_t, QKDBuffer::KeyStorage > m_destinations
Definition: qkd-buffer.h:533
uint32_t GetId(void) const
Get the QKD buffer identifier.
Definition: qkd-buffer.cc:823
void ReserveKey(std::string keyId)
Reserve the QKD key.
Definition: qkd-buffer.cc:665
TracedCallback< double > m_averageKeyConsumptionRateTrace
A trace of the average key consumption rate.
Definition: qkd-buffer.h:529
TracedCallback< uint32_t > m_currentKeyBitIncreaseTrace
A trace of increase in amount of key bits.
Definition: qkd-buffer.h:523
static const uint32_t QKDSTATUS_READY
QKDStatus READY.
Definition: qkd-buffer.h:83
void SetSrcNode(Ptr< Node >)
Set the QKD source node.
Definition: qkd-buffer.cc:909
TracedCallback< double > m_averageKeyGenerationRateTrace
A trace of the average key generation rate.
Definition: qkd-buffer.h:528
void SetMthr(uint32_t thr)
Set the threshold value of the QKD storage.
Definition: qkd-buffer.cc:894
uint32_t GetMinKeyCount()
Get the minimum number of stored keys.
Definition: qkd-buffer.cc:279
double GetAverageKeyGenerationRate()
Get average key generation rate.
Definition: qkd-buffer.cc:431
uint32_t FetchMaxNumberOfRecordedKeyChargingTimePeriods()
Get the maximal number of values which are used for calculation of average key charging time period.
Definition: qkd-buffer.cc:437
TracedCallback< Ptr< QKDKey > > m_transformedKeyAddedTrace
A trace for tranformed keys.
Definition: qkd-buffer.h:519
static uint32_t nBuffers
The number of the created buffers - a static value.
Definition: qkd-buffer.h:303
Ptr< QKDKey > FetchKeyByID(std::string keyID)
Get the key of a given identifier.
Definition: qkd-buffer.cc:498
std::vector< int64_t > m_consumptionTimePeriods
The durations of the serveral last consumption time periods.
Definition: qkd-buffer.h:509
uint32_t GetKeySize()
Get default size of the key (ETSI QKD 014).
Definition: qkd-buffer.cc:235
int64_t FetchLastKeyChargingTimeDuration()
Get the time value about the time duration of last key charging process.
Definition: qkd-buffer.cc:842
std::vector< uint32_t > m_targetSizeSet
The list of requested key sizes.
Definition: qkd-buffer.h:468
static const uint32_t QKDSTATUS_EMPTY
QKDStatus EMPTY.
Definition: qkd-buffer.h:89
void ReleaseReservation(std::string keyId)
Release the key reservation.
Definition: qkd-buffer.cc:697
int64_t m_lastKeyConsumptionTimeDuration
The timestamp of a last key fetch operation.
Definition: qkd-buffer.h:503
Ptr< Node > m_srcNode
The source node.
Definition: qkd-buffer.h:300
uint32_t m_previousStatus
The previous status; important for deciding about further status that can be selected.
Definition: qkd-buffer.h:484
uint32_t GetMthr(void) const
Get the threshold value of QKD storage.
Definition: qkd-buffer.cc:888
uint32_t m_recalculateTimePeriod
The period of time (in seconds) to calculate average amount of the key in the buffer.
Definition: qkd-buffer.h:479
TracedCallback< uint32_t > m_StatusChangeTrace
A trace of status changes.
Definition: qkd-buffer.h:525
bool m_isRisingCurve
Whether curve on graph is rising or not.
Definition: qkd-buffer.h:483
uint64_t m_currentReadyKeyBit
The current amount of key material in the QKD buffer that are ready to be served.
Definition: qkd-buffer.h:497
Ptr< Node > m_dstNode
The destination node.
Definition: qkd-buffer.h:301
void SetDstNode(Ptr< Node >)
Set the QKD destination node.
Definition: qkd-buffer.cc:918
TracedCallback< Ptr< QKDKey > > m_keyServedTrace
A trace for served keys.
Definition: qkd-buffer.h:520
double GetAverageKeyConsumptionRate()
Get average key consumption rate.
Definition: qkd-buffer.cc:366
uint32_t GetMCurrentPrevious(void) const
Get previous - before latest change.
Definition: qkd-buffer.cc:881
static TypeId GetTypeId(void)
Get the TypeId.
Definition: qkd-buffer.cc:40
QKDBuffer()
Constructor.
Definition: qkd-buffer.cc:166
TracedCallback< uint32_t > m_thresholdKeyBitIncreaseTrace
A traceback for generated key bits.
Definition: qkd-buffer.h:492
EventId m_calculateRoutingMetric
The event to calculate routing metric.
Definition: qkd-buffer.h:517
void InitTotalGraph() const
Initialize total graph.
Definition: qkd-buffer.cc:829
uint32_t m_minKeyBit
The minimal amount of key material in the QKD key storage.
Definition: qkd-buffer.h:485
void CheckState(void)
Update the state of the buffer.
Definition: qkd-buffer.cc:778
uint32_t m_nextKeyID
The identifie of the next key to be generated.
Definition: qkd-buffer.h:471
uint32_t m_noAddNewValue
Help value used for graph ploting.
Definition: qkd-buffer.h:476
uint32_t FetchState(void)
Get the current state of the QKD buffer.
Definition: qkd-buffer.cc:867
void RecordTargetSize(uint32_t size)
Record the key target size.
Definition: qkd-buffer.cc:769
uint64_t m_currentTargetKeyBit
The current amount of key material in the QKD buffer that is already targeted.
Definition: qkd-buffer.h:498
void Init(Ptr< Node > srcNode, Ptr< Node > dstNode, uint32_t Mmin, uint32_t Mthr, uint32_t Mmax, uint32_t Mcurrent, bool useRealStorages)
Initialize a QKD buffer.
Definition: qkd-buffer.cc:172
uint32_t m_currentKeyBitPrevious
The previous value of current amount of key material in the QKD key storage.
Definition: qkd-buffer.h:499
uint64_t GetReadyKeyCountBit()
Get the amount of the key material in bits that is ready to be served.
Definition: qkd-buffer.cc:293
uint64_t GetKeyCountBit()
Get the amount of stored keys in bits.
Definition: qkd-buffer.cc:288
QKDKeyState_e
The QKD key states.
Definition: qkd-key.h:76
@ RESERVED
Definition: qkd-key.h:84
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:268
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
int64_t GetMilliSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:383
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:45
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool compareByData(const QKDBuffer::data &a, const QKDBuffer::data &b)
Definition: qkd-buffer.cc:239
Data specific variables.
Definition: qkd-buffer.h:94