A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
qkd-postprocessing-application.cc
Go to the documentation of this file.
1/*
2 * Copyright(c) 2020 DOTFEESA www.tk.etf.unsa.ba
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 *
7 *
8 * Author: Miralem Mehic <miralem.mehic@ieee.org>
9 */
10#include <bitset>
11#include <sstream>
12#include <iomanip>
13#include "ns3/address.h"
14#include "ns3/node.h"
15#include "ns3/nstime.h"
16#include "ns3/socket.h"
17#include "ns3/simulator.h"
18#include "ns3/packet.h"
19#include "ns3/uinteger.h"
20#include "ns3/trace-source-accessor.h"
21#include "http.h"
23#include <iostream>
24#include <fstream>
25#include <string>
26#include <random>
27
28namespace ns3 {
29
30 NS_LOG_COMPONENT_DEFINE("QKDPostprocessingApplication");
31
32
33 NS_OBJECT_ENSURE_REGISTERED(QKDPostprocessingApplication);
34
35 TypeId
37 {
38 static TypeId tid = TypeId("ns3::QKDPostprocessingApplication")
40 .SetGroupName("Applications")
41 .AddConstructor<QKDPostprocessingApplication>()
42 .AddAttribute("KeySize", "The amount of data to be added to QKD Buffer(in bytes).",
43 UintegerValue(8092),
46 .AddAttribute("KeyRate", "The average QKD key rate.",
47 DataRateValue(DataRate("100kbps")),
50 .AddAttribute("DataRate", "The average data rate of communication.",
51 DataRateValue(DataRate("650kbps")), //3.3Mbps //10kbps
54 .AddAttribute("PacketSize", "The size of packets sent in post-processing state",
55 UintegerValue(320), //280
58 .AddAttribute("MaxSiftingPackets", "The size of packets sent in sifting state",
59 UintegerValue(5), ///190
62
63 .AddAttribute("Protocol", "The type of protocol to use(TCP by default).",
67 .AddAttribute("ProtocolSifting", "The type of protocol to use for sifting(UDP by default).",
71
72 .AddAttribute("Remote", "The address of the destination",
76 .AddAttribute("Local", "The local address on which to bind the listening socket.",
80 .AddAttribute("Remote_Sifting", "The address of the destination for sifting traffic.",
84 .AddAttribute("Local_Sifting", "The local address on which to bind the listening sifting socket.",
88 .AddAttribute("Local_KMS", "The local KSM address.",
92 .AddTraceSource("Tx", "A new packet is created and is sent",
94 "ns3::QKDPostprocessingApplication::Tx")
95 .AddTraceSource("Rx", "A packet has been received",
97 "ns3::QKDPostprocessingApplication::Rx")
98 .AddTraceSource("TxKMS", "A new packet is created and is sent to LKMS",
100 "ns3::QKDPostprocessingApplication::TxKMS")
101 .AddTraceSource("RxKMS", "A packet has been received from LKMS",
103 "ns3::QKDPostprocessingApplication::RxLKMS")
104 ;
105 return tid;
106 }
107
109
122
127
128
129// Convert binary bits to byte string
130std::string bitsToBytes(const std::string& bits) {
131 std::string bytes;
132 size_t padding =(8 -(bits.length() % 8)) % 8;
133 std::string padded = bits + std::string(padding, '0');
134
135 for(size_t i = 0; i < padded.length(); i += 8) {
136 bytes += static_cast<char>(std::bitset<8>(padded.substr(i, 8)).to_ulong());
137 }
138
139 return bytes;
140}
141
142 void
146
147
153
158
159 void
161 NS_LOG_FUNCTION(this << node->GetId());
162 m_src = node;
163 }
164
169
170 void
172 NS_LOG_FUNCTION(this << node->GetId());
173 m_dst = node;
174 }
175
176 std::list<Ptr<Socket> >
182
189
196
197 void
199 {
200 NS_LOG_FUNCTION(this << type << socket << isMaster);
201 if(type == "send")//send app
202 m_sendSocket = socket;
203 else // sink app
204 m_sinkSocket = socket;
205
207 }
208
209 void
211 {
212 NS_LOG_FUNCTION(this << type << socket);
213 if(type == "send")//send app
214 m_sendSocket_sifting = socket;
215 else // sink app
216 m_sinkSocket_sifting = socket;
217 }
218
219 void
221 {
222 NS_LOG_FUNCTION(this);
223
224 m_sendSocket = nullptr;
225 m_sinkSocket = nullptr;
226 m_sendSocket_sifting = nullptr;
227 m_sinkSocket_sifting = nullptr;
228
229 m_sinkSocketList.clear();
231 // chain up
233 }
234
235 // Application Methods
236 void
238 {
239 NS_LOG_FUNCTION(this << "\nQKD module ID:" << GetId() << ";\nMatching QKD module ID:" << GetPeerId());
240
241 // SINK socket settings
246 );
247 if(m_sinkSocket->Bind(sinkAddress) == -1) NS_FATAL_ERROR("Failed to bind socket " << m_local);
252 MakeNullCallback<bool, Ptr<Socket>, const Address &>(),
254 );
258 );
259
260 // SEND socket settings
263 uint32_t interface = ipv4->GetInterfaceForAddress( InetSocketAddress::ConvertFrom(m_local).GetIpv4() );
264 Ptr<NetDevice> netDevice = ipv4->GetNetDevice(interface);
265 //m_sendSocket->BindToNetDevice(netDevice);
266 m_sendSocket->ShutdownRecv();
267 m_sendSocket->SetConnectCallback(
268 MakeCallback(&QKDPostprocessingApplication::ConnectionSucceeded, this),
269 MakeCallback(&QKDPostprocessingApplication::ConnectionFailed, this)
270 );
271 m_sendSocket->SetDataSentCallback(
272 MakeCallback(&QKDPostprocessingApplication::DataSend, this)
273 );
274 m_sendSocket->TraceConnectWithoutContext("RTT", MakeCallback(&QKDPostprocessingApplication::RegisterAckTime, this));
275 m_sendSocket->Connect(m_peer);
276
278 this <<
279 "Connecting QKDApp(" <<
280 InetSocketAddress::ConvertFrom(m_peer).GetIpv4() << " port " << InetSocketAddress::ConvertFrom(m_peer).GetPort() <<
281 " from " <<
282 InetSocketAddress::ConvertFrom(m_local).GetIpv4() << " port " << InetSocketAddress::ConvertFrom(m_local).GetPort()
283 );
284
285
286 /**** SIFTING SOCKETS ****/
287 // SINK socket settings
288 if(!m_sinkSocket_sifting) m_sinkSocket_sifting = Socket::CreateSocket(GetNode(), m_tidSifting);
289 if(m_sinkSocket_sifting->Bind(m_local_sifting) == -1) NS_FATAL_ERROR("Failed to bind SIFTING socket " << m_local_sifting);
290 m_sinkSocket_sifting->Listen();
291 m_sinkSocket_sifting->ShutdownSend();
292 m_sinkSocket_sifting->SetRecvCallback(MakeCallback(&QKDPostprocessingApplication::HandleReadSifting, this));
293
294 // SEND socket settings
295 if(!m_sendSocket_sifting) m_sendSocket_sifting = Socket::CreateSocket(GetNode(), m_tidSifting);
296 m_sendSocket_sifting->Connect(m_peer_sifting);
297 m_sendSocket_sifting->ShutdownRecv();
298
299
300 /**** QISKIT SOCKET ****/
301
302 NS_LOG_FUNCTION(
303 this << "BIND QISKIT socket to port " <<
304 InetSocketAddress::ConvertFrom(m_local).GetPort()+50
305 );
306
307 // SINK socket settings
308 if(!m_sinkSocketQiskit) m_sinkSocketQiskit = Socket::CreateSocket(GetNode(), m_tid);
309 InetSocketAddress sinkAddressQiskit = InetSocketAddress(
310 Ipv4Address::GetAny(),
311 //Ipv4Address("192.168.0.8"),
312 InetSocketAddress::ConvertFrom(m_local).GetPort()+50
313 );
314 if(m_sinkSocketQiskit->Bind(sinkAddressQiskit) == -1) NS_FATAL_ERROR("Failed to bind QISKIT socket " << m_local);
315 m_sinkSocketQiskit->Listen();
316 m_sinkSocketQiskit->ShutdownSend();
317 m_sinkSocketQiskit->SetRecvCallback(MakeCallback(&QKDPostprocessingApplication::HandleReadQiskit, this));
318 m_sinkSocketQiskit->SetAcceptCallback(
319 MakeNullCallback<bool, Ptr<Socket>, const Address &>(),
320 MakeCallback(&QKDPostprocessingApplication::HandleAcceptQiskit, this)
321 );
322 m_sinkSocketQiskit->SetCloseCallbacks(
323 MakeCallback(&QKDPostprocessingApplication::HandlePeerCloseQiskit, this),
324 MakeCallback(&QKDPostprocessingApplication::HandlePeerErrorQiskit, this)
325 );
326
327 /**** KMS SOCKETS ****/
328
329 // SEND socket settings
330 if(!m_sendSocketKMS) m_sendSocketKMS = Socket::CreateSocket(GetNode(), m_tid);
331 Ipv4Address localIpv4 = InetSocketAddress::ConvertFrom(m_local).GetIpv4();
332 /*InetSocketAddress senderKMS = InetSocketAddress(
333 InetSocketAddress::ConvertFrom(m_kms).GetIpv4(), //destination address
334 InetSocketAddress::ConvertFrom(m_kms).GetPort() //destination listening port
335 ); */
336
337 //m_sendSocketKMS->Bind(senderKMS);
338 m_sendSocketKMS->Bind();
339 m_sendSocketKMS->ShutdownRecv();
340 m_sendSocketKMS->SetConnectCallback(
341 MakeCallback(&QKDPostprocessingApplication::ConnectionSucceededKMS, this),
342 MakeCallback(&QKDPostprocessingApplication::ConnectionFailedKMS, this));
343 m_sendSocketKMS->SetDataSentCallback(
344 MakeCallback(&QKDPostprocessingApplication::DataSendKMS, this));
345 m_sendSocketKMS->TraceConnectWithoutContext("RTT", MakeCallback(&QKDPostprocessingApplication::RegisterAckTime, this));
346 m_sendSocketKMS->Connect(m_kms);
347
348
349 Address allocatedLocalAddress;
350 m_sendSocketKMS->GetSockName(allocatedLocalAddress);
351 // SINK socket settings
352 Address localAddress = InetSocketAddress(
353 InetSocketAddress::ConvertFrom(m_local).GetIpv4(),
354 InetSocketAddress::ConvertFrom(allocatedLocalAddress).GetPort()+100
355 //82+m_ppId
356 );
357 m_sinkSocketKMS = Socket::CreateSocket(GetNode(), TcpSocketFactory::GetTypeId() );
358 //if(!m_sinkSocketKMS) m_sinkSocketKMS = Socket::CreateSocket(GetNode(), m_tid);
359
360 //uint32_t portKMS = InetSocketAddress::ConvertFrom(m_kms).GetPort();
361 //if(m_sinkSocketKMS->Bind(m_kms) == -1) NS_FATAL_ERROR("Failed to bind socket");
362 if(m_sinkSocketKMS->Bind(localAddress) == -1) NS_FATAL_ERROR("Failed to bind socket");
363 m_sinkSocketKMS->Listen();
364 m_sinkSocketKMS->ShutdownSend();
365 m_sinkSocketKMS->SetRecvCallback(MakeCallback(&QKDPostprocessingApplication::HandleReadKMS, this));
366 m_sinkSocketKMS->SetAcceptCallback(
367 MakeNullCallback<bool, Ptr<Socket>, const Address &>(),
368 MakeCallback(&QKDPostprocessingApplication::HandleAcceptKMS, this));
369 m_sinkSocketKMS->SetCloseCallbacks(
370 MakeCallback(&QKDPostprocessingApplication::HandlePeerCloseKMS, this),
371 MakeCallback(&QKDPostprocessingApplication::HandlePeerErrorKMS, this));
372
374 this <<
375 "Connecting KMS(" <<
376 InetSocketAddress::ConvertFrom(m_kms).GetIpv4() << " port " << InetSocketAddress::ConvertFrom(m_kms).GetPort() <<
377 " from " <<
378 localIpv4 << " port" << InetSocketAddress::ConvertFrom(allocatedLocalAddress).GetPort()
379 );
380 }
381
382 void
383 QKDPostprocessingApplication::StopApplication()
384 {
385 NS_LOG_FUNCTION(this << "\nQKD module ID:" << GetId() << ";\nMatching QKD module ID:" << GetPeerId());
386
387 if(m_sendSocket)
388 m_sendSocket->Close();
389 else
390 NS_LOG_WARN("QKDPostprocessingApplication found null socket to close in StopApplication()!");
391
392 while(!m_sinkSocketList.empty()){ //these are accepted sockets, close them
393 Ptr<Socket> acceptedSocket = m_sinkSocketList.front();
394 m_sinkSocketList.pop_front();
395 acceptedSocket->Close();
396 }
397 if(m_sinkSocket){
398 m_sinkSocket->Close();
399 m_sinkSocket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket> >());
400 }
401
402 m_connected = false;
403 Simulator::Cancel(m_sendEvent);//
404 }
405
406 void
407 QKDPostprocessingApplication::ScheduleNextReset()
408 {
409 //Time nextTime(Seconds(round((m_keySize*8) / static_cast<double>(m_keyRate.GetBitRate())))); // Time till next QKD packet
410 Time nextTime(Seconds((m_keySize*8) / static_cast<double>(m_keyRate.GetBitRate()))); // Time till next QKD packet
411 Simulator::Schedule(nextTime, &QKDPostprocessingApplication::ResetCounter, this);
412
413 NS_LOG_FUNCTION(this << nextTime);
414 }
415
416 void
417 QKDPostprocessingApplication::ResetCounter()
418 {
419 NS_LOG_FUNCTION(this << "Reached packet number:" << m_packetNumber);
420
421 if(m_master) m_packetNumber = 0;
422 if(m_connected){
423 SendSiftingPacket();
424 SendData();
425 ScheduleNextReset();
426 }
427 }
428
429 void
430 QKDPostprocessingApplication::SendData()
431 {
432 if(m_master)
433 NS_LOG_FUNCTION(this << "********************** MASTER **********************");
434 else
435 NS_LOG_FUNCTION(this << "********************** SLAVE **********************");
436
437 NS_LOG_DEBUG(this << "\tSending packet " << m_packetNumber);
438 if(m_packetNumber > 0){
439 nlohmann::json msgBody = {
440 {"ACTION", "QKDPPS"},
441 {"NUMBER", m_packetNumber}
442 };
443 std::string message = msgBody.dump();
444 PrepareOutput(message, "qkdpps");
445
446 }else{
447 NS_LOG_FUNCTION(this << "m_lastUUID:\t" << m_lastUUID);
448
449 std::string keyId;
450 if(m_master){
451 UUID keyIdRaw = UUID::Sequential();
452 keyId = keyIdRaw.string();
453 }else
454 keyId = m_lastUUID;
455
456 if(!keyId.empty())
457 {
458 GenerateRandomKeyId();
459 nlohmann::json msgBody = {
460 {"ACTION", "ADDKEY"},
461 {"size", m_keySize},
462 {"uuid", keyId},
463 {"srid", m_randomSeed}
464 };
465 std::string message = msgBody.dump();
466 PrepareOutput(message, "addkey");
467 //ScheduleNextReset();
468
469 if(m_master && m_connected)
470 {
471
472 // Convert to bytes
473 std::string byteKey = GenerateRandomString(m_keySize);
474 // Convert to Base64 for JSON storage
475 std::string keyValue = m_encryptor->Base64Encode(byteKey);
476
477 NS_LOG_FUNCTION(this << "ADDKEY:" << keyId);
478 NS_LOG_FUNCTION(this << "m_keySize:" << m_keySize);
479 NS_LOG_FUNCTION(this << "byteKey.size():" << byteKey.size());
480 //NS_LOG_FUNCTION(this << "byteKey:" << byteKey);
481 //NS_LOG_FUNCTION(this << "keyValue:" << keyValue);
482
483 StoreKey(keyId, keyValue);
484
485 }
486 }
487
488 }
489 m_packetNumber++;
490
491 }
492
493 void
494 QKDPostprocessingApplication::PrepareOutput(std::string value, std::string action)
495 {
496 NS_LOG_FUNCTION(this << Simulator::Now() << action);
497
498 if(static_cast<double>(m_dataRate.GetBitRate()) > 0 && m_pktSize > 0)
499 {
500 std::ostringstream msg;
501 msg << value << ";";
502 //Playing with packet size to introduce some randomness
503 msg << std::string(m_random->GetValue(m_pktSize, m_pktSize*1.1), '0');
504 msg << '\0';
505
506 Ptr<Packet> packet = Create<Packet>((uint8_t*) msg.str().c_str(), msg.str().length());
507 NS_LOG_DEBUG(this << "\t!!!SENDING PACKET WITH CONTENT:" << value << " of size " << packet->GetSize());
508
509 uint32_t bits = packet->GetSize() * 8;
510 NS_LOG_LOGIC(this << "bits = " << bits);
511
512 if(action == "qkdpps"){
513 Time nextTime(Seconds(bits / static_cast<double>(m_dataRate.GetBitRate()))); // Time till next packet
514 NS_LOG_FUNCTION(this << "CALCULATED NEXTTIME:" << bits / m_dataRate.GetBitRate());
515 NS_LOG_LOGIC("nextTime = " << nextTime);
516 m_sendEvent = Simulator::Schedule(nextTime, &QKDPostprocessingApplication::SendPacket, this, packet);
517
518 }else if(action == "addkey")
519 SendPacket(packet);
520 }
521 }
522
523
524 void
525 QKDPostprocessingApplication::SendPacket(Ptr<Packet> packet)
526 {
527 NS_LOG_FUNCTION(this << "\t" << packet << "PACKETID: " << packet->GetUid() << packet->GetSize());
528 if(m_connected){
529 m_txTrace(packet);
530 m_sendSocket->Send(packet);
531 }
532 }
533
534 void
535 QKDPostprocessingApplication::StoreKey(std::string keyId, std::string keyValue)
536 {
537 NS_LOG_FUNCTION(this << keyId);
538 nlohmann::json msgBody = {
539 {"qkd_module_ID", GetId()},
540 {"matching_qkd_module_ID", GetPeerId()},
541 {"key_ID", keyId},
542 {"key", keyValue}
543 };
544 std::string msg = msgBody.dump();
545
546 std::string headerUri = "http://" + GetStringAddress(m_kms) + "/api/v1/keys/" + GetPeerId() + "/store_key";
547
548 NS_LOG_FUNCTION(this <<"aaaa:" << headerUri);
549 HTTPMessage httpMessage;
550 httpMessage.CreateRequest(headerUri, "POST", msg);
551 httpMessage.SetHeader("User-Agent", "QKDModule_" + GetId());
552 std::string hMessage = httpMessage.ToString();
553 Ptr<Packet> packet = Create<Packet>(
554 (uint8_t*)(hMessage).c_str(),
555 hMessage.size()
556 );
557 NS_ASSERT(packet);
558
559 NS_LOG_FUNCTION(this << "Sending PACKETID: "
560 << packet->GetUid()
561 << " of size: " << packet->GetSize()
562 << " method name:" << "store_key"
563 << " key_id: " << keyId
564 << " via socket " << m_sendSocketKMS
565 << httpMessage.GetUri()
566 << " of msg " << msg
567 );
568
569 m_txTraceKMS(packet);
570 m_sendSocketKMS->Send(packet);
571
572 }
573
574 std::string
575 QKDPostprocessingApplication::GetStringAddress(Address m_address)
576 {
577 NS_LOG_FUNCTION(this << m_address);
578 Ipv4Address ipv4Adr = InetSocketAddress::ConvertFrom(m_address).GetIpv4();
579 std::ostringstream ipv4AdrTemp;
580 ipv4Adr.Print(ipv4AdrTemp); //IPv4Address to string
581
582 return ipv4AdrTemp.str();
583 }
584
585 void
586 QKDPostprocessingApplication::SendSiftingPacket()
587 {
588 NS_LOG_FUNCTION(this);
589
590 Ptr<Packet> packet = Create<Packet>( uint32_t(800 + m_random->GetValue(100, 300)) );
591 m_sendSocket_sifting->Send(packet);
592 NS_LOG_FUNCTION(this << "Sending SIFTING packet" << "PACKETID: " << packet->GetUid() << " of size: " << packet->GetSize());
593
594 m_packetNumber_sifting++;
595 if(m_packetNumber_sifting < m_maxPackets_sifting)
596 Simulator::Schedule(MicroSeconds(400), &QKDPostprocessingApplication::SendSiftingPacket, this);
597 else
598 m_packetNumber_sifting = 0;
599 }
600
601 void
602 QKDPostprocessingApplication::HandleReadKMS(Ptr<Socket> socket)
603 {
604 if(m_master)
605 NS_LOG_FUNCTION(this << "--------------MASTER--------------");
606 else
607 NS_LOG_FUNCTION(this << "--------------SLAVE--------------");
608
609 Ptr<Packet> packet;
610 Address from;
611 while((packet = socket->RecvFrom(from))){
612
613 if(packet->GetSize() == 0) break; //EOF
614
615 NS_LOG_FUNCTION(this << packet << "PACKETID: " << packet->GetUid() << " of size: " << packet->GetSize() );
616
617 m_totalRx += packet->GetSize();
618 if(InetSocketAddress::IsMatchingType(from))
619 NS_LOG_FUNCTION(this << "At time " << Simulator::Now().GetSeconds()
620 << "s packet sink received "
621 << packet->GetSize() << " bytes from "
622 << InetSocketAddress::ConvertFrom(from).GetIpv4()
623 << " port " << InetSocketAddress::ConvertFrom(from).GetPort()
624 << " total Rx " << m_totalRx << " bytes");
625 m_rxTraceKMS(packet, from);
626
627 }
628 }
629
630 void
631 QKDPostprocessingApplication::HandleReadQiskit(Ptr<Socket> socket)
632 {
633 if(m_master)
634 NS_LOG_FUNCTION(this << "--------------MASTER--------------");
635 else
636 NS_LOG_FUNCTION(this << "--------------SLAVE--------------");
637
638 Ptr<Packet> packet;
639 Address from;
640 while((packet = socket->RecvFrom(from)))
641 {
642 if(packet->GetSize() == 0) break; //EOF
643
644 NS_LOG_FUNCTION(this << packet << "PACKETID: " << packet->GetUid() << " of size: " << packet->GetSize() );
645 PacketReceived(packet, from, socket);
646 }
647 }
648void
649QKDPostprocessingApplication::PacketReceived(const Ptr<Packet> &p, const Address &from, Ptr<Socket> socket)
650{
651 NS_LOG_FUNCTION(this << p->GetUid() << p->GetSize() << from);
652
653 // Maintain per-sender buffer
654 Ptr<Packet> &buffer = m_buffer[from];
655 if (!buffer) buffer = Create<Packet>(0);
656 buffer->AddAtEnd(p);
657 NS_LOG_DEBUG("Buffer after append: " << buffer->GetSize());
658
659 HTTPMessageParser parser;
660 while (buffer->GetSize() > 0) {
661 // Copy buffer to string
662 std::string bufferStr(buffer->GetSize(), '\0');
663 buffer->CopyData(reinterpret_cast<uint8_t*>(&bufferStr[0]), bufferStr.size());
664
665 std::string httpMessageStr;
666 size_t httpMessageSize = 0;
667
668 if (!parser.TryExtractHttpMessage(bufferStr, httpMessageStr, httpMessageSize)) {
669 NS_LOG_DEBUG("[DEBUG] Incomplete or fragmented HTTP message. Awaiting more data.");
670 break;
671 }
672
673 // Parse HTTP message
674 HTTPMessage request;
675 parser.Parse(&request, httpMessageStr);
676
677 if (request.IsFragmented() || request.GetSize() == 0) {
678 NS_LOG_WARN("[WARN] Fragmented or malformed HTTP message. Waiting...");
679 break;
680 }
681
682 // Process complete HTTP packet
683 Ptr<Packet> completePacket = buffer->CreateFragment(0, static_cast<uint32_t>(httpMessageSize));
684 buffer->RemoveAtStart(static_cast<uint32_t>(httpMessageSize));
685
686 NS_LOG_DEBUG("[DEBUG] Processing Qiskit request, size: " << httpMessageSize);
687 ProcessQiskitRequest(request, completePacket, socket);
688 }
689}
690
691
692
693
694 void
695 QKDPostprocessingApplication::ProcessQiskitRequest(HTTPMessage headerIn, Ptr<Packet> packet, Ptr<Socket> socket)
696 {
697 NS_LOG_FUNCTION(this << headerIn.GetUri() << packet->GetUid());
698 NS_ASSERT(!headerIn.GetUri().empty());
699
700 std::string payloadRaw = headerIn.GetMessageBodyString(); //Read payload
701 if(!payloadRaw.empty()){
702 std::string label;
703 nlohmann::json jresponse;
704 try{
705 jresponse = nlohmann::json::parse(payloadRaw);
706 }catch(...){
707 NS_FATAL_ERROR(this << "JSON parse error!");
708 }
709
710 if(jresponse.contains("ACTION")) label = jresponse["ACTION"];
711 NS_LOG_DEBUG(this << "\tLABEL:\t" << label << "\tPACKETVALUE:\t" << socket);
712
713 if(label == "SAVEQISKITKEY")
714 {
715 //if(!m_master){
716
717 std::string keyId;
718 std::string keyValueBits;
719 std::string keyValue;
720 if(jresponse.contains("keyid")) keyId = jresponse["keyid"];
721 if(jresponse.contains("keyvalue")) keyValueBits = jresponse["keyvalue"];
722
723 NS_LOG_FUNCTION(this << "SAVEQISKITKEY" << keyId);
724
725 // Convert to bytes
726 std::string byteKey = bitsToBytes(keyValueBits);
727
728 // Convert to Base64 for JSON storage
729 keyValue = m_encryptor->Base64Encode(byteKey);
730
731 if(!keyId.empty() && !keyValue.empty())
732 StoreKey(keyId, keyValue);
733
734 //create packet
735 HTTPMessage httpMessage;
736 httpMessage.CreateResponse(HTTPMessage::HttpStatus::Ok, "", {
737 {"Content-Type", "application/json; charset=utf-8"},
738 {"Request URI", headerIn.GetUri() }
739 });
740 std::string hMessage = httpMessage.ToString();
741 Ptr<Packet> packetR = Create<Packet>(
742 (uint8_t*)(hMessage).c_str(),
743 hMessage.size()
744 );
745 socket->Send(packetR);
746
747
748 //}
749 }
750 }
751}
752
753
754
755
756
757
758
759
760
761
762
763
764 void
765 QKDPostprocessingApplication::HandleRead(Ptr<Socket> socket)
766 {
767 if(m_master)
768 NS_LOG_FUNCTION(this << "--------------MASTER--------------");
769 else
770 NS_LOG_FUNCTION(this << "--------------SLAVE--------------");
771
772 Ptr<Packet> packet;
773 Address from;
774 while((packet = socket->RecvFrom(from))){
775
776 if(packet->GetSize() == 0) break; //EOF
777
778 NS_LOG_FUNCTION(this << packet << "PACKETID: " << packet->GetUid() << " of size: " << packet->GetSize() );
779
780 m_totalRx += packet->GetSize();
781 if(InetSocketAddress::IsMatchingType(from))
782 NS_LOG_FUNCTION(this << "At time " << Simulator::Now().GetSeconds()
783 << "s packet sink received "
784 << packet->GetSize() << " bytes from "
785 << InetSocketAddress::ConvertFrom(from).GetIpv4()
786 << " port " << InetSocketAddress::ConvertFrom(from).GetPort()
787 << " total Rx " << m_totalRx << " bytes");
788
789
790 m_rxTrace(packet, from);
791 if(!m_master) ProcessIncomingPacket(packet);
792
793 }
794 }
795
796
797 void
798 QKDPostprocessingApplication::ProcessIncomingPacket(Ptr<Packet> packet)
799 {
800 /**
801 * POST PROCESSING
802 */
803 uint8_t *buffer = new uint8_t[packet->GetSize()];
804 packet->CopyData(buffer, packet->GetSize());
805 std::string s = std::string((char*)buffer);
806 delete[] buffer;
807
808 if(s.size() > 5){
809
810 NS_LOG_FUNCTION(this << "payload:" << s);
811 std::size_t pos = s.find(";");
812 std::string payloadRaw = s.substr(0,pos); //remove padding zeros
813 NS_LOG_FUNCTION(this << "payloadRaw:" << payloadRaw);
814
815 std::string label;
816 nlohmann::json jresponse;
817 try{
818 jresponse = nlohmann::json::parse(payloadRaw);
819 }catch(...){
820 NS_FATAL_ERROR(this << "JSON parse error!");
821 }
822
823 if(jresponse.contains("ACTION")) label = jresponse["ACTION"];
824 NS_LOG_DEBUG(this << "\tLABEL:\t" << jresponse["ACTION"] << "\tPACKETVALUE:\t" << s);
825
826 if(label == "ADDKEY"){
827
828 if(!m_master){
829 uint32_t keySize = m_keySize;
830 if(jresponse.contains("size")) keySize = uint32_t(jresponse["size"]);
831 if(jresponse.contains("uuid")) m_lastUUID = jresponse["uuid"];
832 if(jresponse.contains("srid")) m_randomSeed = jresponse["srid"];
833
834 NS_LOG_FUNCTION(this << "ADDKEY" << m_lastUUID);
835
836 // Convert to bytes
837 std::string byteKey = GenerateRandomString(keySize);
838 // Convert to Base64 for JSON storage
839 std::string keyValue = m_encryptor->Base64Encode(byteKey);
840
841 StoreKey(m_lastUUID, keyValue);
842 m_packetNumber = 0;
843 }
844
845 }
846 }
847 SendData();
848 }
849
850 void
851 QKDPostprocessingApplication::HandleReadSifting(Ptr<Socket> socket)
852 {
853 NS_LOG_FUNCTION(this << socket);
854
855 if(m_master)
856 NS_LOG_FUNCTION(this << "***MASTER***" );
857 else
858 NS_LOG_FUNCTION(this << "!!!SLAVE!!!");
859
860 Ptr<Packet> packet;
861 packet = socket->Recv(65535, 0);
862 }
863
864 void
865 QKDPostprocessingApplication::HandlePeerClose(Ptr<Socket> socket)
866 {
867 NS_LOG_FUNCTION(this << socket);
868 }
869
870 void
871 QKDPostprocessingApplication::HandlePeerCloseKMS(Ptr<Socket> socket)
872 {
873 NS_LOG_FUNCTION(this << socket);
874 }
875
876 void
877 QKDPostprocessingApplication::HandlePeerCloseQiskit(Ptr<Socket> socket)
878 {
879 NS_LOG_FUNCTION(this << socket);
880 }
881
882 void
883 QKDPostprocessingApplication::HandlePeerError(Ptr<Socket> socket)
884 {
885 NS_LOG_FUNCTION(this << socket);
886 }
887
888 void
889 QKDPostprocessingApplication::HandlePeerErrorQiskit(Ptr<Socket> socket)
890 {
891 NS_LOG_FUNCTION(this << socket);
892 }
893
894
895 void
896 QKDPostprocessingApplication::HandlePeerErrorKMS(Ptr<Socket> socket)
897 {
898 NS_LOG_FUNCTION(this << socket);
899 }
900
901 void
902 QKDPostprocessingApplication::HandleAccept(Ptr<Socket> s, const Address& from)
903 {
904 NS_LOG_FUNCTION(this << s << from);
905 s->SetRecvCallback(MakeCallback(&QKDPostprocessingApplication::HandleRead, this));
906 m_sinkSocketList.push_back(s);
907 }
908
909 void
910 QKDPostprocessingApplication::HandleAcceptKMS(Ptr<Socket> s, const Address& from)
911 {
912 NS_LOG_FUNCTION(this << s << from);
913 s->SetRecvCallback(MakeCallback(&QKDPostprocessingApplication::HandleReadKMS, this));
914 }
915
916 void
917 QKDPostprocessingApplication::HandleAcceptQiskit(Ptr<Socket> s, const Address& from)
918 {
919 NS_LOG_FUNCTION(this << s << from);
920 s->SetRecvCallback(MakeCallback(&QKDPostprocessingApplication::HandleReadQiskit, this));
921 }
922
923 void
924 QKDPostprocessingApplication::HandleAcceptSifting(Ptr<Socket> s, const Address& from)
925 {
926 NS_LOG_FUNCTION(this << s << from);
927 s->SetRecvCallback(MakeCallback(&QKDPostprocessingApplication::HandleReadSifting, this));
928 m_sinkSocketList.push_back(s);
929 }
930
931 void
932 QKDPostprocessingApplication::ConnectionSucceeded(Ptr<Socket> socket)
933 {
934 NS_LOG_FUNCTION(this << socket);
935 NS_LOG_FUNCTION(this << "QKDPostprocessingApplication Connection succeeded");
936
937 if(m_sendSocket == socket || m_sinkSocket == socket){
938 m_connected = true;
939
940 if(m_master){
941
942 NS_LOG_FUNCTION(this << "m_master:" << m_master);
943 NS_LOG_FUNCTION(this << "m_dataRate.GetBitRate():" << m_dataRate.GetBitRate());
944 NS_LOG_FUNCTION(this << "m_pktSize:" << m_pktSize);
945
946 if(static_cast<double>(m_dataRate.GetBitRate()) > 0 && m_pktSize > 0)
947 {
948 SendSiftingPacket();
949 SendData();
950 ScheduleNextReset();
951 }
952 }
953 }
954 }
955
956 void
957 QKDPostprocessingApplication::ConnectionSucceededSifting(Ptr<Socket> socket)
958 {
959 NS_LOG_FUNCTION(this << socket);
960 NS_LOG_FUNCTION(this << "QKDPostprocessingApplication SIFTING Connection succeeded");
961 }
962
963 void
964 QKDPostprocessingApplication::ConnectionFailed(Ptr<Socket> socket)
965 {
966 NS_LOG_FUNCTION(this << socket);
967 NS_LOG_FUNCTION(this << "QKDPostprocessingApplication, Connection Failed");
968 }
969
970 void
971 QKDPostprocessingApplication::DataSend(Ptr<Socket> socket, uint32_t value)
972 {
973 NS_LOG_FUNCTION(this);
974 }
975
976 void
977 QKDPostprocessingApplication::ConnectionSucceededKMS(Ptr<Socket> socket)
978 {
979 NS_LOG_FUNCTION(this << socket);
980 NS_LOG_FUNCTION(this << "QKDPostprocessingApplication-KMS Connection succeeded");
981 }
982
983 void
984 QKDPostprocessingApplication::ConnectionFailedKMS(Ptr<Socket> socket)
985 {
986 NS_LOG_FUNCTION(this << socket);
987 NS_LOG_FUNCTION(this << "QKDPostprocessingApplication-KMS Connection Failed");
988 }
989
990 void
991 QKDPostprocessingApplication::DataSendKMS(Ptr<Socket> socket, uint32_t value)
992 {
993 NS_LOG_FUNCTION(this);
994 }
995
996 void
997 QKDPostprocessingApplication::RegisterAckTime(Time oldRtt, Time newRtt)
998 {
999 NS_LOG_FUNCTION(this << oldRtt << newRtt);
1000 m_lastAck = Simulator::Now();
1001 }
1002
1003 Time
1004 QKDPostprocessingApplication::GetLastAckTime()
1005 {
1006 NS_LOG_FUNCTION(this);
1007 return m_lastAck;
1008 }
1009
1010 std::string
1011 QKDPostprocessingApplication::GenerateRandomString(const int len) {
1012
1013 NS_LOG_FUNCTION( this << len );
1014
1015 std::string tmp_s;
1016 static const char alphanum[] =
1017 "0123456789"
1018 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1019 "abcdefghijklmnopqrstuvwxyz";
1020 //srand( m_internalID );
1021 for(int i = 0; i < len; ++i){
1022 tmp_s += alphanum[rand() %(sizeof(alphanum) - 1)];
1023 }
1024 return tmp_s;
1025 }
1026
1027} // Namespace ns3
a polymophic address class
Definition address.h:90
AttributeValue implementation for Address.
Definition address.h:275
The base class for all ns3 applications.
Definition application.h:51
void DoDispose() override
Destructor implementation.
Ptr< Node > GetNode() const
Class for representing data rates.
Definition data-rate.h:78
AttributeValue implementation for DataRate.
Definition data-rate.h:285
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.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
QKDPostprocessingApplication is a class used to generate QKD key in key establishment process.
Ptr< Socket > m_sinkSocketKMS
Associated socket.
void HandleRead(Ptr< Socket > socket)
Handle a packet received by the application.
std::list< Ptr< Socket > > GetAcceptedSockets() const
void HandleAccept(Ptr< Socket > socket, const Address &from)
Handle an incoming connection.
std::list< Ptr< Socket > > m_sinkSocketList
the accepted sockets
void StartApplication() override
Called at time specified by Start.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTraceKMS
Ptr< Node > GetSrc()
pointer to associated source node
Ptr< Socket > GetSinkSocket() const
set the sink socket
Ptr< Node > GetDst()
pointer to associated destination node
Address m_peer_sifting
Peer address for sifting.
uint32_t m_maxPackets_sifting
Limitation for the number of sifting packets.
void SetSiftingSocket(std::string type, Ptr< Socket > socket)
uint64_t m_randomSeed
Random seed used when generating key values.
void HandlePeerError(Ptr< Socket > socket)
Handle an connection error KMS.
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)
void DoDispose() override
Destructor implementation.
TracedCallback< Ptr< const Packet > > m_txTrace
void GenerateRandomKeyId()
Generate Random Seed Used to Generate Key Values.
Address m_local_sifting
Local address for sifting to bind to.
std::string GetPeerId()
Get matching QKD module 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< Socket > m_sendSocket
IMITATE post-processing traffic(CASCADE, PRIVACY AMPLIFICATION and etc.
TracedCallback< Ptr< const Packet > > m_txTraceKMS
uint32_t m_packetNumber_sifting
How many sifting packets have been sent.
void HandlePeerClose(Ptr< Socket > socket)
Handle an connection close.
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:274
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:94
virtual int ShutdownSend()=0
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:85
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition socket.cc:117
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:61
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:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
AttributeValue implementation for TypeId.
Definition type-id.h:641
static TypeId GetTypeId()
Get the type ID.
Hold an unsigned integer type.
Definition uinteger.h:34
Callback< R, Args... > MakeNullCallback()
Definition callback.h:727
#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_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
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.
Ptr< const AttributeAccessor > MakeDataRateAccessor(T1 a1)
Definition data-rate.h:285
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
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Ptr< const AttributeChecker > MakeAddressChecker()
Definition address.cc:169
Ptr< const AttributeChecker > MakeDataRateChecker()
Definition data-rate.cc:20
Ptr< const AttributeChecker > MakeTypeIdChecker()
Definition type-id.cc:1335
std::string bitsToBytes(const std::string &bits)
Ptr< const AttributeAccessor > MakeAddressAccessor(T1 a1)
Definition address.h:275
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Definition type-id.h:641