A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
qkd-app-014.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: Emir Dervisevic <emir.dervisevic@etf.unsa.ba>
9 * Miralem Mehic <miralem.mehic@ieee.org>
10 */
11
12#include "ns3/address.h"
13#include "ns3/address-utils.h"
14#include "ns3/log.h"
15#include "ns3/inet-socket-address.h"
16#include "ns3/inet6-socket-address.h"
17#include "ns3/node.h"
18#include "ns3/socket.h"
19#include "ns3/udp-socket-factory.h"
20#include "ns3/tcp-socket-factory.h"
21#include "ns3/simulator.h"
22#include "ns3/socket-factory.h"
23#include "ns3/packet.h"
24#include "ns3/trace-source-accessor.h"
25#include "qkd-app-014.h"
26
27namespace ns3 {
28
29NS_LOG_COMPONENT_DEFINE("QKDApp014");
30
32
33TypeId
35{
36 static TypeId tid = TypeId("ns3::QKDApp014")
38 .SetGroupName("Applications")
39 .AddConstructor<QKDApp014>()
40 .AddAttribute("Protocol", "The type of protocol to use.",
44 .AddAttribute("NumberOfKeyToFetchFromKMS",
45 "The total number of keys per request to LKMS(ESTI QKD 014)",
49 .AddAttribute("LengthOfAuthenticationTag",
50 "The default length of the authentication tag",
51 UintegerValue(256), //32 bytes
54 .AddAttribute("EncryptionType",
55 "The type of encryption to be used(0-unencrypted, 1-OTP, 2-AES)",
59 .AddAttribute("AuthenticationType",
60 "The type of authentication to be used(0-unauthenticated, 1-VMAC, 2-MD5, 3-SHA1)",
64 .AddAttribute("AESLifetime",
65 "Lifetime of AES key expressed in number of packets",
69 .AddAttribute("UseCrypto",
70 "Should crypto functions be performed(0-No, 1-Yes)",
74 .AddAttribute("WaitInsufficient","Penalty time(in seconds) when there is insufficient amount of key",
75 TimeValue(Seconds(0.3)),
78
79 .AddTraceSource("Tx", "A new packet is created and is sent",
81 "ns3::Packet::TracedCallback")
82 .AddTraceSource("TxSig", "A new signaling packet is created and is sent",
84 "ns3::Packet::TracedCallback")
85 .AddTraceSource("TxKMS", "A new packet is created and is sent to local KMS",
87 "ns3::Packet::TracedCallback")
88 .AddTraceSource("Rx", "A new packet is received",
90 "ns3::Packet::TracedCallback")
91 .AddTraceSource("RxSig", "A new signaling packet is received",
93 "ns3::Packet::TracedCallback")
94 .AddTraceSource("RxKMS", "A new packet is received from local KMS",
96 "ns3::Packet::TracedCallback")
97 .AddTraceSource("StateTransition",
98 "Trace fired upon every QKDApp014 state transition.",
100 "ns3::Application::StateTransitionCallback")
101 .AddTraceSource("PacketEncrypted",
102 "The change trance for currenly ecrypted packet",
104 "ns3::QKDCrypto::PacketEncrypted")
105 .AddTraceSource("PacketDecrypted",
106 "The change trance for currenly decrypted packet",
108 "ns3::QKDCrypto::PacketDecrypted")
109 .AddTraceSource("PacketAuthenticated",
110 "The change trance for currenly authenticated packet",
112 "ns3::QKDCrypto::PacketAuthenticated")
113 .AddTraceSource("PacketDeAuthenticated",
114 "The change trance for currenly deauthenticated packet",
116 "ns3::QKDCrypto::PacketDeAuthenticated")
117 .AddTraceSource("Mx", "Missed send packet call",
119 "ns3::Packet::TracedCallback")
120 ;
121
122 return tid;
123}
124//@toDo: add use fallback to AES when OTP is used(Y/N)
125
127
128/**
129 * ********************************************************************************************
130
131 * SETUP
132
133 * ********************************************************************************************
134 */
135
137 : m_signalingSocketApp(nullptr),
138 m_dataSocketApp(nullptr),
139 m_socketToKMS(nullptr),
140 m_state(NOT_STARTED),
141 m_master(0),
142 m_size(0),
143 m_rate(0),
144 m_encryptor(nullptr),
145 m_sendEvent()
146{
148
150 {"NOT_STARTED", "INITIALIZED"},
151 {"INITIALIZED", "WAIT"},
152 {"INITIALIZED", "READY"},
153 {"WAIT", "READY"},
154 {"READY", "WAIT"},
155 {"READY", "SEND_DATA"},
156 {"SEND_DATA", "READY"},
157 {"READY", "DECRYPT_DATA"},
158 {"DECRYPT_DATA", "READY"},
159 {"DECRYPT_DATA", "STOPPED"},
160 {"SEND_DATA", "STOPPED"},
161 {"READY", "STOPPED"},
162 {"WAIT", "STOPPED"},
163 };
164}
165
170
171void
173{
174 NS_LOG_FUNCTION(this);
175
176 //Data sockets
177 m_dataSocketApp = nullptr;
178 //Signaling sockets
179 m_signalingSocketApp = nullptr;
180 //KMS sockets
181 m_socketToKMS = nullptr;
182
184}
185
186void
188 std::string socketType,
189 std::string appId,
190 std::string remoteAppId,
191 const Address& appAddress,
193 const Address& kmAddress,
194 std::string type
195){
196 Setup(
198 appId,
202 kmAddress,
203 0,
204 0,
205 type
206 );
207}
208
209void
211 std::string socketType,
212 std::string appId,
213 std::string remoteAppId,
214 const Address& appAddress,
216 const Address& kmAddress,
219 std::string type
220)
221{
222 NS_LOG_FUNCTION(this);
223 if(type == "alice")
224 m_master = 1;
225 else
226 m_master = 0;
227
228 m_id = appId;
230
232 if(!remoteAppAddress.IsInvalid())
234
236 if(!appAddress.IsInvalid())
238
239 NS_LOG_FUNCTION(this << kmAddress);
240 if(!kmAddress.IsInvalid())
242
244
245 NS_LOG_FUNCTION(this << "Peer IP " << InetSocketAddress::ConvertFrom(m_peer).GetIpv4() << " and port " << m_portSignaling );
246
250
251 m_internalAppWait = false; //No longer wait schedule required!
252 InitKeyStores(); //Setup application key buffer!
254}
255
256/**
257 * ********************************************************************************************
258
259 * SCHEDULE functions
260
261 * ********************************************************************************************
262 */
263void
265{
268 {
269 double delay = m_size * 8 / static_cast<double>(m_rate.GetBitRate());
270 NS_LOG_FUNCTION(this << "schedule in" << Seconds(delay));
272 }
273}
274
275void
276QKDApp014::ScheduleAction(Time t, std::string action)
277{
278 NS_LOG_FUNCTION(this);
279 if(action == "ManageStores"){
281 {
283 NS_LOG_FUNCTION(this << action << "scheduled in" << t);
284 }else
285 NS_LOG_FUNCTION(this << action << "already scheduled");
286
287 }else
288 NS_FATAL_ERROR( this << "invalid action" << action );
289}
290
291
292/**
293 * ********************************************************************************************
294
295 * SOCKET functions
296
297 * ********************************************************************************************
298 */
299
300void
334
335void
337{
338 NS_LOG_FUNCTION(this);
339
340 ////////////////
341 // SIGNALING SOCKET
342 ////////////////
343
345 {
346
350 );
351
355 );
356
358
360 {
361 NS_LOG_FUNCTION(this << "Let's create signaling socket to peer APP!");
362
367 );
372 );
376 );
377 if(m_master)
379 }
380
382 {
383 if(m_master)
384 {
385 NS_LOG_FUNCTION(this << "Let's connect to peer!");
386
388 NS_LOG_DEBUG(this << " Connect() return value= " << ret << " GetErrNo= " << m_signalingSocketApp->GetErrno()
389 << ".");
390 NS_ASSERT_MSG(m_signalingSocketApp, "Failed creating socket.");
391
392 }else{
394 {
395 NS_FATAL_ERROR("Failed to bind socket");
396 }
397 NS_LOG_FUNCTION(this << "PEER Listen");
399 }
400 }
401 }
402
403 ////////////////
404 // DATA SOCKET
405 ////////////////
406
408 {
409
413 );
414
418 );
419
420 if(!m_dataSocketApp)
421 {
422 NS_LOG_FUNCTION(this << "Let's create DATA socket to peer APP!");
423
424 if(m_socketType == "tcp")
426 else
428
432 );
437 );
441 );
442 if(m_master)
444 }
445
447 {
448 if(m_master)
449 {
450 NS_LOG_FUNCTION(this << "Let's connect to DATA peer!");
451
453 NS_LOG_DEBUG(this << " Connect() return value= " << ret << " GetErrNo= " << m_dataSocketApp->GetErrno()
454 << ".");
455 NS_ASSERT_MSG(m_dataSocketApp, "Failed creating DATA socket.");
456
457 }else{
459 {
460 NS_FATAL_ERROR("Failed to bind DATA socket");
461 }
462 NS_LOG_FUNCTION(this << "PEER DATA Listen");
464 }
465 }
466
467 }else
468 NS_LOG_FUNCTION(this << "sockets exists" << m_signalingSocketApp << m_dataSocketApp);
469
470}
471
472
473bool
475{
476 NS_LOG_FUNCTION(this << socket << from
477 << InetSocketAddress::ConvertFrom(from).GetIpv4()
478 << InetSocketAddress::ConvertFrom(from).GetPort()
479 );
480 NS_LOG_FUNCTION(this << "requested on socket " << socket);
482
483 return true;
484}
485
486bool
488{
489 NS_LOG_FUNCTION(this << socket << from
490 << InetSocketAddress::ConvertFrom(from).GetIpv4()
491 << InetSocketAddress::ConvertFrom(from).GetPort()
492 );
493 NS_LOG_FUNCTION(this << "requested on socket " << socket);
495
496 return true;
497}
498
499bool
501{
502 NS_LOG_FUNCTION(this << socket << from
503 << InetSocketAddress::ConvertFrom(from).GetIpv4()
504 << InetSocketAddress::ConvertFrom(from).GetPort()
505 );
506 NS_LOG_FUNCTION(this << "requested on socket " << socket);
507
508 return true;
509}
510
511void
513{
514 NS_LOG_FUNCTION(this << socket << from
515 << InetSocketAddress::ConvertFrom(from).GetIpv4()
516 << InetSocketAddress::ConvertFrom(from).GetPort()
517 );
518 NS_LOG_FUNCTION(this << "accepted on socket " << socket);
519 socket->SetRecvCallback(MakeCallback(&QKDApp014::HandleReadFromKMS, this));
520
521}
522
523void
525{
526 NS_LOG_FUNCTION(this << s << from
527 << InetSocketAddress::ConvertFrom(from).GetIpv4()
528 << InetSocketAddress::ConvertFrom(from).GetPort()
529 );
530 m_dataSocketApp = s;
531 NS_LOG_FUNCTION(this << "accepted on socket " << s);
532 s->SetRecvCallback(MakeCallback(&QKDApp014::HandleReadFromApp, this));
533
534}
535
536void
538{
539 NS_LOG_FUNCTION(this << s << from
540 << InetSocketAddress::ConvertFrom(from).GetIpv4()
541 << InetSocketAddress::ConvertFrom(from).GetPort()
542 );
544 NS_LOG_FUNCTION(this << "accepted on socket " << s);
545 s->SetRecvCallback(MakeCallback(&QKDApp014::HandleReadSignalingFromApp, this));
546
547}
548
549void
551{
552 NS_LOG_FUNCTION(this << socket << "succeeded via socket " << socket);
553}
554
555void
557{
558 NS_LOG_FUNCTION(this << socket << "failed via socket " << socket);
559}
560void
562{
563 NS_LOG_FUNCTION(this << "failed via socket " << socket);
564}
565
566void
568{
569 NS_LOG_FUNCTION(this << "succeeded via socket " << socket);
571}
572
573void
575{
576 NS_LOG_FUNCTION(this << "succeeded via socket " << socket);
578}
579
580void
582{
583 NS_LOG_FUNCTION(this << "failed via socket " << socket);
584}
585
586void
588{
589 NS_LOG_FUNCTION(this << socket);
590}
591
592void
594{
595 NS_LOG_FUNCTION(this << socket);
596}
597
598void
600{
601 NS_LOG_FUNCTION(this << socket);
602}
603void
605{
606 NS_LOG_FUNCTION(this << socket);
607}
608
609void
614
615void
620
621void
623{
624 NS_LOG_FUNCTION(this << socket);
625 Ptr<Packet> packet;
626 Address from;
627 while((packet = socket->RecvFrom(from))){
628 if(packet->GetSize() == 0) //EOF
629 break;
630
631 NS_LOG_FUNCTION(this
632 << packet << "PACKETID: " << packet->GetUid()
633 << " of size: " << packet->GetSize()
634 );
636 NS_LOG_FUNCTION("At time " << Simulator::Now().GetSeconds()
637 << "s packet from KMS received "
638 << packet->GetSize() << " bytes from "
640 << " port " << InetSocketAddress::ConvertFrom(from).GetPort()
641 );
642
643 }
644 HttpPacketReceived(packet, from, socket);
645
646 }
647}
648
649void
651{
652 NS_LOG_FUNCTION(this << socket);
653 Ptr<Packet> packet;
654 Address from;
655 while((packet = socket->RecvFrom(from))){
656 if(packet->GetSize() == 0) //EOF
657 break;
658
659 NS_LOG_FUNCTION(this << packet
660 << "PACKETID: " << packet->GetUid()
661 << " of size: " << packet->GetSize()
662 );
664 NS_LOG_FUNCTION( this << "At time " << Simulator::Now().GetSeconds()
665 << "s packet from APP pair received "
666 << packet->GetSize() << " bytes from "
668 << " port " << InetSocketAddress::ConvertFrom(from).GetPort()
669 );
670
671 }
672 QAppPacketReceived(packet, from, socket);
673
674 }
675}
676
677void
679{
680 NS_LOG_FUNCTION(this << socket);
681 Ptr<Packet> packet;
682 Address from;
683 while((packet = socket->RecvFrom(from))){
684 if(packet->GetSize() == 0) //EOF
685 break;
686
687 NS_LOG_FUNCTION(this << packet
688 << "PACKETID: " << packet->GetUid()
689 << " of size: " << packet->GetSize()
690 );
692 NS_LOG_FUNCTION( this << "At time " << Simulator::Now().GetSeconds()
693 << "s signaling packet from APP pair received "
694 << packet->GetSize() << " bytes from "
696 << " port " << InetSocketAddress::ConvertFrom(from).GetPort()
697 );
698
699 }
700 HttpPacketReceived(packet, from, socket);
701
702 }
703}
704
705
706void
708{
709 NS_LOG_FUNCTION( this << m_master << p->GetUid() << p->GetSize() << from );
711
712 //Must be ready to receive data
713 if(GetState() == READY)
714 {
715 QKDAppHeader header;
716 Ptr<Packet> buffer;
717
718 auto itBuffer = m_buffer_QKDApp014.find(from);
719 if(itBuffer == m_buffer_QKDApp014.end())
720 itBuffer = m_buffer_QKDApp014.insert(std::make_pair(from, Create<Packet>(0))).first;
721
722 buffer = itBuffer->second;
723 buffer->AddAtEnd(p);
724 buffer->PeekHeader(header);
725 NS_ABORT_IF(header.GetLength() == 0);
726
727 while(buffer->GetSize() >= header.GetLength()){
728 NS_LOG_DEBUG("Removing packet of size " << header.GetLength() << " from buffer of size " << buffer->GetSize());
729 Ptr<Packet> completePacket = buffer->CreateFragment(0, static_cast<uint32_t>(header.GetLength()));
730 buffer->RemoveAtStart(static_cast<uint32_t>(header.GetLength()));
731
733 completePacket->RemoveHeader(header);
734 NS_LOG_FUNCTION(this << "RECEIVED QKDApp014 HEADER: " << header);
735
736 ProcessDataPacket(header, completePacket, socket);
737 if(buffer->GetSize() > header.GetSerializedSize())
738 buffer->PeekHeader(header);
739 else
740 break;
741
742 }
743
744 }else
745 NS_LOG_DEBUG(this << "invalid state " << GetAppStateString());
746
747}
748
749void
751{
752 NS_LOG_FUNCTION(this << p->GetUid() << p->GetSize() << from);
753
754 // Maintain per-peer buffer
755 Ptr<Packet> &buffer = m_buffer_kms[from];
756 if (!buffer) buffer = Create<Packet>(0);
757 buffer->AddAtEnd(p);
758
759 HTTPMessageParser parser;
760 while (buffer->GetSize() > 0) {
761 // Convert buffer into string
762 std::string bufferStr(buffer->GetSize(), '\0');
763 buffer->CopyData(reinterpret_cast<uint8_t*>(&bufferStr[0]), bufferStr.size());
764
765 std::string httpMsgStr;
766 size_t httpMsgSize = 0;
767
768 if (!parser.TryExtractHttpMessage(bufferStr, httpMsgStr, httpMsgSize)) {
769 NS_LOG_DEBUG("[DEBUG] Fragmented or incomplete HTTP message. Awaiting more data.");
770 break;
771 }
772
773 // Parse full HTTP message
775 parser.Parse(&request, httpMsgStr);
776
777 if (request.IsFragmented() || request.GetSize() == 0) {
778 NS_LOG_DEBUG("[DEBUG] Detected fragmented or malformed HTTP message. Waiting...");
779 break;
780 }
781
782 // Process full packet
783 Ptr<Packet> completePacket = buffer->CreateFragment(0, static_cast<uint32_t>(httpMsgSize));
784 buffer->RemoveAtStart(static_cast<uint32_t>(httpMsgSize));
785
788
789 NS_LOG_DEBUG("[DEBUG] Received from: " << senderIp << ", expected peer IP: " << peerIp);
790
791 if (senderIp == peerIp) {
794 } else {
797 }
798
799 NS_LOG_DEBUG("[DEBUG] Processed HTTP message: " << request.ToString());
800 NS_LOG_DEBUG("[DEBUG] Remaining buffer size: " << buffer->GetSize());
801 }
802}
803
804
805
806void
808{
809 NS_LOG_FUNCTION(this << "sent via socket " << socket);
810}
811
812
813/**
814 * ********************************************************************************************
815
816 * KEY BUFFER functions
817
818 * ********************************************************************************************
819 */
820void
822{
823 NS_LOG_FUNCTION(this); //Initialize key stores!
824 m_commonStore.clear();
825 m_encStore.clear();
826 m_authStore.clear();
827
828}
829
830void
832{
833 NS_LOG_FUNCTION(this);
836 if(m_master)
837 { //Only at Primary application!
838 if(GetEncryptionKeySize() != 0 && m_encStore.empty()) //Check the state of encryption key store
839 GetKeysFromKMS("encryption"); // 0 - Encryption key
840 if(GetAuthenticationKeySize() != 0 && m_authStore.empty()) //Check the state of authentication key store
841 GetKeysFromKMS("authentication"); // 1 - Authentication key
842 CheckAppState();
843 }
844}
845
847QKDApp014::GetLocalKey(std::string type, std::string keyId)
848{
849 NS_LOG_FUNCTION(this << m_master << type << keyId);
851 if(m_master){ //master
852 if(type == "encryption"){ //Get encryption key
853 auto it = m_encStore.begin();
854 if(it != m_encStore.end()){
855 localKey = it->second;
856 NS_LOG_FUNCTION(this << localKey->GetLifetime());
857 if( localKey->GetLifetime() < 2*m_size ){
858 NS_LOG_FUNCTION(this << "lifetime expired! key " << localKey->GetId() << " removed");
859 m_encStore.erase(it);
860 }else
861 it->second->UseLifetime(m_size);
862
863 }else
864 NS_LOG_DEBUG(this << m_master << type << "store empty");
865
866 }else{
867 auto it = m_authStore.begin();
868 if(it != m_authStore.end()){
869 localKey = it->second;
870 NS_LOG_FUNCTION(this << type << localKey->GetId());
871 m_authStore.erase(it);
872 NS_LOG_FUNCTION(this << "key removed" << localKey->GetId());
873 }else
874 NS_LOG_DEBUG(this << m_master << "store empty" << type);
875
876 }
877
878 }else{ //slave
879 auto it = m_commonStore.find(keyId);
880 if(it != m_commonStore.end()){
881 localKey = it->second;
882 if(localKey->GetType() == AppKey::ENCRYPTION){
883 if( localKey->GetLifetime() < 2*m_size ){
884 NS_LOG_FUNCTION(this << "lifetime expired! key " << localKey->GetId() << " removed");
885 m_commonStore.erase(it);
886 }else
887 it->second->UseLifetime(m_size);
888
889 }else{ //Authenticaiton key
890 NS_LOG_FUNCTION(this << "key " << localKey->GetId() << " removed");
891 m_commonStore.erase(it);
892
893 }
894
895 }else
896 NS_LOG_DEBUG(this << m_master << "store empty" << type);
897
898 }
899
900 return localKey;
901}
902
903void
905{
906 NS_LOG_FUNCTION(this << "encryption key count" << m_encStore.size()
907 << "authentication key count" << m_authStore.size()
908 << "inbound/temporary key count" << m_commonStore.size());
909}
910
911void
913{
915 bool encryptionReady {true};
916 bool authenticationReady {true};
917
918 if(GetEncryptionKeySize() && m_encStore.empty())
919 encryptionReady = false;
920
922 authenticationReady = false;
923
925
928
931
932}
933
934/**
935 * ********************************************************************************************
936
937 * HTTP mapping
938
939 * ********************************************************************************************
940 */
941void
943{
944 NS_LOG_FUNCTION(this);
945 if(input.empty()) NS_LOG_ERROR(this << "empty input");
946 m_kmsHttpReqQueue.push_back(input);
947}
948
949void
950QKDApp014::PushHttpAppRequest(std::vector<std::string> keyIds)
951{
952 NS_LOG_FUNCTION(this);
953 if(keyIds.empty()) NS_LOG_ERROR(this << "empty input");
954 m_appHttpReqQueue.push_back(keyIds);
955}
956
957std::string
959{
960 NS_LOG_FUNCTION(this);
961 std::string output;
962 if(m_kmsHttpReqQueue.empty()) NS_LOG_ERROR(this << "request queue is empty");
963 auto it = m_kmsHttpReqQueue.begin();
964 output = *it;
965 m_kmsHttpReqQueue.erase(it);
966
967 return output;
968}
969
970std::vector<std::string>
972{
973 NS_LOG_FUNCTION(this);
974 std::vector<std::string> keyIds {};
975 if(m_appHttpReqQueue.empty()) NS_LOG_ERROR(this << "request queue is empty");
976 auto it = m_appHttpReqQueue.begin();
977 keyIds = *it;
978 m_appHttpReqQueue.erase(it);
979
980 return keyIds;
981}
982
983
984/**
985 * ********************************************************************************************
986
987 * APPLICATION functions
988
989 * ********************************************************************************************
990 */
991void
993{
994 NS_LOG_FUNCTION( this << m_local << m_peer << m_master );
996 NS_FATAL_ERROR("invalid encryption type" << m_encryption << "allowed values are(0-unencrypted, 1-OTP, 2-AES)");
998 NS_FATAL_ERROR("invalid authentication type" << m_authentication << "allowed values are(0-unauthenticated, 1-VMAC, 2-MD5, 3-SHA1)");
999
1000 if(m_aesLifetime < 0)
1001 NS_FATAL_ERROR("invalid key lifetime " << m_aesLifetime << "the value must be positive");
1002 else if(m_aesLifetime < m_size && m_aesLifetime != 0)
1003 NS_FATAL_ERROR("invalid key lifetime " << m_aesLifetime << "the value must be larger than packet size" << m_size);
1004
1005 if(GetState() == INITIALIZED){
1010 );
1011 AppTransitionTree(); //Transition states
1012 PrepareSocketToApp(); //Create sink sockets for peer QKD applications
1013
1014 }else
1015 NS_FATAL_ERROR("invalid state" << GetAppStateString() << "for StartApplication().");
1016
1017}
1018
1019void
1021{
1022 NS_LOG_FUNCTION(this);
1024
1025 //Close sockets
1029
1030 InitKeyStores(); //Clear key stores
1032
1033}
1034
1035void
1037{
1038 NS_LOG_FUNCTION(this);
1039
1042
1043 if(GetState() == READY) SwitchAppState(SEND_DATA); //Direct call from SceduleTx()
1044
1045 if(GetState() == SEND_DATA){ //Send only if in SEND_DATA state!
1046
1047 bool encrypted {m_encryptionType != 0};
1049 NS_LOG_FUNCTION(this << "enc/auth" << encrypted << authenticated);
1050
1051 //Obtain secret keys!
1054 std::string encKeyDecoded;
1055 std::string authKeyDecoded;
1056 std::string confidentialMsg {GetPacketContent()};
1057 std::string encryptedMsg {confidentialMsg};
1058 std::string authTag;
1059
1060 if(encrypted){
1061 encKey = GetLocalKey("encryption");
1062 encKeyDecoded = m_encryptor->Base64Decode(encKey->GetKeyString());
1063 if(m_useCrypto){
1065 NS_LOG_FUNCTION(this << "\n\tencryption key" << encKey->GetId() << encKeyDecoded
1066 << "\n\tencrypted message(Base64 print)" << m_encryptor->Base64Encode(encryptedMsg));
1067
1068 }else{
1070 NS_LOG_FUNCTION(this << "\n\tencryption key" << encKey->GetId() << encKeyDecoded);
1071
1072 }
1073 }
1074
1076 authKey = GetLocalKey("authentication");
1077 authKeyDecoded = m_encryptor->Base64Decode(authKey->GetKeyString());
1078 if(m_useCrypto){
1080 NS_LOG_FUNCTION(this << "\n\tauthentication key" << authKey->GetId() << authKeyDecoded
1081 << "\n\tauthentication tag" << authTag);
1082
1083 }else{
1085 NS_LOG_FUNCTION(this << "\n\tauthentication key" << authKey->GetId() << authKeyDecoded);
1086
1087 }
1088 }
1089
1090 //Create packet with protected/unprotected data
1091 std::string msg {encryptedMsg};
1092 Ptr<Packet> packet = Create<Packet>((uint8_t*) msg.c_str(), msg.length() );
1093 NS_ASSERT(packet);
1095
1096 //Add qkd header!
1099 if(encKey) qHeader.SetEncryptionKeyId(CreateKeyIdField(encKey->GetId()));
1100 else qHeader.SetEncryptionKeyId(std::string(32, '0'));
1101 qHeader.SetAuthenticated(m_authenticationType);
1102 if(authKey) qHeader.SetAuthenticationKeyId(CreateKeyIdField(authKey->GetId()));
1103 else qHeader.SetAuthenticationKeyId(std::string(32, '0'));
1104 qHeader.SetAuthTag(authTag);
1105 qHeader.SetLength(packet->GetSize() + qHeader.GetSerializedSize());
1106 packet->AddHeader(qHeader);
1107
1108 NS_LOG_FUNCTION(this << "sending data packet id" << packet->GetUid() << packet->GetSize());
1109
1110 //Send packet!
1111 m_txTrace(GetId(), packet);
1112 m_dataSocketApp->Send(packet);
1113
1114 SwitchAppState(READY); //Application is now ready
1115 ManageStores(); //Fill stores if necessary
1116 ScheduleTx(); //Schedule send data
1117
1118 }else if(GetState() == WAIT){
1119 m_mxTrace(GetId(), nullptr);
1120 ScheduleTx();
1121 NS_LOG_FUNCTION(this << "unable to send" << GetAppStateString(GetState()));
1122
1124 ScheduleAction(Time(m_waitInsufficient), "ManageStores");
1125 }
1126
1127}
1128
1129void
1131{
1132 NS_LOG_FUNCTION(this);
1134 uint8_t *buffer = new uint8_t[packet->GetSize()];
1135 packet->CopyData(buffer, packet->GetSize());
1136 std::string payload = std::string((char*)buffer, packet->GetSize());
1137 delete[] buffer;
1138
1139 NS_LOG_FUNCTION(this << "\ndata received\n" << m_encryptor->Base64Encode(payload));
1142 std::string decryptedMsg;
1143 m_size = payload.length();
1144
1145 if(GetAuthenticationKeySize()){ //Perform authentication first
1146 Ptr<AppKey> key {GetLocalKey("authentication", ReadKeyIdField(header.GetAuthenticationKeyId()))};
1147 if(m_useCrypto){
1148 std::string decodedKey {m_encryptor->Base64Decode(key->GetKeyString())}; //Decode key
1149 if(m_encryptor->CheckAuthentication(payload, header.GetAuthTag(), decodedKey)) //Check authTag
1150 NS_LOG_FUNCTION(this << "authentication successful");
1151 else
1152 NS_LOG_WARN(this << "authentication failed");
1153
1154 }else //We assume packet is authenticated
1155 NS_LOG_FUNCTION(this << "authentication successful");
1156
1157 }else if(header.GetAuthenticated()){
1158 if(m_useCrypto){
1159 if(m_encryptor->CheckAuthentication(payload, header.GetAuthTag(), ""))
1160 NS_LOG_FUNCTION(this << "authentication successful");
1161 else
1162 NS_LOG_WARN(this << "authentication failed");
1163
1164 }else//We assume packet is authenticated
1165 NS_LOG_FUNCTION(this << "authentication successful");
1166
1167 }
1168
1169 if(header.GetEncrypted()){ //Perform decryption
1170 Ptr<AppKey> key {GetLocalKey("encryption", ReadKeyIdField(header.GetEncryptionKeyId()))};
1171 if(m_useCrypto){
1172 std::string decodedKey {m_encryptor->Base64Decode(key->GetKeyString())}; //Decode key
1173 NS_LOG_FUNCTION(this << "\n\tdecryption key" << decodedKey);
1175 NS_LOG_FUNCTION(this << "\n\tdecrypted message" << decryptedMsg);
1176 }else
1177 NS_LOG_FUNCTION(this << "packet decrypted");
1178
1179 }else
1180 NS_LOG_FUNCTION(this << "Received message" << payload);
1181
1183
1184}
1185
1186/**
1187 * ********************************************************************************************
1188
1189 * KEY MANAGEMENT functions
1190
1191 * ********************************************************************************************
1192 */
1193
1194void
1196{
1197 NS_LOG_FUNCTION(this);
1199
1200 //Create packet
1201 HTTPMessage httpMessage;
1202 httpMessage.CreateRequest("http://" + IpToString(GetKmsIp()) + "/api/v1/keys/" + m_dstId + "/status", "GET");
1203 httpMessage.SetHeader("User-Agent", "QKDApp014_" + GetId());
1204 std::string hMessage = httpMessage.ToString();
1205 Ptr<Packet> packet = Create<Packet>(
1206 (uint8_t*)(hMessage).c_str(),
1207 hMessage.size()
1208 );
1209
1210 NS_ASSERT(packet);
1211 NS_LOG_FUNCTION(this << "GET STATUS URL: " << "http://" + IpToString(GetKmsIp()) + "/api/v1/keys/" + m_dstId + "/status");
1212
1213 NS_LOG_FUNCTION(this << "Sending PACKETID: " << packet->GetUid()
1214 << " of size: " << packet->GetSize()
1215 << " via socket " << m_socketToKMS
1216 );
1217
1218 m_txKmsTrace(GetId(), packet);
1219 m_socketToKMS->Send(packet);
1220
1221}
1222
1223void
1225{
1226 NS_LOG_FUNCTION(this << keyType);
1228
1229 uint32_t number {m_numberOfKeysKMS};
1230 uint32_t size {0};
1231 if(keyType == "encryption")
1232 size = GetEncryptionKeySize();
1233 else if(keyType == "authentication")
1234 size = GetAuthenticationKeySize();
1235 else
1236 NS_FATAL_ERROR(this << "invalid key type" << keyType);
1237
1238 //Application basic check of user input!
1239 if(number <= 0) NS_FATAL_ERROR(this << "invalid m_numberOfKeysKMS" << number);
1240 if(size <= 0) NS_FATAL_ERROR(this << "invalid key_size" << size);
1241
1242 std::vector<std::string> additional_slave_SAE_IDs {}; //No additional Replica SAEs
1243 bool useGet {true}; //Used GET(if possible)
1244 if(!additional_slave_SAE_IDs.empty())
1245 useGet = false;
1246
1247 HTTPMessage httpMessage;
1248 std::string headerUri {"http://" + IpToString(GetKmsIp()) + "/api/v1/keys/" + m_dstId + "/enc_keys"};
1249 if(useGet){ //Update header URI
1250 headerUri += "/number/" + std::to_string(number) + "/size/" + std::to_string(size);
1251 httpMessage.CreateRequest(headerUri, "GET");
1252 httpMessage.SetHeader("User-Agent", "QKDApp014_" + GetId());
1253
1254 }else
1255 NS_LOG_ERROR(this << "POST method disabled");
1256
1257 std::string hMessage = httpMessage.ToString();
1258 Ptr<Packet> packet = Create<Packet>(
1259 (uint8_t*)(hMessage).c_str(),
1260 hMessage.size()
1261 );
1262 NS_ASSERT(packet);
1263
1264 NS_LOG_FUNCTION(this << "Sending PACKETID: " << packet->GetUid()
1265 << " of size: " << packet->GetSize()
1266 << " via socket " << m_socketToKMS
1267 << " uri " << headerUri
1268 );
1269
1271 m_txKmsTrace(GetId(), packet);
1272 m_socketToKMS->Send(packet);
1273}
1274
1275void
1277{
1278 NS_LOG_FUNCTION(this);
1280
1281 //Create packet
1282 HTTPMessage httpMessage;
1283 httpMessage.CreateRequest("http://" + IpToString(GetKmsIp()) + "/api/v1/keys/" + m_dstId + "/dec_keys", "POST", keyIds);
1284 httpMessage.SetHeader("User-Agent", "QKDApp014_" + GetId());
1285 std::string hMessage = httpMessage.ToString();
1286 Ptr<Packet> packet = Create<Packet>(
1287 (uint8_t*)(hMessage).c_str(),
1288 hMessage.size()
1289 );
1290 NS_ASSERT(packet);
1291
1292 NS_LOG_FUNCTION(this << "Sending PACKETID: " << packet->GetUid()
1293 << " of size: " << packet->GetSize()
1294 << " via socket " << m_socketToKMS
1295 );
1296
1297 m_txKmsTrace(GetId(), packet);
1298 m_socketToKMS->Send(packet);
1299}
1300
1301void
1303{
1304 NS_LOG_FUNCTION(this << header.GetRequestUri() << header.GetStatus());
1305
1306 std::string reqMethod = ReadUri(header.GetRequestUri())[5]; //Get method from request URI field!
1307 nlohmann::json responseBody;
1308 try{
1309 responseBody = nlohmann::json::parse(header.GetMessageBodyString());
1310 }catch(...){
1311 NS_FATAL_ERROR(this << "json parse error");
1312 }
1313
1314 /** status **/
1315 if(reqMethod == "status"){
1316 if(header.GetStatus() == HTTPMessage::Ok)
1317 ManageStores();
1318 else
1319 NS_LOG_ERROR(this << "status error" << responseBody.dump());
1320
1321
1322 /** enc_keys **/
1323 }else if(reqMethod == "enc_keys"){
1324 if(header.GetStatus() == HTTPMessage::Ok){
1325 std::string keyType {PopHttpKmsRequest()};
1326 std::vector<std::string> keyIds; //Obtained keyIds
1327 for(nlohmann::json::iterator it = responseBody["keys"].begin(); it != responseBody["keys"].end(); ++it){
1328 Ptr<AppKey> key = CreateObject<AppKey>( std::string{(it.value())["key_ID"]}, std::string {(it.value())["key"]}, AppKey::ENCRYPTION, m_size );
1329 if(keyType == "encryption" && m_encryptionType == QKDEncryptor::QKDCRYPTO_AES)
1330 key->SetLifetime(m_aesLifetime);
1331 else if(keyType == "authentication")
1332 key->SetType(AppKey::AUTHENTICATION);
1333
1334 m_commonStore.insert(std::make_pair(key->GetId(), key)); //Add keys to temporary key store
1335 keyIds.push_back(key->GetId());
1336
1337 }
1338 SendKeyIds(keyIds); //send key ids to receiver App014
1339
1340 }else{
1341 if(responseBody.contains("message"))
1342 {
1343 if(responseBody["message"] == std::string {"insufficient amount of key material"})
1344 ScheduleAction(Time(m_waitInsufficient), "ManageStores");
1345 else
1346 NS_FATAL_ERROR(this << "get_key error" << responseBody.dump());
1347
1348 }else
1349 NS_FATAL_ERROR(this << "response data format error" << responseBody.dump());
1350 }
1351 /** dec_keys **/
1352 }else if(reqMethod == "dec_keys"){
1353 if(header.GetStatus() == HTTPMessage::HttpStatus::Ok){
1354 //Replica application directly stores the keys in application key buffer!
1355 for(nlohmann::json::iterator it = responseBody["keys"].begin(); it != responseBody["keys"].end(); ++it)
1356 m_commonStore.insert(
1357 std::make_pair((it.value())["key_ID"],
1358 CreateObject<AppKey>( std::string{(it.value())["key_ID"]}, std::string{(it.value())["key"]}, AppKey::ENCRYPTION, m_aesLifetime )
1359 )
1360 );
1361 }else
1362 NS_LOG_ERROR(this << "error");
1363
1364 SendKeyIds({}, header.GetStatus()); //Send response on key ids notification
1365
1366 }else
1367 NS_FATAL_ERROR(this << "unknown method" << reqMethod);
1368
1369
1370}
1371
1372void
1374{
1375 NS_LOG_FUNCTION(this << m_master << packet->GetSize() << packet->GetUid());
1376
1377 //Sender App014 process response on KEY_IDS notification
1378 if(m_master)
1379 {
1380 std::vector<std::string> keyIds = PopHttpAppRequest(); //mapping of response to request
1381
1382 //Sender App014 moves keys to outbound key store
1383 if(header.GetStatus() == HTTPMessage::Ok)
1384 {
1385 for(auto const& el: keyIds){
1386 auto it = m_commonStore.find(el);
1387 if(it == m_commonStore.end())
1388 NS_LOG_ERROR(this << "unknown key");
1389 else{
1390 if(it->second->GetType() == AppKey::ENCRYPTION){
1391 m_encStore.insert( std::make_pair(it->second->GetId(), it->second) );
1392 NS_LOG_DEBUG(this << "moved to encryption store\t" << it->second->GetId());
1393 }else if(it->second->GetType() == AppKey::AUTHENTICATION){
1394 m_authStore.insert( std::make_pair(it->second->GetId(), it->second) );
1395 NS_LOG_DEBUG(this << "moved to authentication store\t" << it->second->GetId());
1396 }else
1397 NS_LOG_ERROR(this << "unknown key type");
1398
1399 NS_LOG_DEBUG(this << "key removed from common\t" << it->second->GetId());
1400 m_commonStore.erase(it);
1401 }
1402 }
1403
1405 CheckAppState();
1406
1407 }else{ //Error
1408 NS_LOG_WARN(this << "unexpected KEY_IDS error");
1409 //auto keyIds = PopHttpAppRequest();
1410 AppKey::Type type {};
1411 for(auto const& el : keyIds){ //remove keys from temporary key store
1412 auto it = m_commonStore.find(el);
1413 if(it != m_commonStore.end()){
1414 type = it->second->GetType();
1415 m_commonStore.erase(it);
1416 }else
1417 NS_LOG_ERROR(this << "unknown key" << el);
1418
1419 }
1420 if(!m_internalAppWait){
1421 if(type == AppKey::ENCRYPTION) GetKeysFromKMS("encryption");
1422 else GetKeysFromKMS("authentication");
1423
1424 }
1425
1426 }
1427
1428 }else //Receiver App014 process KEY_IDS notification
1430
1431}
1432
1433void
1435{
1436 NS_LOG_FUNCTION(this << m_master);
1437
1440
1441 if(m_master){ //Primary QKDApp014 sends proposal of keys to Replica QKDApp014
1442 nlohmann::json jKeyIds;
1443 for(uint i = 0; i < keyIds.size(); i++)
1444 jKeyIds["key_IDs"].push_back({ {"key_ID", keyIds[i]} });
1445
1446 std::string reqUri {"http://" + IpToString(GetPeerIp()) + "/keys/key_ids"};
1447 HTTPMessage httpMessage;
1448 httpMessage.CreateRequest(reqUri, "POST", jKeyIds.dump());
1449 httpMessage.SetHeader("User-Agent", "QKDApp014_" + GetId());
1450 std::string hMessage = httpMessage.ToString();
1451 Ptr<Packet> packet = Create<Packet>( //Create packet
1452 (uint8_t*)(hMessage).c_str(),
1453 hMessage.size()
1454 );
1455 NS_ASSERT(packet);
1456
1457 PushHttpAppRequest(keyIds);
1458 m_txSigTrace(GetId(), packet);
1459 m_signalingSocketApp->Send(packet);
1460 NS_LOG_FUNCTION(this << "proposal sent" << packet->GetUid() << packet->GetSize() << httpMessage.ToString());
1461
1462 }else{ //Replica QKDApp014 sends response to Primary QKDApp014.
1463 HTTPMessage httpMessage;
1464 httpMessage.CreateResponse(statusCode, "", {
1465 {"Request URI", "http://"+ IpToString(GetIp()) +"/keys/key_ids"}
1466 });
1467 std::string hMessage = httpMessage.ToString();
1468 Ptr<Packet> packet = Create<Packet>(
1469 (uint8_t*)(hMessage).c_str(),
1470 hMessage.size()
1471 );
1472 NS_ASSERT(packet);
1473
1474 NS_LOG_FUNCTION(this << "PEER Sending SIGNALING PACKETID: " << packet->GetUid()
1475 << " of size: " << packet->GetSize()
1476 << " via socket " << m_signalingSocketApp
1477 );
1478
1479 m_txSigTrace(GetId(), packet);
1480 m_signalingSocketApp->Send(packet);
1481
1482 NS_LOG_FUNCTION(this << "\n\n\n" << packet->GetUid() << packet->GetSize() << httpMessage.ToString());
1483
1484 }
1485
1486}
1487
1488
1489
1490/**
1491 * ********************************************************************************************
1492
1493 * STATE functions
1494
1495 * ********************************************************************************************
1496 */
1497
1498/*
1499 * @brief QKD App state transitions(Data transmision)
1500 */
1501void
1503{
1504 NS_LOG_FUNCTION( this );
1505
1506 if(m_master) //Data transmision state transition for Primary QKDApp014
1507 {
1508
1509 if(GetState() == INITIALIZED) {
1511 if(GetEncryptionKeySize() == 0 && GetAuthenticationKeySize() == 0) //No initial key material needed!
1512 {
1515 SendDataPacket(); //Imidiatly send packet
1516 } else { //Obtain status information from KMS, obtain initial key material!
1519 GetStatusFromKMS(); //First call Get Status
1520 SendDataPacket(); //It will result in schedule
1521 }
1522 } else {
1523 NS_FATAL_ERROR( this << "Invalid entry state" << GetState() <<
1524 "for AppTransitionTree()!");
1525 }
1526
1527 } else if(!m_master) { //Data transmision state transition for Replica QKDApp014
1528
1529 if(GetState() == INITIALIZED) {
1531 } else {
1532 NS_FATAL_ERROR( this << "Invalid entry state" << GetState() <<
1533 "for AppTransitionTree()!");
1534 }
1535
1536 }
1537}
1538
1539
1540std::string
1542{
1543 switch(state)
1544 {
1545 case NOT_STARTED:
1546 return "NOT_STARTED";
1547 break;
1548 case INITIALIZED:
1549 return "INITIALIZED";
1550 break;
1551 case READY:
1552 return "READY";
1553 break;
1554 case WAIT:
1555 return "WAIT";
1556 break;
1557 case SEND_DATA:
1558 return "SEND_DATA";
1559 break;
1560 case DECRYPT_DATA:
1561 return "DECRYPT_DATA";
1562 break;
1563 case STOPPED:
1564 return "STOPPED";
1565 break;
1566 default:
1567 NS_FATAL_ERROR("Unknown state");
1568 return "FATAL_ERROR";
1569 break;
1570 }
1571}
1572
1573
1574std::string
1576{
1577 return GetAppStateString(GetState());
1578}
1579
1580void
1582{
1583
1584 const std::string oldState = GetAppStateString();
1585 const std::string newState = GetAppStateString(state);
1586
1587
1588 bool found = false;
1589 for(auto iter = m_transitionMatrix.begin(); iter != m_transitionMatrix.end(); iter++)
1590 {
1591 if(iter->first == oldState && iter->second == newState){
1592 SetState(state);
1593 NS_LOG_DEBUG(this << " QKDApp014 " << oldState << " --> " << newState << ".");
1595 found = true;
1596 }
1597 }
1598
1599 if(!found) {
1600 NS_FATAL_ERROR("Unsupported transition from " << oldState << " to " << newState);
1601 }
1602
1603
1604}
1605
1606/**
1607 * ********************************************************************************************
1608
1609 * ADDTIONAL functions
1610
1611 * ********************************************************************************************
1612 */
1613
1614void
1665
1666std::string
1668{
1669 NS_LOG_FUNCTION(this);
1670
1671 if(msgLength == 0)
1672 msgLength = m_size;
1673
1674 //Generate random string with same size as merged key string
1675 std::string confidentialMessage;
1676 static const char alphanum[] =
1677 "0123456789"
1678 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1679 "abcdefghijklmnopqrstuvwxyz";
1680 for(std::size_t i = 0; i < msgLength; ++i){
1681 confidentialMessage += alphanum[rand() %(sizeof(alphanum) - 1)];
1682 }
1683
1684 return confidentialMessage;
1685
1686}
1687
1688std::string
1690{
1691 keyId.erase(std::remove(keyId.begin(), keyId.end(), '-'), keyId.end());
1692 return keyId;
1693}
1694
1695std::string
1697{
1698 NS_LOG_FUNCTION(this << keyId);
1699 keyId.insert(8, "-");
1700 keyId.insert(13, "-");
1701 keyId.insert(18, "-");
1702 keyId.insert(23, "-");
1703 NS_LOG_FUNCTION(this << keyId);
1704 return keyId;
1705}
1706
1709{
1710
1711 NS_LOG_FUNCTION(this << CryptoPP::AES::DEFAULT_KEYLENGTH);
1712
1713 switch(m_encryptionType)
1714 {
1716 return 0;
1717 break;
1719 return m_size * 8; //This will work great for Primary QKDApp014, Replica QKDApp014 needs to calculate for itself this!
1720 break;
1722 return CryptoPP::AES::MAX_KEYLENGTH * 8; //In bits 256!
1723 break;
1724 }
1725
1726 return 0;
1727
1728}
1729
1732{
1733 switch(m_authenticationType)
1734 {
1736 return 0;
1737 break;
1739 return CryptoPP::AES::BLOCKSIZE * 8; //In bits //Before: m_authTagSize - 32B?
1740 break;
1742 return 0; //NoKey
1743 break;
1745 return 0; //NoKey
1746 break;
1747 }
1748
1749 return 0;
1750
1751}
1752
1753std::vector<std::string>
1755{
1756 NS_LOG_FUNCTION(this);
1757
1758 std::string delimiter {"/"};
1759 std::string token;
1760 size_t pos = 0;
1761 std::vector<std::string> uriParams;
1762 while((pos = s.find(delimiter)) != std::string::npos){
1763 token = s.substr(0, pos);
1764 if(!token.empty())
1765 uriParams.push_back(token);
1766
1767 s.erase(0, pos + delimiter.length());
1768
1769 }
1770 if(!s.empty())
1771 uriParams.push_back(s);
1772
1773 return uriParams;
1774}
1775
1782
1789
1796
1797std::string
1799{
1800 NS_LOG_FUNCTION(this);
1801 std::string sAddress;
1802 std::ostringstream peerkmsAddressTemp;
1803 address.Print(peerkmsAddressTemp); //IPv4Address to string
1804 return peerkmsAddressTemp.str();
1805}
1806
1807
1808} // Namespace ns3
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition json.h:20337
a polymophic address class
Definition address.h:90
@ AUTHENTICATION
Definition app-key.h:43
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
uint64_t GetBitRate() const
Get the underlying bitrate.
Definition data-rate.cc:234
bool IsPending() const
This method is syntactic sugar for !IsExpired().
Definition event-id.cc:65
The basic class to represent both HTTP requests and responses.
Definition http.h:77
std::string GetRequestUri() const
Definition http.h:430
std::string ToString()
Takes the headers added to the message along with the body and outputs it to a std::string for use in...
Definition http.h:632
void CreateRequest(const std::string &url, const std::string &method)
Definition http.h:735
std::string GetMessageBodyString()
Definition http.h:713
HTTPMessage & SetHeader(const std::string &name, const std::string &value)
Set a header in the map to the value provided.
Definition http.h:409
void CreateResponse(const HttpStatus status)
Definition http.h:781
HTTPMessage::HttpStatus GetStatus() const
To be returned with a status code in a response is a status text describing the status code by text r...
Definition http.h:168
A basic class to parse a HTTP message, both request and response.
Definition http.h:936
an Inet address class
static bool IsMatchingType(const Address &address)
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
Establish secure communication on application lavel to use the key and test LKSM.
Definition qkd-app-014.h:71
void SetState(State state)
set application state
void AppTransitionTree()
Transition tree of the application.
uint32_t m_master
is master App014
void HandleAcceptFromKMS(Ptr< Socket > s, const Address &from)
Handle an incoming connection from KMS.
std::string PopHttpKmsRequest()
Pop HTTP request from kms queue.
TracedCallback< const std::string &, Ptr< const Packet > > m_rxKmsTrace
Traced Callback: received packets from KMS.
Ptr< Socket > m_dataSocketApp
void HandleReadFromKMS(Ptr< Socket > socket)
Handle a packet received by the QKD application from KMS application.
std::map< std::string, Ptr< AppKey > > m_authStore
void QAppPacketReceived(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Check for tcp segmentation of signaling packets received from KMS.
Ptr< QKDEncryptor > m_encryptor
encryptor
std::vector< std::string > m_kmsHttpReqQueue
void ConnectionSignalingToAppSucceeded(Ptr< Socket > socket)
Callback function after the signaling connection to the APP is complete.
void SwitchAppState(State state)
Change the state of the application.
TracedCallback< const std::string &, Ptr< const Packet > > m_txTrace
Traced Callback: transmitted data packets.
std::string CreateKeyIdField(std::string keyId)
Create encryption key id field for the QKDApp header.
void ProcessDataPacket(QKDAppHeader header, Ptr< Packet > packet, Ptr< Socket > socket)
Process data packets from peer QKD application.
void HandlePeerCloseSignalingFromApp(Ptr< Socket > socket)
Handle a signaling connection close from peer QKD application.
void ConnectionSignalingToAppFailed(Ptr< Socket > socket)
Callback function after the signaling connection to the APP has.
bool ConnectionRequestedFromApp(Ptr< Socket > socket, const Address &address)
Callback function after the connection for response from KMS has been received.
TracedCallback< const std::string &, Ptr< const Packet > > m_rxSigTrace
Traced Callback: received signaling packets.
State GetState() const
returns application state
TracedCallback< const std::string &, Ptr< const Packet > > m_txKmsTrace
Traced Callback: transmitted packets to KMS.
std::string GetPacketContent(uint32_t msgLength=0)
Get the packet payload content.
Ipv4Address GetPeerIp()
Get ipv4 address of destination.
void HandlePeerErrorFromKMS(Ptr< Socket > socket)
Handle a connection error from KMS.
Ptr< Socket > m_signalingSocketApp
TracedCallback< const std::string &, Ptr< const Packet > > m_mxTrace
Traced Callback: missed send packet call.
void InitKeyStores()
Initialize key stores at application layer.
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer_kms
Buffer for received packets(fragmentation)
TypeId m_tid
tid
void StartApplication() override
Start application.
void Setup(std::string socketType, std::string appId, std::string remoteAppId, const Address &appAddress, const Address &remoteAppAddress, const Address &kmAddress, uint32_t packetSize, DataRate dataRate, std::string type)
uint32_t m_aesLifetime
key lifetime in bytes
Time m_waitInsufficient
time wait before submitting new get_key after error
void ConnectionToKMSSucceeded(Ptr< Socket > socket)
Callback function after the connection to the KMS is complete.
State
QKD App states(App) States that refer to QKDApp014 data transmision!
Definition qkd-app-014.h:85
Ptr< Socket > m_socketToKMS
void PrintStoreStats()
Print status information on key stores.
static TypeId GetTypeId()
Get the type ID.
Ipv4Address GetIp()
Get ipv4 address of source.
void SendDataPacket()
Send protected data.
std::vector< std::string > PopHttpAppRequest()
Pop HTTP request from app queue.
Ptr< AppKey > GetLocalKey(std::string keyType, std::string keyId="")
Get key from key store.
void HandleAcceptSignalingFromApp(Ptr< Socket > s, const Address &from)
Handle a signaling incoming connection from peer QKD application.
EventId m_scheduleManageStores
uint32_t GetAuthenticationKeySize()
Get key size for defined authentication algorithm.
std::string m_id
source application id
void ManageStores()
Checks the state of the key stores.
void HandlePeerCloseFromKMS(Ptr< Socket > socket)
Handle a connection close from KMS.
uint32_t GetEncryptionKeySize()
Get key size for defined encryption algorithm.
uint32_t m_encryption
encryption type
std::string IpToString(Ipv4Address address)
Convert ipv4 address in string.
void PushHttpAppRequest(std::vector< std::string > keyIds)
Adds HTTP request to app queue to properly map response later.
void ProcessResponseFromKMS(HTTPMessage &header, Ptr< Packet > packet, Ptr< Socket > socket)
Process response from KMS application.
void PrepareSocketToApp()
Prepare send socket to communicate with QKD Application.
void HandleAcceptFromApp(Ptr< Socket > s, const Address &from)
Handle an incoming connection from peer QKD application.
void ConnectionToAppFailed(Ptr< Socket > socket)
Callback function after the connection to the APP has failed.
std::string GetAppStateString() const
Returns the current state of the application in string format.
Address m_kms
local kms address
std::vector< std::vector< std::string > > m_appHttpReqQueue
void GetKeyWithKeyIDs(std::string keyIds)
Get keys identified with given IDs from local KMS.
TracedCallback< Ptr< Packet >, std::string > m_authenticationTrace
trace callback for authentication
uint32_t m_numberOfKeysKMS
number of keys to fetch per request
std::string ReadKeyIdField(std::string keyId)
Read key ID from the encryption key ID field of the QKDApp header.
bool ConnectionRequestedFromKMS(Ptr< Socket > socket, const Address &address)
Callback function after the connection for response from KMS has been received.
std::string m_socketType
TracedCallback< Ptr< Packet > > m_encryptionTrace
trace callback for encryption
uint32_t m_authentication
authentication type
std::string GetId()
Get the application ID.
void ScheduleAction(Time t, std::string action)
Schedule action to performe.
DataRate m_rate
data rate
EventId m_sendEvent
uint32_t m_authTagSize
length of the authentication tag in bits
void StopApplication() override
Stop application.
void HandleReadFromApp(Ptr< Socket > socket)
Handle a packet received by the QKD application from peer QKD application.
void ScheduleTx()
Schedule event to send data.
TracedCallback< const std::string &, Ptr< const Packet > > m_rxTrace
Traced Callback: received data packets.
void HandlePeerErrorFromApp(Ptr< Socket > socket)
Handle a connection error from peer QKD application.
void ConnectionToAppSucceeded(Ptr< Socket > socket)
Callback function after the connection to the APP is complete.
TracedCallback< const std::string &, Ptr< const Packet > > m_txSigTrace
Traced Callback: transmitted signaling packets.
void ProcessSignalingPacketFromApp(HTTPMessage &header, Ptr< Packet > packet, Ptr< Socket > socket)
Process signaling packets from peer QKD application.
void DoDispose() override
Destructor implementation.
void GetKeysFromKMS(std::string keyType)
Get keys from local KMS.
bool m_isDataConnectedToApp
~QKDApp014() override
std::map< std::string, Ptr< AppKey > > m_commonStore
std::string m_dstId
destination application id
void DataToKMSSend(Ptr< Socket >, uint32_t)
Callback function to notify that data to KMS has been sent.
void ConnectionToKMSFailed(Ptr< Socket > socket)
Callback function after the connection to the KMS has failed.
ns3::TracedCallback< const std::string &, const std::string & > m_stateTransitionTrace
The StateTransition trace source.
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer_QKDApp014
Buffer for received packets(fragmentation)
void SendKeyIds(std::vector< std::string > keyIds, HTTPMessage::HttpStatus statusCode=HTTPMessage::Ok)
Implementation of send KEY_IDS notification.
void GetStatusFromKMS()
Get status from local KMS.
Address m_local
local address
void HandlePeerErrorSignalingFromApp(Ptr< Socket > socket)
Handle a signaling connection error from peer QKD application.
static uint32_t m_applicationCounts
application count
void SetCryptoSettings(uint32_t encryptionType, uint32_t authenticationType, uint32_t authenticationTagLengthInBits)
Set encryption and authentication type.
void HttpPacketReceived(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Check for tcp segmentation of packets received.
void CheckAppState()
Checks the conditions to change the application state.
uint32_t m_useCrypto
execute crypo algorithms
void PrepareSocketToKMS()
Prepare send socket to communicate with KMS Application.
std::multimap< std::string, std::string > m_transitionMatrix
transition map of protocol states
Ipv4Address GetKmsIp()
Get ipv4 address of local KMS.
TracedCallback< Ptr< Packet >, std::string > m_deauthenticationTrace
trace callback for authentication check
std::map< std::string, Ptr< AppKey > > m_encStore
void HandleReadSignalingFromApp(Ptr< Socket > socket)
Handle a signaling packet received by the QKD application from peer QKD application.
bool ConnectionRequestedSignalingFromApp(Ptr< Socket > socket, const Address &address)
Callback function after the connection for response from KMS has been received.
TracedCallback< Ptr< Packet > > m_decryptionTrace
trace callback for decryption
std::vector< std::string > ReadUri(std::string s)
Read http uri in vector.
Address m_peer
peer address
uint32_t m_size
data packet size
QKDEncryptor::AuthenticationType m_authenticationType
authentication type
void HandlePeerCloseFromApp(Ptr< Socket > socket)
Handle a connection close from peer QKD application.
bool m_isSignalingConnectedToApp
QKDEncryptor::EncryptionType m_encryptionType
encryption type
uint16_t m_portSignaling
void PushHttpKmsRequest(std::string input)
Adds HTTP request to kms queue to properly map response later.
QKD app packet header that carries info about used encryption, auth tag and other.
uint32_t GetLength() const
std::string GetAuthTag() const
uint32_t GetEncrypted() const
void SetEncrypted(uint32_t value)
uint32_t GetSerializedSize() const override
std::string GetEncryptionKeyId() const
std::string GetAuthenticationKeyId() const
uint32_t GetAuthenticated() const
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
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
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
void SetConnectCallback(Callback< void, Ptr< Socket > > connectionSucceeded, Callback< void, Ptr< Socket > > connectionFailed)
Specify callbacks to allow the caller to determine if the connection succeeds of fails.
Definition socket.cc:76
virtual Socket::SocketErrno GetErrno() const =0
Get last error number.
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
void SetDataSentCallback(Callback< void, Ptr< Socket >, uint32_t > dataSent)
Notify application when a packet has been sent from transport protocol (non-standard socket call)
Definition socket.cc:103
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
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 Close()=0
Close a socket.
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.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
AttributeValue implementation for Time.
Definition nstime.h:1431
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
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1452
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition abort.h:65
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
#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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
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 > MakeTimeAccessor(T1 a1)
Definition nstime.h:1432
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 > MakeTypeIdChecker()
Definition type-id.cc:1335
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Definition type-id.h:641
static const uint32_t packetSize
Packet size generated at the AP.