A Discrete-Event Network Simulator
API
qkd-postprocessing-application.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 #include "ns3/address.h"
22 #include "ns3/node.h"
23 #include "ns3/nstime.h"
24 #include "ns3/socket.h"
25 #include "ns3/simulator.h"
26 #include "ns3/packet.h"
27 #include "ns3/uinteger.h"
28 #include "ns3/trace-source-accessor.h"
30 #include <iostream>
31 #include <fstream>
32 #include <string>
33 
34 namespace ns3 {
35 
36  NS_LOG_COMPONENT_DEFINE ("QKDPostprocessingApplication");
37 
38  NS_OBJECT_ENSURE_REGISTERED (QKDPostprocessingApplication);
39 
40  TypeId
42  {
43  static TypeId tid = TypeId ("ns3::QKDPostprocessingApplication")
45  .SetGroupName("Applications")
46  .AddConstructor<QKDPostprocessingApplication> ()
47  .AddAttribute ("KeySizeInBits", "The amount of data to be added to QKD Buffer (in bits).",
48  UintegerValue (8192),
50  MakeUintegerChecker<uint32_t> ())
51  .AddAttribute ("KeyRate", "The average QKD key rate in bps.",
52  DataRateValue (DataRate ("1000bps")),
53  MakeDataRateAccessor (&QKDPostprocessingApplication::m_keyRate),
54  MakeDataRateChecker ())
55  .AddAttribute ("DataRate", "The average data rate of communication.",
56  DataRateValue (DataRate ("650kbps")), //3.3Mbps //10kbps
57  MakeDataRateAccessor (&QKDPostprocessingApplication::m_dataRate),
58  MakeDataRateChecker ())
59  .AddAttribute ("PacketSize", "The size of packets sent in post-processing state",
60  UintegerValue (320), //280
62  MakeUintegerChecker<uint32_t> ())
63  .AddAttribute ("MaxSiftingPackets", "The size of packets sent in sifting state",
64  UintegerValue (5),
66  MakeUintegerChecker<uint32_t> ())
67 
68  .AddAttribute ("Protocol", "The type of protocol to use (TCP by default).",
72  .AddAttribute ("ProtocolSifting", "The type of protocol to use for sifting (UDP by default).",
76 
77  .AddAttribute ("Remote", "The address of the destination",
78  AddressValue (),
79  MakeAddressAccessor (&QKDPostprocessingApplication::m_peer),
80  MakeAddressChecker ())
81  .AddAttribute ("Local", "The local address on which to bind the listening socket.",
82  AddressValue (),
83  MakeAddressAccessor (&QKDPostprocessingApplication::m_local),
84  MakeAddressChecker ())
85  .AddAttribute ("Remote_Sifting", "The address of the destination for sifting traffic.",
86  AddressValue (),
87  MakeAddressAccessor (&QKDPostprocessingApplication::m_peer_sifting),
88  MakeAddressChecker ())
89  .AddAttribute ("Local_Sifting", "The local address on which to bind the listening sifting socket.",
90  AddressValue (),
91  MakeAddressAccessor (&QKDPostprocessingApplication::m_local_sifting),
92  MakeAddressChecker ())
93  .AddAttribute ("Local_KMS", "The local KSM address.",
94  AddressValue (),
95  MakeAddressAccessor (&QKDPostprocessingApplication::m_kms),
96  MakeAddressChecker ())
97  .AddTraceSource ("Tx", "A new packet is created and is sent",
99  "ns3::QKDPostprocessingApplication::Tx")
100  .AddTraceSource ("Rx", "A packet has been received",
102  "ns3::QKDPostprocessingApplication::Rx")
103  .AddTraceSource ("TxKMS", "A new packet is created and is sent to LKMS",
105  "ns3::QKDPostprocessingApplication::TxKMS")
106  .AddTraceSource ("RxKMS", "A packet has been received from LKMS",
108  "ns3::QKDPostprocessingApplication::RxLKMS")
109  ;
110  return tid;
111  }
112 
114  {
115  m_connected = false;
116  m_random = CreateObject<UniformRandomVariable> ();
117  m_packetNumber = 1;
118  m_totalRx = 0;
122  }
123 
125  {
126  NS_LOG_FUNCTION (this);
127  }
128 
129  void
131  m_keyId = m_random->GetValue (0, 99999999);
132  }
133 
134 
136  {
137  NS_LOG_FUNCTION (this);
138  return m_totalRx;
139  }
140 
141  Ptr<Node>
143  return m_src;
144  }
145  void
147  NS_LOG_FUNCTION (this << node->GetId());
148  m_src = node;
149  }
150 
151  Ptr<Node>
153  return m_dst;
154  }
155  void
157  NS_LOG_FUNCTION (this << node->GetId());
158  m_dst = node;
159  }
160 
161  std::list<Ptr<Socket> >
163  {
164  NS_LOG_FUNCTION (this);
165  return m_sinkSocketList;
166  }
167 
170  {
171  NS_LOG_FUNCTION (this);
172  return m_sinkSocket;
173  }
174 
177  {
178  NS_LOG_FUNCTION (this);
179  return m_sendSocket;
180  }
181 
182  void
183  QKDPostprocessingApplication::SetSocket (std::string type, Ptr<Socket> socket, bool isMaster)
184  {
185  NS_LOG_FUNCTION (this << type << socket << isMaster);
186  if(type == "send"){//send app
187  m_sendSocket = socket;
188  }else{ // sink app
189  m_sinkSocket = socket;
190  }
191  m_master = isMaster;
192  }
193 
194  void
196  {
197  NS_LOG_FUNCTION (this << type << socket);
198  if(type == "send"){//send app
199  m_sendSocket_sifting = socket;
200  }else{ // sink app
201  m_sinkSocket_sifting = socket;
202  }
203  }
204 
205  void
207  {
208  NS_LOG_FUNCTION (this);
209 
210  m_sendSocket = 0;
211  m_sinkSocket = 0;
214 
215  m_sinkSocketList.clear ();
217  // chain up
219  }
220 
221  // Application Methods
222  void QKDPostprocessingApplication::StartApplication (void) // Called at time specified by Start
223  {
224  NS_LOG_FUNCTION (this);
226 
227  // SINK socket settings
229  InetSocketAddress sinkAddress = InetSocketAddress (
232  );
233  if (m_sinkSocket->Bind (sinkAddress) == -1) NS_FATAL_ERROR ("Failed to bind socket");
234  m_sinkSocket->Listen ();
238  MakeNullCallback<bool, Ptr<Socket>, const Address &> (),
240  );
244  );
245 
246  // SEND socket settings
249  uint32_t interface = ipv4->GetInterfaceForAddress( InetSocketAddress::ConvertFrom (m_local).GetIpv4 () );
250  Ptr<NetDevice> netDevice = ipv4->GetNetDevice(interface);
251  //m_sendSocket->BindToNetDevice (netDevice);
252  m_sendSocket->ShutdownRecv ();
253  m_sendSocket->SetConnectCallback (
254  MakeCallback (&QKDPostprocessingApplication::ConnectionSucceeded, this),
255  MakeCallback (&QKDPostprocessingApplication::ConnectionFailed, this)
256  );
257  m_sendSocket->SetDataSentCallback (
258  MakeCallback (&QKDPostprocessingApplication::DataSend, this)
259  );
260  m_sendSocket->TraceConnectWithoutContext ("RTT", MakeCallback (&QKDPostprocessingApplication::RegisterAckTime, this));
261  m_sendSocket->Connect (m_peer);
262 
264  this <<
265  "Connecting QKDApp (" <<
266  InetSocketAddress::ConvertFrom (m_peer).GetIpv4 () << " port " << InetSocketAddress::ConvertFrom (m_peer).GetPort () <<
267  " from " <<
268  InetSocketAddress::ConvertFrom (m_local).GetIpv4 () << " port " << InetSocketAddress::ConvertFrom (m_local).GetPort ()
269  );
270 
271 
272 
273  /**** SIFTING SOCKETS ****/
274  // SINK socket settings
275  if (!m_sinkSocket_sifting) m_sinkSocket_sifting = Socket::CreateSocket (GetNode (), m_tidSifting);
276  m_sinkSocket_sifting->Bind (m_local_sifting);
277  m_sinkSocket_sifting->Listen ();
278  m_sinkSocket_sifting->ShutdownSend ();
279  m_sinkSocket_sifting->SetRecvCallback (MakeCallback (&QKDPostprocessingApplication::HandleReadSifting, this));
280 
281  // SEND socket settings
282  if (!m_sendSocket_sifting) m_sendSocket_sifting = Socket::CreateSocket (GetNode (), m_tidSifting);
283  m_sendSocket_sifting->Connect (m_peer_sifting);
284  m_sendSocket_sifting->ShutdownRecv ();
285 
286 
287 
288  /**** KMS SOCKETS ****/
289  // SINK socket settings
290  if (!m_sinkSocketKMS) m_sinkSocketKMS = Socket::CreateSocket (GetNode (), m_tid);
291  uint32_t portKMS = InetSocketAddress::ConvertFrom (m_kms).GetPort ();
292  if (m_sinkSocketKMS->Bind (m_kms) == -1) NS_FATAL_ERROR ("Failed to bind socket");
293  m_sinkSocketKMS->Listen ();
294  m_sinkSocketKMS->ShutdownSend ();
295  m_sinkSocketKMS->SetRecvCallback (MakeCallback (&QKDPostprocessingApplication::HandleReadKMS, this));
296  m_sinkSocketKMS->SetAcceptCallback (
297  MakeNullCallback<bool, Ptr<Socket>, const Address &> (),
298  MakeCallback (&QKDPostprocessingApplication::HandleAcceptKMS, this));
299  m_sinkSocketKMS->SetCloseCallbacks (
300  MakeCallback (&QKDPostprocessingApplication::HandlePeerCloseKMS, this),
301  MakeCallback (&QKDPostprocessingApplication::HandlePeerErrorKMS, this));
302 
303  // SEND socket settings
304  if (!m_sendSocketKMS) m_sendSocketKMS = Socket::CreateSocket (GetNode (), m_tid);
305  Ipv4Address localIpv4 = InetSocketAddress::ConvertFrom (m_local).GetIpv4 ();
306  InetSocketAddress senderKMS = InetSocketAddress (
307  localIpv4,
308  portKMS
309  );
310  NS_LOG_FUNCTION(
311  this <<
312  "Connecting KMS (" <<
313  InetSocketAddress::ConvertFrom (m_kms).GetIpv4 () << " port " << portKMS <<
314  " from " <<
315  localIpv4 << " port" << portKMS
316  );
317  m_sendSocketKMS->Bind (senderKMS);
318  m_sendSocketKMS->ShutdownRecv ();
319  m_sendSocketKMS->SetConnectCallback (
320  MakeCallback (&QKDPostprocessingApplication::ConnectionSucceededKMS, this),
321  MakeCallback (&QKDPostprocessingApplication::ConnectionFailedKMS, this));
322  m_sendSocketKMS->SetDataSentCallback (
323  MakeCallback (&QKDPostprocessingApplication::DataSendKMS, this));
324  m_sendSocketKMS->TraceConnectWithoutContext ("RTT", MakeCallback (&QKDPostprocessingApplication::RegisterAckTime, this));
325  m_sendSocketKMS->Connect (m_kms);
326 
327  }
328 
329 
330  void QKDPostprocessingApplication::StopApplication (void) // Called at time specified by Stop
331  {
332  NS_LOG_FUNCTION (this);
333 
334  if (m_sendSocket)
335  {
336  m_sendSocket->Close ();
337  }
338  else
339  {
340  NS_LOG_WARN ("QKDPostprocessingApplication found null socket to close in StopApplication");
341  }
342 
343  NS_LOG_FUNCTION (this);
344  while(!m_sinkSocketList.empty ()) //these are accepted sockets, close them
345  {
346  Ptr<Socket> acceptedSocket = m_sinkSocketList.front ();
347  m_sinkSocketList.pop_front ();
348  acceptedSocket->Close ();
349  }
350  if (m_sinkSocket)
351  {
352  m_sinkSocket->Close ();
353  m_sinkSocket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
354  }
355 
356  m_connected = false;
357  Simulator::Cancel (m_sendEvent);//
358  }
359 
360  void QKDPostprocessingApplication::ScheduleNextReset(){
361 
362  double ratio = m_keySizeInBits / static_cast<double>(m_keyRate.GetBitRate ());
363 
364  Time nextTime (Seconds (ratio)); // Time till next QKD packet
365  Simulator::Schedule (nextTime, &QKDPostprocessingApplication::ResetCounter, this);
366 
367  NS_LOG_FUNCTION (this << m_keySizeInBits << "\t" << static_cast<double>(m_keyRate.GetBitRate ()) << "\t" << "ratio:" << ratio << "nextTime:" << nextTime);
368  }
369 
370  void QKDPostprocessingApplication::ResetCounter (){
371 
372  NS_LOG_FUNCTION (this << m_packetNumber);
373 
374  if(m_master) m_packetNumber = 0;
375  if(m_connected) SendSiftingPacket();
376  SendData();
377 
378  }
379 
380  void QKDPostprocessingApplication::SendData (void)
381  {
382  NS_LOG_FUNCTION (this);
383 
384  if(m_master == true){
385  NS_LOG_FUNCTION(this << "********************** MASTER **********************");
386  }else{
387  NS_LOG_FUNCTION(this << "********************** SLAVE **********************");
388  }
389 
390  NS_LOG_DEBUG (this << "\t Sending packet " << m_packetNumber );
391  if(m_packetNumber > 0){
392  nlohmann::json msgBody;
393  msgBody["ACTION"] = "QKDPPS";
394  msgBody["NUMBER"] = m_packetNumber;
395  std::string message = msgBody.dump();
396  PrepareOutput(message, "qkdpps");
397  }else{
398 
399  NS_LOG_FUNCTION (this << "m_lastUUID:\t" << m_lastUUID);
400 
401  std::string keyId;
402  if(m_master){
403  UUID keyIdRaw = UUID::Sequential();
404  keyId = keyIdRaw.string();
405  }else
406  keyId = m_lastUUID;
407 
408  if(keyId.size() > 0){
409 
410  GenerateRandomKeyId();
411 
412  nlohmann::json msgBody;
413  msgBody["ACTION"] = "ADDKEY";
414  msgBody["size"] = m_keySizeInBits;
415  msgBody["uuid"] = keyId;
416  msgBody["srid"] = m_keyId; //seed random key id
417  std::string message = msgBody.dump();
418 
419  PrepareOutput(message, "addkey");
420  ScheduleNextReset();
421 
422  if(m_master && m_connected){
423  NS_LOG_FUNCTION( this << "ADDKEY" << keyId );
424  Ptr<QKDKey> newKey = Create<QKDKey> (keyId, m_keyId, m_keySizeInBits);
425  SendPacketToKMS(newKey);
426  }
427  }
428  }
429  m_packetNumber++;
430 
431  }
432 
433  void QKDPostprocessingApplication::PrepareOutput (std::string value, std::string action)
434  {
435  NS_LOG_FUNCTION (this << Simulator::Now () << action << value);
436 
437  std::ostringstream msg;
438  msg << value << ";";
439 
440  //playing with packet size to introduce some randomness
441  msg << std::string( m_random->GetValue (m_pktSize, m_pktSize*1.1), '0');
442  msg << '\0';
443 
444  Ptr<Packet> packet = Create<Packet> ((uint8_t*) msg.str().c_str(), msg.str().length());
445  NS_LOG_DEBUG(this << "\t !!!SENDING PACKET WITH CONTENT:" << value << " of size " << packet->GetSize() );
446 
447  uint32_t bits = packet->GetSize() * 8;
448  NS_LOG_LOGIC (this << "bits = " << bits);
449 
450  if(action == "qkdpps"){
451  Time nextTime (Seconds (bits / static_cast<double>(m_dataRate.GetBitRate ()))); // Time till next packet
452  NS_LOG_FUNCTION(this << "CALCULATED NEXTTIME:" << bits / m_dataRate.GetBitRate ());
453  NS_LOG_LOGIC ("nextTime = " << nextTime);
454  m_sendEvent = Simulator::Schedule (nextTime, &QKDPostprocessingApplication::SendPacket, this, packet);
455  }else if(action == "addkey"){
456  SendPacket(packet);
457  }
458 
459  }
460 
461 
462  void QKDPostprocessingApplication::SendPacket (Ptr<Packet> packet){
463 
464  NS_LOG_FUNCTION (this << "\t" << packet << "PACKETID: " << packet->GetUid() << packet->GetSize() );
465  if(m_connected){
466  m_txTrace (packet);
467  m_sendSocket->Send (packet);
468  }
469  }
470 
471  void QKDPostprocessingApplication::SendPacketToKMS (Ptr<QKDKey> key){
472 
473  NS_LOG_FUNCTION (this);
474 
475  //Create a message body
476  nlohmann::json msgBody;
477  Ipv4Address source = InetSocketAddress::ConvertFrom(m_local).GetIpv4 ();
478  std::ostringstream srcAddressTemp;
479  source.Print(srcAddressTemp); //IPv4Address to string
480  std::string sourceString = srcAddressTemp.str ();
481 
482  Ipv4Address destination = InetSocketAddress::ConvertFrom(m_peer).GetIpv4 ();
483  std::ostringstream dstAddressTemp;
484  destination.Print(dstAddressTemp); //IPv4Address to string
485  std::string destinationString = dstAddressTemp.str ();
486 
487  msgBody["source"] = sourceString;
488  msgBody["destination"] = destinationString;
489 
490  msgBody["key_id"] = key->GetId();
491  msgBody["key"] = key->GetKeyString();
492  msgBody["src_id"] = GetSrc()->GetId();
493  msgBody["dst_id"] = GetDst()->GetId();
494 
495  std::string message = msgBody.dump();
496 
497  Ipv4Address lkmsAddress = InetSocketAddress::ConvertFrom(m_kms).GetIpv4 ();
498  std::ostringstream lkmsAddressTemp;
499  lkmsAddress.Print(lkmsAddressTemp); //IPv4Address to string
500  std::string headerUri = "http://" + lkmsAddressTemp.str ();
501  headerUri += "/api/v1/keys/" + destinationString + "/store_pp_key";
502 
503  HTTPMessage httpMessage;
504  httpMessage.CreateRequest(headerUri, "POST", message);
505  std::string hMessage = httpMessage.ToString();
506  Ptr<Packet> packet = Create<Packet> (
507  (uint8_t*) (hMessage).c_str(),
508  hMessage.size()
509  );
510  NS_ASSERT (packet);
511 
512  NS_LOG_FUNCTION (this << "Sending PACKETID: " << packet->GetUid()
513  << " of size: " << packet->GetSize()
514  << " key_id: " << key->GetId()
515  << " via socket " << m_sendSocketKMS
516  );
517 
518  m_txTraceKMS (packet);
519  m_sendSocketKMS->Send (packet);
520  }
521 
522  void QKDPostprocessingApplication::SendSiftingPacket(){
523 
524  NS_LOG_FUNCTION (this);
525 
526  uint32_t tempValue = 800 + m_random->GetValue (100, 300);
527  NS_LOG_FUNCTION (this << "Sending SIFTING packet of size" << tempValue);
528  Ptr<Packet> packet = Create<Packet> (tempValue);
529  m_sendSocket_sifting->Send (packet);
530  NS_LOG_FUNCTION (this << packet << "PACKETID: " << packet->GetUid() << " of size: " << packet->GetSize() );
531 
532  m_packetNumber_sifting++;
533 
534  if(m_packetNumber_sifting < m_maxPackets_sifting){
535  Simulator::Schedule (MicroSeconds(400), &QKDPostprocessingApplication::SendSiftingPacket, this);
536  }else {
537  m_packetNumber_sifting = 0;
538  }
539  }
540 
541  void QKDPostprocessingApplication::HandleReadKMS (Ptr<Socket> socket)
542  {
543  if(m_master == true) {
544  NS_LOG_FUNCTION(this << "--------------MASTER--------------");
545  } else {
546  NS_LOG_FUNCTION(this << "--------------SLAVE--------------");
547  }
548 
549  Ptr<Packet> packet;
550  Address from;
551  while ((packet = socket->RecvFrom (from)))
552  {
553  if (packet->GetSize () == 0)
554  { //EOF
555  break;
556  }
557 
558  NS_LOG_FUNCTION (this << packet << "PACKETID: " << packet->GetUid() << " of size: " << packet->GetSize() );
559 
560  m_totalRx += packet->GetSize ();
561  if (InetSocketAddress::IsMatchingType (from))
562  {
563 
564  NS_LOG_FUNCTION (this << "At time " << Simulator::Now ().GetSeconds ()
565  << "s packet sink received "
566  << packet->GetSize () << " bytes from "
567  << InetSocketAddress::ConvertFrom(from).GetIpv4 ()
568  << " port " << InetSocketAddress::ConvertFrom (from).GetPort ()
569  << " total Rx " << m_totalRx << " bytes");
570  }
571  m_rxTraceKMS (packet, from);
572  }
573  }
574  void QKDPostprocessingApplication::HandleRead (Ptr<Socket> socket)
575  {
576  if(m_master == true) {
577  NS_LOG_FUNCTION(this << "--------------MASTER--------------");
578  } else {
579  NS_LOG_FUNCTION(this << "--------------SLAVE--------------");
580  }
581 
582  Ptr<Packet> packet;
583  Address from;
584  while ((packet = socket->RecvFrom (from)))
585  {
586  if (packet->GetSize () == 0)
587  { //EOF
588  break;
589  }
590 
591  NS_LOG_FUNCTION (this << packet << "PACKETID: " << packet->GetUid() << " of size: " << packet->GetSize() );
592 
593  m_totalRx += packet->GetSize ();
594  if (InetSocketAddress::IsMatchingType (from))
595  {
596 
597  NS_LOG_FUNCTION (this << "At time " << Simulator::Now ().GetSeconds ()
598  << "s packet sink received "
599  << packet->GetSize () << " bytes from "
600  << InetSocketAddress::ConvertFrom(from).GetIpv4 ()
601  << " port " << InetSocketAddress::ConvertFrom (from).GetPort ()
602  << " total Rx " << m_totalRx << " bytes");
603 
604  }
605 
606  m_rxTrace (packet, from);
607  ProcessIncomingPacket(packet);
608 
609  }
610  }
611 
612 
613  void QKDPostprocessingApplication::ProcessIncomingPacket(Ptr<Packet> packet)
614  {
618  uint8_t *buffer = new uint8_t[packet->GetSize ()];
619  packet->CopyData(buffer, packet->GetSize ());
620  std::string s = std::string((char*)buffer);
621  delete[] buffer;
622 
623  std::string packetValue;
624  if(s.size() > 5){
625 
626  NS_LOG_FUNCTION(this << "payload:" << s);
627 
628  std::size_t pos = s.find(";");
629  std::string payloadRaw = s.substr(0,pos); //remove padding zeros
630 
631  NS_LOG_FUNCTION(this << "payloadRaw:" << payloadRaw << payloadRaw.size());
632 
633  try{
634 
635  std::string label;
636  nlohmann::json jresponse;
637  jresponse = nlohmann::json::parse(payloadRaw);
638 
639  if (jresponse.contains("ACTION")) label = jresponse["ACTION"];
640  NS_LOG_DEBUG (this << "\tLABEL:\t" << jresponse["ACTION"] << "\tPACKETVALUE:\t" << s);
641 
642  if(label == "ADDKEY"){
643 
644  if(!m_master){
645 
646  std::string keyId;
647  uint32_t keySize = m_keySizeInBits;
648 
649  if (jresponse.contains("size")) keySize = uint32_t(jresponse["size"]);
650  if (jresponse.contains("uuid")) keyId = jresponse["uuid"];
651  if (jresponse.contains("srid")) m_keyId = jresponse["srid"];
652 
653  m_lastUUID = keyId;
654  NS_LOG_FUNCTION( this << "ADDKEY" << keyId );
655  Ptr<QKDKey> newKey = Create<QKDKey> (keyId, m_keyId, keySize);
656  SendPacketToKMS(newKey);
657  m_packetNumber = 0;
658  }
659 
660  }
661 
662  }catch (...){
663  NS_LOG_FUNCTION( this << "!!!!!!!!!!!!!!!!!!!!! JSON parse error! !!!!!!!!!!!!!!!!!!!!! \t"<< payloadRaw << payloadRaw.size());
664  }
665 
666  }
667  SendData();
668  }
669 
670  void QKDPostprocessingApplication::HandleReadSifting (Ptr<Socket> socket)
671  {
672  NS_LOG_FUNCTION (this << socket);
673 
674  if(m_master == true)
675  {
676  NS_LOG_FUNCTION(this << "***MASTER***" );
677  }
678  else
679  {
680  NS_LOG_FUNCTION(this << "!!!SLAVE!!!");
681  }
682 
683  Ptr<Packet> packet;
684  packet = socket->Recv (65535, 0);
685  }
686 
687  void QKDPostprocessingApplication::HandlePeerClose (Ptr<Socket> socket)
688  {
689  NS_LOG_FUNCTION (this << socket);
690  }
691  void QKDPostprocessingApplication::HandlePeerCloseKMS (Ptr<Socket> socket)
692  {
693  NS_LOG_FUNCTION (this << socket);
694  }
695 
696  void QKDPostprocessingApplication::HandlePeerError (Ptr<Socket> socket)
697  {
698  NS_LOG_FUNCTION (this << socket);
699  }
700  void QKDPostprocessingApplication::HandlePeerErrorKMS (Ptr<Socket> socket)
701  {
702  NS_LOG_FUNCTION (this << socket);
703  }
704 
705  void QKDPostprocessingApplication::HandleAccept (Ptr<Socket> s, const Address& from)
706  {
707  NS_LOG_FUNCTION (this << s << from);
708  s->SetRecvCallback (MakeCallback (&QKDPostprocessingApplication::HandleRead, this));
709  m_sinkSocketList.push_back (s);
710  }
711  void QKDPostprocessingApplication::HandleAcceptKMS (Ptr<Socket> s, const Address& from)
712  {
713  NS_LOG_FUNCTION (this << s << from);
714  s->SetRecvCallback (MakeCallback (&QKDPostprocessingApplication::HandleReadKMS, this));
715  }
716  void QKDPostprocessingApplication::HandleAcceptSifting (Ptr<Socket> s, const Address& from)
717  {
718  NS_LOG_FUNCTION (this << s << from);
719  s->SetRecvCallback (MakeCallback (&QKDPostprocessingApplication::HandleReadSifting, this));
720  m_sinkSocketList.push_back (s);
721  }
722 
723  void QKDPostprocessingApplication::ConnectionSucceeded (Ptr<Socket> socket)
724  {
725  NS_LOG_FUNCTION (this << socket);
726  NS_LOG_FUNCTION (this << "QKDPostprocessingApplication Connection succeeded");
727 
728  if (m_sendSocket == socket || m_sinkSocket == socket){
729  m_connected = true;
730 
731  if(m_master) {
732  SendSiftingPacket();
733  SendData();
734  ScheduleNextReset();
735  }
736  }
737  }
738 
739  void QKDPostprocessingApplication::ConnectionSucceededSifting (Ptr<Socket> socket)
740  {
741  NS_LOG_FUNCTION (this << socket);
742  NS_LOG_FUNCTION (this << "QKDPostprocessingApplication SIFTING Connection succeeded");
743  }
744 
745  void QKDPostprocessingApplication::ConnectionFailed (Ptr<Socket> socket)
746  {
747  NS_LOG_FUNCTION (this << socket);
748  NS_LOG_FUNCTION (this << "QKDPostprocessingApplication, Connection Failed");
749  }
750 
751  void QKDPostprocessingApplication::DataSend (Ptr<Socket> socket, uint32_t value)
752  {
753  NS_LOG_FUNCTION (this);
754  }
755 
756 
757 
758 
759  void QKDPostprocessingApplication::ConnectionSucceededKMS (Ptr<Socket> socket)
760  {
761  NS_LOG_FUNCTION (this << socket);
762  NS_LOG_FUNCTION (this << "QKDPostprocessingApplication-KMS Connection succeeded");
763  }
764 
765  void QKDPostprocessingApplication::ConnectionFailedKMS (Ptr<Socket> socket)
766  {
767  NS_LOG_FUNCTION (this << socket);
768  NS_LOG_FUNCTION (this << "QKDPostprocessingApplication-KMS Connection Failed");
769  }
770 
771  void QKDPostprocessingApplication::DataSendKMS (Ptr<Socket> socket, uint32_t value)
772  {
773  NS_LOG_FUNCTION (this);
774  }
775 
776 
777 
778 
779 
780  void QKDPostprocessingApplication::RegisterAckTime (Time oldRtt, Time newRtt)
781  {
782  NS_LOG_FUNCTION (this << oldRtt << newRtt);
783  m_lastAck = Simulator::Now ();
784  }
785 
786  Time QKDPostprocessingApplication::GetLastAckTime ()
787  {
788  NS_LOG_FUNCTION (this);
789  return m_lastAck;
790  }
791 
792  std::string
793  QKDPostprocessingApplication::GenerateRandomString(const int len) {
794  std::string tmp_s;
795  static const char alphanum[] =
796  "0123456789"
797  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
798  "abcdefghijklmnopqrstuvwxyz";
799 
800  uint32_t randVal = 0;
801  for (int i = 0; i < len; ++i){
802  randVal = round(m_random->GetValue (0, sizeof(alphanum) - 1));
803  tmp_s += alphanum[ randVal ];
804  }
805  return tmp_s;
806  }
807 
808 } // Namespace ns3
a polymophic address class
Definition: address.h:101
The base class for all ns3 applications.
Definition: application.h:62
void DoDispose() override
Destructor implementation.
Definition: application.cc:86
Ptr< Node > GetNode() const
Definition: application.cc:108
Class for representing data rates.
Definition: data-rate.h:89
an Inet address class
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
static Ipv4Address GetAny()
Implement the IPv4 layer.
uint32_t GetId() const
Definition: node.cc:117
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:315
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
void HandleRead(Ptr< Socket > socket)
Handle a packet received from the peer application.
void HandleAccept(Ptr< Socket > socket, const Address &from)
Handle an incoming connection from the application.
std::list< Ptr< Socket > > m_sinkSocketList
the accepted sockets
void StartApplication(void)
Start the post-processing application.
Ptr< Socket > GetSinkSocket(void) const
Get the sink socket.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTraceKMS
Ptr< Node > GetSrc()
Get the source node.
uint64_t m_keyId
ID counter of generated keys.
Ptr< Node > GetDst()
Get the destination node.
std::list< Ptr< Socket > > GetAcceptedSockets(void) const
Get the list of the accepted sockets.
Address m_peer_sifting
Peer address for sifting.
std::string GenerateRandomString(const int len)
Generate a random string with a given length.
uint32_t m_maxPackets_sifting
Limitation for the number of sifting packets.
void SetSiftingSocket(std::string type, Ptr< Socket > socket)
Set the sifting socket.
void HandlePeerError(Ptr< Socket > socket)
Handle a connection error from the peer application.
Ptr< Socket > m_sendSocket_sifting
Sockets used for SIFTING.
DataRate m_dataRate
Rate that data is generatedm_pktSize.
Ptr< Socket > m_sinkSocket_sifting
Associated socket for sifting.
void SetSocket(std::string type, Ptr< Socket > socket, bool isMaster)
Set the socket.
TracedCallback< Ptr< const Packet > > m_txTrace
static TypeId GetTypeId(void)
Get the type ID.
void GenerateRandomKeyId()
Generate a random seed that will be used to generate key values.
Address m_local_sifting
Local address for sifting to bind to.
Address m_local
Local address to bind to.
std::string m_appId
Random string marking the app ID.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTrace
Traced Callback: received packets, source address.
EventId m_sendEvent
Event id of pending "send packet" event.
Ptr< UniformRandomVariable > m_random
The uniform random variable.
Ptr< Socket > m_sendSocket
IMITATE post-processing traffic (CASCADE, PRIVACY AMPLIFICATION and etc.
Ptr< Socket > m_sinkSocket
Associated socket.
uint32_t GetTotalRx() const
Get the total amount of data received (in bytes).
void SetSrc(Ptr< Node >)
Set the source node.
TracedCallback< Ptr< const Packet > > m_txTraceKMS
uint32_t m_keySizeInBits
KeyRate of the QKDlink.
virtual void DoDispose(void)
Destructor implementation.
uint32_t m_packetNumber_sifting
How many sifting packets have been sent.
Ptr< Socket > GetSendSocket(void) const
Get the send socket.
void HandlePeerClose(Ptr< Socket > socket)
Handle a connection close from the peer application.
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:285
void SetCloseCallbacks(Callback< void, Ptr< Socket >> normalClose, Callback< void, Ptr< Socket >> errorClose)
Detect socket recv() events such as graceful shutdown or error.
Definition: socket.cc:96
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
Definition: socket.cc:105
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
virtual int ShutdownSend()=0
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:72
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int Listen()=0
Listen for incoming connections.
static TypeId GetTypeId()
Get the type ID.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
static TypeId GetTypeId()
Get the type ID.
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:747
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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:46
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.
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:704
Ptr< const AttributeChecker > MakeTypeIdChecker()
Definition: type-id.cc:1250
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Definition: type-id.h:598
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46