22 #include "ns3/address.h"
23 #include "ns3/address-utils.h"
25 #include "ns3/inet-socket-address.h"
26 #include "ns3/inet6-socket-address.h"
28 #include "ns3/socket.h"
29 #include "ns3/udp-socket-factory.h"
30 #include "ns3/tcp-socket-factory.h"
31 #include "ns3/simulator.h"
32 #include "ns3/socket-factory.h"
33 #include "ns3/packet.h"
34 #include "ns3/trace-source-accessor.h"
48 .SetGroupName(
"Applications")
50 .AddAttribute (
"Protocol",
"The type of protocol to use.",
54 .AddAttribute (
"LengthOfAuthenticationTag",
55 "The default length of the authentication tag",
58 MakeUintegerChecker<uint32_t> ())
59 .AddAttribute (
"EncryptionType",
60 "The type of encryption to be used (0-unencrypted, 1-OTP, 2-AES)",
63 MakeUintegerChecker<uint32_t> ())
64 .AddAttribute (
"AuthenticationType",
65 "The type of authentication to be used (0-unauthenticated, 1-VMAC, 2-MD5, 3-SHA1)",
68 MakeUintegerChecker<uint32_t> ())
69 .AddAttribute (
"AESLifetime",
70 "Lifetime of AES key expressed in number of packets",
73 MakeUintegerChecker<uint32_t> ())
74 .AddAttribute (
"UseCrypto",
75 "Should crypto functions be performed (0-No, 1-Yes)",
78 MakeUintegerChecker<uint32_t> ())
79 .AddAttribute (
"LengthOfKeyBufferForEncryption",
80 "How many keys to store in local buffer of QKDApp004 for encryption?",
83 MakeUintegerChecker<uint32_t> ())
84 .AddAttribute (
"LengthOfKeyBufferForAuthentication",
85 "How many keys to store in local buffer of QKDApp004 for authentication?",
88 MakeUintegerChecker<uint32_t> ())
89 .AddAttribute (
"SocketToKMSHoldTime",
"How long (seconds) should QKDApp004 wait to close socket to KMS after receiving REST response?",
93 .AddAttribute (
"MaliciousApplication",
94 "Is this application malicious?",
97 MakeUintegerChecker<uint32_t> ())
98 .AddAttribute (
"DoSAttackIntensity",
99 "The time elapsed between successive malicious requests; For testing DoS/DDoS attacks;",
103 .AddAttribute (
"MinDataRate",
"The minimal data key rate (encryption+authentication) of the app (QoS settings).",
108 .AddAttribute (
"Priority",
109 "QoS Priority (0 - default, 1 - premium)",
112 MakeUintegerChecker<uint32_t> ())
113 .AddAttribute (
"TTL",
114 "QoS TTL - defines duration (seconds) of ETSI004 association",
117 MakeUintegerChecker<uint32_t> ())
120 .AddTraceSource (
"Tx",
"A new packet is created and is sent",
122 "ns3::Packet::TracedCallback")
123 .AddTraceSource (
"TxSig",
"A new signaling packet is created and is sent",
125 "ns3::Packet::TracedCallback")
126 .AddTraceSource (
"TxKMS",
"A new packet is created and is sent to local KMS",
128 "ns3::Packet::TracedCallback")
129 .AddTraceSource (
"Rx",
"A new packet is received",
131 "ns3::Packet::TracedCallback")
132 .AddTraceSource (
"RxSig",
"A new signaling packet is received",
134 "ns3::Packet::TracedCallback")
135 .AddTraceSource (
"RxKMS",
"A new packet is received from local KMS",
137 "ns3::Packet::TracedCallback")
138 .AddTraceSource (
"StateTransition",
139 "Trace fired upon every QKDApp state transition.",
141 "ns3::Application::StateTransitionCallback")
142 .AddTraceSource (
"PacketEncrypted",
143 "The change trance for currenly ecrypted packet",
145 "ns3::QKDCrypto::PacketEncrypted")
146 .AddTraceSource (
"PacketDecrypted",
147 "The change trance for currenly decrypted packet",
149 "ns3::QKDCrypto::PacketDecrypted")
150 .AddTraceSource (
"PacketAuthenticated",
151 "The change trance for currenly authenticated packet",
153 "ns3::QKDCrypto::PacketAuthenticated")
154 .AddTraceSource (
"PacketDeAuthenticated",
155 "The change trance for currenly deauthenticated packet",
157 "ns3::QKDCrypto::PacketDeAuthenticated")
158 .AddTraceSource (
"Mx",
"Missed send packet call",
160 "ns3::Packet::TracedCallback")
161 .AddTraceSource (
"KeyObtained",
"Trace amount of obtained key material",
163 "ns3::QKDApp004::KeyObtained")
181 : m_sendSignalingSocketApp (0),
182 m_sinkSignalingSocketApp (0),
183 m_sendDataSocketApp (0),
184 m_sinkDataSocketApp (0),
185 m_sendSocketToKMS (0),
186 m_sinkSocketFromKMS (0),
194 m_appState (NOT_STARTED)
198 m_random = CreateObject<UniformRandomVariable> ();
216 std::string socketType,
238 std::string socketType,
244 uint32_t nPacketsSize,
312 std::map<uint32_t, EventId >::iterator eventEntry =
m_scheduledEvents.find ( eventId );
527 NS_LOG_FUNCTION (
this <<
"QKDApp Connection from KMS requested on socket " << socket);
540 NS_LOG_FUNCTION (
this <<
"QKDApp Connection from KMS accepted on socket " << socket);
553 NS_LOG_FUNCTION (
this <<
"QKDApp Connection from APP accepted on socket " << s);
565 NS_LOG_FUNCTION (
this <<
"QKDApp Signaling Connection from APP accepted on socket " << s);
572 NS_LOG_FUNCTION (
this << socket <<
"QKDApp Connection to KMS succeeded via socket " << socket);
578 NS_LOG_FUNCTION (
this << socket <<
"QKDApp, Connection to KMS Failed via socket " << socket);
584 NS_LOG_FUNCTION (
this << socket <<
"QKDApp Connection to APP succeeded via socket " << socket);
590 NS_LOG_FUNCTION (
this << socket <<
"QKDApp, Connection to APP Failed via socket " << socket);
596 NS_LOG_FUNCTION (
this << socket <<
"QKDApp Signaling Connection to APP succeeded via socket " << socket);
602 NS_LOG_FUNCTION (
this << socket <<
"QKDApp, Connection to APP Failed via socket " << socket);
681 while ((packet = socket->
RecvFrom (from)))
689 << packet <<
"PACKETID: " << packet->
GetUid()
690 <<
" of size: " << packet->
GetSize()
696 <<
"s packet from KMS received "
697 << packet->
GetSize () <<
" bytes from "
745 if(it->packet != 0) {
760 std::string receivedStatus = p->
ToString();
767 if (receivedStatus.find(
"Fragment") != std::string::npos) {
771 std::make_pair (from, Create<Packet> (0))
774 buffer = itBuffer->second;
785 uint8_t *b1 =
new uint8_t[buffer->
GetSize ()];
787 std::string requestString = std::string((
char*)b1);
795 parser.
Parse(&request, requestString);
809 <<
") from buffer of size " << buffer->
GetSize ()
813 uint8_t *b2 =
new uint8_t[completePacket->
GetSize ()];
815 std::string completePacketString = std::string((
char*)b2);
818 parser.
Parse(&completePacketHttp, completePacketString);
844 while ((packet = socket->
RecvFrom (from)))
852 <<
"PACKETID: " << packet->
GetUid()
853 <<
" of size: " << packet->
GetSize()
859 <<
"s packet from APP pair received "
860 << packet->
GetSize () <<
" bytes from "
884 itBuffer =
m_buffer_qkdapp.insert (std::make_pair (from, Create<Packet> (0))).first;
887 buffer = itBuffer->second;
931 while ((packet = socket->
RecvFrom (from)))
939 <<
"PACKETID: " << packet->
GetUid()
940 <<
" of size: " << packet->
GetSize()
946 <<
"s signaling packet from APP pair received "
947 << packet->
GetSize () <<
" bytes from "
960 std::string receivedStatus = p->
ToString();
964 if (receivedStatus.find(
"Fragment") != std::string::npos) {
968 std::make_pair (from, Create<Packet> (0))
971 buffer = itBuffer->second;
982 uint8_t *b1 =
new uint8_t[buffer->
GetSize ()];
984 std::string requestString = std::string((
char*)b1);
988 parser.
Parse(&request, requestString);
1001 uint8_t *b2 =
new uint8_t[completePacket->
GetSize ()];
1003 std::string s2 = std::string((
char*)b2);
1006 parser.
Parse(&request2, s2);
1023 NS_LOG_FUNCTION (
this <<
"QKDApp Data to KMS Sent via socket " << socket);
1068 bool encAssociation =
true;
1069 bool authAssociation =
true;
1071 encAssociation =
false;
1073 authAssociation =
false;
1076 NS_LOG_FUNCTION(
this <<
"All necessary associations are established" );
1080 NS_LOG_FUNCTION(
this <<
"Necessary associations are NOT yet established" );
1088 bool encQueueReady =
false;
1089 bool authQueueReady =
false;
1093 encQueueReady =
true;
1098 authQueueReady =
true;
1100 if(authQueueReady && encQueueReady){
1107 NS_LOG_FUNCTION(
this <<
"Both Primary and Replica QKDApp established queues!" );
1111 NS_LOG_FUNCTION(
this <<
"Primary QKDApp establihed queues! Waiting on Replica QKDApp ..." );
1128 std::map<uint32_t, QKDAppKey>::iterator it =
m_associations.first.buffer.begin();
1131 NS_LOG_FUNCTION(
this <<
"The lifetime of the first key is " << (it->second).lifetime );
1133 output = it->second;
1137 uint32_t counter = 0;
1141 NS_LOG_FUNCTION(
this <<
"Key " << counter++ <<
" of size " << output.
key.size() <<
" and lifetime " << (it2->second).lifetime );
1142 if(int32_t ((it2->second).lifetime) <= 0)
1145 NS_LOG_FUNCTION(
this <<
"Local encryption key erased " << it2->first <<
". Key lifetime expired!" );
1167 encKey = it->second;
1169 std::map<uint32_t, QKDAppKey>::iterator a =
m_associations.first.buffer.begin(),
1172 NS_LOG_FUNCTION(
this <<
"Local encryption key store entry (test - krecS)" << a->first );
1176 NS_LOG_FUNCTION(
this <<
"Local encryption key erased " << it1->first <<
". Synchronization!" );
1193 std::map<uint32_t, QKDAppKey>::iterator it =
m_associations.second.buffer.begin();
1198 std::map<uint32_t, QKDAppKey>::iterator a =
m_associations.second.buffer.begin(),
1201 NS_LOG_FUNCTION(
this <<
"Local authentication key store entry (test - krecM)" << a->first << a->second.key.size());
1205 NS_LOG_FUNCTION(
this <<
"Local authentication key erased " << it->first );
1220 authKey = it->second;
1222 NS_LOG_FUNCTION(
this <<
"Local authentication key erased " << it1->first );
1285 std::make_pair(ksid, keyType)
1295 std::map<std::string, std::pair<std::string, uint32_t> >::iterator it =
m_httpRequestsKMS.find(uri);
1308 std::string delimiter =
"/";
1310 std::vector<std::string> uriParams;
1311 while ((pos = uri.find(delimiter)) != std::string::npos) {
1312 token = uri.substr(0, pos);
1313 if(token.length() > 0){
1314 uriParams.push_back(token);
1316 uri.erase(0, pos + delimiter.length());
1318 if(uri.length() > 0){
1319 uriParams.push_back(uri);
1321 for(uint32_t i=0; i< uriParams.size(); i++){
1322 if(uriParams[i] ==
"open_connect"){
1324 }
else if(uriParams[i] ==
"get_key"){
1326 }
else if(uriParams[i] ==
"close"){
1340 uri =
"http://" + uri;
1341 std::map<std::string, std::pair<std::string, uint32_t> >::iterator it =
m_httpRequestsKMS.find(uri);
1343 return it->second.first;
1348 std::string delimiter =
"/";
1350 std::vector<std::string> uriParams;
1351 while ((pos = uri.find(delimiter)) != std::string::npos) {
1352 token = uri.substr(0, pos);
1353 if(token.length() > 0){
1354 uriParams.push_back(token);
1356 uri.erase(0, pos + delimiter.length());
1358 if(uri.length() > 0){
1359 uriParams.push_back(uri);
1361 for(uint32_t i=0; i< uriParams.size(); i++){
1363 if(uriParams[i] ==
"open_connect" || uriParams[i] ==
"get_key" || uriParams[i] ==
"close"){
1364 return uriParams[i-1];
1376 uri =
"http://" + uri;
1378 std::map<std::string, std::pair<std::string, uint32_t> >::iterator it =
m_httpRequestsKMS.find(uri);
1380 return it->second.second;
1407 std::string message;
1417 std::ostringstream lkmsAddressTemp;
1418 lkmsAddress.
Print(lkmsAddressTemp);
1419 std::string headerUri =
"http://" + lkmsAddressTemp.str();
1434 {
"key_chunk_size", 100},
1438 message = msgBody.dump();
1443 std::string hMessage = httpMessage.
ToString();
1445 (uint8_t*) (hMessage).c_str(),
1455 <<
" with payload: " << message
1485 if(m_encryptionTypeInt < 0 || m_encryptionTypeInt > 2){
1487 <<
". Allowed values are (0-unencrypted, 1-OTP, 2-AES)" );
1489 if(m_authenticationTypeInt < 0 || m_authenticationTypeInt > 3){
1491 <<
". Allowed values are (0-unauthenticated, 1-VMAC, 2-MD5, 3-SHA1)" );
1495 <<
". The value must be larger than zero." );
1498 <<
". The value must be larger than one packet size " <<
m_packetSize );
1514 <<
" for StartApplication()." );
1553 NS_LOG_FUNCTION(
this <<
"Data and signaling sockets are closed. Data transmission is stopped ..." );
1581 if(encKey.
key ==
""){
1590 if(authKey.
key ==
""){
1598 NS_LOG_FUNCTION(
this <<
"\nEncryption Key (krec)" << encKey.
key <<
"\nAuthentication Key (krec)" << authKey.
key);
1602 NS_LOG_FUNCTION(
this <<
"Confidential message" << confidentialMsg.size() << confidentialMsg );
1604 std::string encryptedMsg;
1605 std::string authTag;
1608 encryptedMsg =
m_encryptor->EncryptMsg(confidentialMsg, encKey.
key);
1610 <<
"Encrypted message" <<
m_encryptor->Base64Encode(encryptedMsg));
1616 <<
"Authentication tag" << authTag );
1620 encryptedMsg = confidentialMsg;
1629 std::string msg = encryptedMsg;
1630 Ptr<Packet> packet = Create<Packet> ( (uint8_t*) msg.c_str(), msg.length() );
1683 std::string decryptedMsg;
1684 bool authSuccessful =
false;
1686 NS_LOG_FUNCTION(
this <<
"Executing authentication check on received packet!" );
1691 NS_LOG_FUNCTION(
this <<
"Synchronization - calling get_key request" );
1696 if(authKey.
key ==
""){
1702 NS_LOG_FUNCTION(
this <<
"Authentication key obtained from the local key store" << authKey.
index << authKey.
key );
1706 authSuccessful =
true;
1709 authSuccessful =
true;
1714 authSuccessful =
true;
1717 authSuccessful =
true;
1720 authSuccessful =
true;
1723 NS_LOG_FUNCTION(
this <<
"Packet is successfully authenticated! Processing ... " );
1725 NS_LOG_FUNCTION(
this <<
"Authentication of received packet FAILED. Packet is dropped!" );
1732 NS_LOG_FUNCTION(
this <<
"Synchronization - calling get_key request" );
1737 if(encKey.
key ==
""){
1747 NS_LOG_FUNCTION(
this <<
"Packet decrypted! Decrypted message: \n" << decryptedMsg );
1755 NS_LOG_FUNCTION(
this <<
"Packet received unprotected! Received message: \n" << payload );
1760 NS_FATAL_ERROR(
this <<
"Only Replica QKDApp receives protected packets! Only unidirectional secure data communication!" );
1784 NS_FATAL_ERROR (
this <<
"Invalid ETSI QKD GS 004 function used in request");
1819 uint32_t keySize {0};
1835 {
"max_bps", maxRate},
1836 {
"min_bps", minRate},
1839 {
"key_chunk_size", keySize},
1844 msgBody[
"Key_stream_ID"] = ksid;
1846 msgBody[
"QoS"][
"key_chunk_size"] = keySize;
1849 std::string message = msgBody.dump();
1852 std::ostringstream lkmsAddressTemp;
1853 lkmsAddress.
Print(lkmsAddressTemp);
1854 std::string headerUri =
"http://" + lkmsAddressTemp.str();
1860 std::string hMessage = httpMessage.
ToString();
1862 (uint8_t*) (hMessage).c_str(),
1868 <<
" of size: " << packet->
GetSize()
1876 kmsPacket.
packet = packet;
1878 kmsPacket.
uri = headerUri;
1881 kmsPacket.
ksid =
"";
1884 kmsPacket.
ksid = ksid;
1905 std::ostringstream lkmsAddressTemp;
1906 lkmsAddress.
Print(lkmsAddressTemp);
1907 std::string headerUri =
"http://" + lkmsAddressTemp.str();
1911 msgBody[
"Key_stream_ID"] = ksid;
1912 std::string message = msgBody.dump();
1917 std::string hMessage = httpMessage.
ToString();
1919 (uint8_t*) (hMessage).c_str(),
1925 <<
" of size: " << packet->
GetSize()
1934 kmsPacket.
packet = packet;
1937 kmsPacket.
ksid = ksid;
1938 kmsPacket.
uri = headerUri;
1956 NS_LOG_FUNCTION(
this <<
"Encryption key stream association closed on QKDApp side!");
1959 NS_LOG_FUNCTION(
this <<
"Authentication key stream association closed on QKDApp side!");
1961 NS_FATAL_ERROR(
this <<
"Closing association failed. Ksid not registered" << ksid );
1965 std::ostringstream lkmsAddressTemp;
1966 lkmsAddress.
Print(lkmsAddressTemp);
1967 std::string headerUri =
"http://" + lkmsAddressTemp.str ();
1968 headerUri +=
"/api/v1/keys/" + ksid +
"/close";
1973 std::string hMessage = httpMessage.
ToString();
1975 (uint8_t*) (hMessage).c_str(),
1981 <<
" of size: " << packet->
GetSize()
1990 kmsPacket.
packet = packet;
1993 kmsPacket.
ksid = ksid;
1994 kmsPacket.
uri = headerUri;
2014 if(!payload.empty()){
2016 jOpenConnect = nlohmann::json::parse(payload);
2027 responseStatus == HTTPMessage::HttpStatus::BadRequest ||
2028 responseStatus == HTTPMessage::HttpStatus::Unauthorized ||
2029 responseStatus == HTTPMessage::HttpStatus::ServiceUnavailable
2049 }
else if(responseStatus == HTTPMessage::HttpStatus::Ok){
2054 if(jOpenConnect.contains(
"Key_stream_ID")) ksid = jOpenConnect[
"Key_stream_ID"];
2059 NS_LOG_FUNCTION(
this <<
"KSID " << ksid <<
" registered for encryption" );
2062 NS_LOG_FUNCTION(
this <<
"KSID " << ksid <<
" registered for authentication" );
2076 <<
"Unknown ksid: " << ksid <<
"\t"
2085 NS_FATAL_ERROR(
this <<
"Unsupported error status code" << responseStatus <<
"of response.");
2098 if(!payload.empty()){
2100 jGetKeyResponse = nlohmann::json::parse(payload);
2108 responseStatus == HTTPMessage::HttpStatus::BadRequest ||
2109 responseStatus == HTTPMessage::HttpStatus::Unauthorized ||
2110 responseStatus == HTTPMessage::HttpStatus::ServiceUnavailable
2125 }
else if(responseStatus == HTTPMessage::HttpStatus::Ok){
2126 uint32_t index = -1;
2128 if (jGetKeyResponse.contains(
"index"))
2129 index = jGetKeyResponse[
"index"];
2130 if (jGetKeyResponse.contains(
"Key_buffer"))
2131 key = jGetKeyResponse[
"Key_buffer"];
2140 appKey.
index = index;
2144 m_associations.first.buffer.insert( std::make_pair(index, appKey) );
2146 m_associations.second.buffer.insert( std::make_pair(index, appKey) );
2148 NS_FATAL_ERROR(
this <<
"Association with ksid" << ksid <<
"does not exist on QKDApp" );
2163 NS_FATAL_ERROR(
this <<
"Unsupported status code" << responseStatus <<
" of the response.");
2183 responseStatus == HTTPMessage::HttpStatus::BadRequest ||
2184 responseStatus == HTTPMessage::HttpStatus::Unauthorized ||
2185 responseStatus == HTTPMessage::HttpStatus::ServiceUnavailable
2187 NS_LOG_FUNCTION(
this <<
"QKDApp received error message on CLOSE method" );
2190 }
else if(responseStatus == HTTPMessage::HttpStatus::Ok){
2191 NS_LOG_FUNCTION(
this <<
"Application successfully closed association " << ksid );
2195 NS_FATAL_ERROR(
this <<
"Unsupported error status code" << responseStatus <<
"of response.");
2203 NS_LOG_FUNCTION(
this <<
"Processing singnaling packet received from peer QKDApp" );
2209 if(methodType == 0){
2210 NS_LOG_FUNCTION(
this <<
"SEND_KSID: Primary QKDApp received response from Replica QKDApp." );
2213 }
else if (methodType == 1){
2214 NS_LOG_FUNCTION(
this <<
"ESTABLISH_QUEUES: Primary QKDApp received response from Replica QKDApp. Packet ID" );
2221 std::string s = header.
GetUri();
2222 std::string delimiter =
"/";
2226 std::vector<std::string> uriParams;
2227 while((pos = s.find(delimiter)) != std::string::npos){
2228 token = s.substr(0, pos);
2229 if(token.length() > 0){
2230 uriParams.push_back(token);
2232 s.erase(0, pos + delimiter.length());
2235 uriParams.push_back(s);
2238 std::string requestType;
2240 uriParams.size() > 3 &&
2241 uriParams[1] ==
"api" &&
2242 uriParams[2] ==
"v1"
2244 requestType = uriParams[4];
2249 if(requestType ==
"connect"){
2252 std::string ksid = uriParams[5];
2254 std::string cryptoT = uriParams[6];
2259 else if(cryptoT ==
"1")
2269 }
else if(requestType ==
"establish_queues") {
2275 NS_FATAL_ERROR(
this <<
"Invalid method received on app. RequestType:" << requestType << s );
2302 std::stringstream ss;
2303 m_peerAddress.
Print(ss);
2304 std::string headerUri =
"http://" + ss.str();
2314 std::string hMessage = httpMessage.
ToString();
2316 (uint8_t*) (hMessage).c_str(),
2327 NS_LOG_FUNCTION(
this <<
"SEND_KSID: Primary QKDApp sends KSID to Replica QKDApp" <<
2328 headerUri <<
". Packet ID" << packet->
GetUid() );
2334 NS_LOG_FUNCTION(
this <<
"Sending response on SEND_KSID to Primary QKDApp" << httpStatus << msg );
2345 {
"Content-Type",
"application/json; charset=utf-8"}
2351 std::string hMessage = httpMessage.
ToString();
2353 (uint8_t*) (hMessage).c_str(),
2363 NS_LOG_FUNCTION(
this <<
"SEND_KSID: Replica QKDApp sends respose to Primary QKDApp. Packet ID"
2370 NS_LOG_FUNCTION(
this <<
"Processing /connect response (send_ksid)" );
2372 if(header.
GetStatus() == HTTPMessage::HttpStatus::Ok){
2379 NS_LOG_FUNCTION(
this <<
"Association successfully established between QKDApps " << ksid );
2391 NS_LOG_FUNCTION(
this <<
"Primary QKDApp sending establish_queues notification to Replica QKDApp" );
2395 std::stringstream ss;
2396 m_peerAddress.
Print(ss);
2397 std::string headerUri =
"http://" + ss.str();
2398 headerUri +=
"/api/v1/" + this->
GetId().
string() +
"/establish_queues";
2403 std::string hMessage = httpMessage.
ToString();
2405 (uint8_t*) (hMessage).c_str(),
2424 NS_LOG_FUNCTION(
this <<
"Replica QKDApp sending response on /fill indicating success" );
2430 std::string hMessage = httpMessage.
ToString();
2432 (uint8_t*) (hMessage).c_str(),
2474 NS_LOG_FUNCTION(
this <<
"Clearing key stream association on QKDApp" << ksid );
2486 NS_LOG_FUNCTION(
this <<
"Key stream association " << ksid <<
" cleared!" );
2529 "for AppTransitionTree()!" );
2544 "for AppTransitionTree()!" );
2564 return "NOT_STARTED";
2567 return "INITIALIZED";
2570 return "ESTABLISHING_ASSOCIATIONS";
2573 return "ASSOCIATIONS_ESTABLISHED";
2576 return "ESTABLISHING_KEY_QUEUES";
2579 return "KEY_QUEUES_ESTABLISHED";
2591 return "DECRYPT_DATA";
2598 return "FATAL_ERROR";
2618 if (oldState ==
"SEND_DATA" && newState ==
"READY") {
2622 state = QKDApp004::QKDAppState::WAIT;
2641 uint32_t encryptionType,
2642 uint32_t authenticationType,
2643 uint32_t authenticationTagLengthInBits
2646 NS_LOG_FUNCTION (
this << encryptionType << authenticationType << authenticationTagLengthInBits);
2648 switch (encryptionType){
2660 switch (authenticationType){
2679 authenticationTagLengthInBits
2685 authenticationTagLengthInBits
2700 std::string confidentialMessage;
2701 static const char alphanum[] =
2703 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2704 "abcdefghijklmnopqrstuvwxyz";
2706 uint32_t randVal = 0;
2707 for (uint32_t i = 0; i < msgLength; ++i){
2709 confidentialMessage += alphanum[ randVal ];
2712 return confidentialMessage;
2727 return CryptoPP::AES::MAX_KEYLENGTH * 8;
2754 rate = CryptoPP::AES::MAX_KEYLENGTH * 8;
2781 rate = CryptoPP::AES::DEFAULT_KEYLENGTH * 8;
2819 rate = CryptoPP::AES::DEFAULT_KEYLENGTH * 8;
2830 rate = CryptoPP::AES::DEFAULT_KEYLENGTH * 8;
2856 uint8_t *buffer =
new uint8_t[packet->
GetSize ()];
2858 std::string payload = std::string((
char*)buffer, packet->
GetSize());
a polymophic address class
The base class for all ns3 applications.
Ptr< Node > GetNode() const
Class for representing data rates.
uint64_t GetBitRate() const
Get the underlying bitrate.
AttributeValue implementation for DataRate.
An identifier for simulation events.
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
The basic class to represent both HTTP requests and responses.
std::string GetRequestUri() const
std::string ToString()
Takes the headers added to the message along with the body and outputs it to a std::string for use in...
std::string GetUri() const
Grab the uri.
void CreateRequest(const std::string &url, const std::string &method)
std::string GetMessageBodyString()
size_t GetContentLength()
Return the size of the binary body vector.
void CreateResponse(const HttpStatus status)
HTTPMessage::HttpStatus GetStatus()
To be returned with a status code in a response is a status text describing the status code by text r...
uint32_t GetHeadersSize()
std::string GetStatusMessage() const
Get the current status message for this message.
A basic class to parse a HTTP message, both request and response.
void Parse(HTTPMessage *httpMessage, const std::string &buffer)
Parse a std::string to a HTTP message.
uint16_t GetPort(void) const
Ipv4Address GetIpv4(void) const
static bool IsMatchingType(const Address &address)
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.
void Print(std::ostream &os) const
Print this address to the given output stream.
static Ipv4Address GetAny(void)
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
void AddHeader(const Header &header)
Add header to this packet.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
std::string ToString(void) const
Return a string representation of the packet.
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
uint64_t GetUid(void) const
Returns the packet's Uid.
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Establish secure communication on application lavel to use the key and test LKSM.
void ProcessDataPacketFromApp(QKDAppHeader header, Ptr< Packet > packet, Ptr< Socket > socket)
Process data packets from the peer QKD application.
void HandlePeerErrorFromKMS(Ptr< Socket > socket)
Handle a connection error from the KMS.
Ptr< Socket > m_sinkSignalingSocketApp
The receiving socket for the signaling messages.
virtual void StopApplication(void)
Application specific shutdown code.
void HandlePeerCloseFromApp(Ptr< Socket > socket)
Handle a connection close from the peer QKD application.
double m_delay
The time interval between two successive data transmissions (calculated based on the application data...
TracedCallback< Ptr< const Packet > > m_rxSigTrace
A trace for received signaling packets.
void HandleReadFromApp(Ptr< Socket > socket)
Handle a packet received from the peer QKD application.
UUID m_dstSaeId
The peer application identifier.
TracedCallback< Ptr< Packet >, std::string > m_deauthenticationTrace
A trace callback for the authentication check event.
void CancelScheduledAction(uint32_t eventId)
Cancel the scheduled event.
void ConnectionToKMSSucceeded(Ptr< Socket > socket)
Callback function after the connection to the KMS is complete.
std::string GetAppStateString() const
Get the current state of the application in a string notation.
QKDAppState m_appState
The application state.
QKDAppKey GetAuthKey()
Get the authentication key from the queue.
void Http004AppQueryComplete(void)
Remove the request from the vector of HTTP requests made to the peer QKD application.
DataRate m_dataRate
The application data rate.
void ConnectionToKMSFailed(Ptr< Socket > socket)
Callback function after the connection to the KMS has failed.
void HandleAcceptFromKMS(Ptr< Socket > s, const Address &from)
Handle an incoming connection from the KMS.
uint32_t m_useCrypto
Execute actual cryptographic algorithms?
void SendPacket(void)
Send the application packet (includes the generation of a random message and optional encryption or/a...
void OpenConnect(std::string ksid, uint32_t keyType=0)
Request a key stream session (an association) from the local KMS.
uint32_t GetMethodFromHttp004AppQuery(void)
Map the HTTP response from the peer QKD application and obtain the ETSI method type.
void PrepareSinkSocketFromKMS()
Prepare the sink socket to listen from the KMS Application.
void RegisterAckTime(Time oldRtt, Time newRtt)
Register the acknowledgement time.
Address m_localSignaling
The local address for the signaling data transmission.
void SendMaliciousRequestToKMS()
Send a malicious request to the KMS.
static TypeId GetTypeId(void)
Get the type ID.
uint32_t m_keyBufferLengthEncryption
The size of the encryption key queue at the application layer.
void ProcessSignalingPacketFromApp(HTTPMessage &header, Ptr< Socket > socket)
Process a signaling packets from the peer QKD application.
Time m_dosAttackIntensity
The intensity of the DoS attack.
QKDAppState
The QKD application states.
@ ESTABLISHING_ASSOCIATIONS
@ ASSOCIATIONS_ESTABLISHED
@ ESTABLISHING_KEY_QUEUES
void ProcessOpenConnectResponse(HTTPMessage &header)
Process the OPEN_CONNECT response.
void ProcessGetKeyResponse(HTTPMessage &header)
Process the GET_KEY response.
TracedCallback< Ptr< Packet >, std::string > m_authenticationTrace
A trace callback for the authentication event.
UUID m_id
The application identifier.
uint32_t m_keyBufferLengthAuthentication
The size of the authentication key queue at the application layer.
uint32_t m_packetsSent
The number of sent data packets.
std::map< uint32_t, EventId > m_scheduledEvents
The map of scheduled events.
TracedCallback< Ptr< Packet > > m_encryptionTrace
A trace callback for the encryption event.
Address m_peer
The address of the peer for the data transmission.
void Http004KMSQueryComplete(std::string uri)
Remove the request from the vector of HTTP requests made to the KMS.
void GetKeyFromKMS(std::string ksid, uint32_t index=0)
Get key for the key stream.
ns3::TracedCallback< const std::string &, const std::string & > m_stateTransitionTrace
A trace for the application state transitions.
uint32_t GetKeyTypeFromHttp004KMSQuery(std::string uri)
Map the HTTP reponse from the KMS and obtain the key type.
std::string m_socketType
The sockets type.
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer_qkdapp
The buffer for received data packets (fragmentation).
uint32_t m_packetSize
The data packet size.
void DataToKMSSend(Ptr< Socket >, uint32_t)
Callback function to notify that data to KMS has been sent.
TracedCallback< Ptr< const Packet > > m_txSigTrace
A trace for transmitted signaling packets.
void PrepareSinkSocketFromApp()
Prepare the sink socket to listen from the peer QKD Application.
void HandleAcceptSignalingFromApp(Ptr< Socket > s, const Address &from)
Handle a signaling incoming connection from the peer QKD application.
uint32_t m_aesLifetime
The AES key lifetime.
void ClearAssociation(std::string ksid)
Delete all records of key stream session identified with a given KSID.
bool m_primaryQueueEstablished
Is the queue established at the sender application?
void ProcessSendKsidResponse(HTTPMessage &header, std::string ksid)
Process the SEND_KSID response.
virtual ~QKDApp004()
Destructor.
Ptr< UniformRandomVariable > m_random
The uniform random variable.
void HandleReadSignalingFromApp(Ptr< Socket > socket)
Handle a signaling packet received from the peer QKD application.
virtual void StartApplication(void)
EventId m_closeSocketEvent
The closing socket event.
TracedCallback< const uint32_t & > m_obtainedKeyMaterialTrace
A trace callback for the obtained key material.
void ProcessCreateQueuesResponse()
Start establishing key queues at the reciving application once requested by the sender.
std::string GetKsidFromHttp004AppQuery(void)
Map the HTTP response from the peer QKD application and obtain the key stream identifier.
Ptr< Socket > m_sendDataSocketApp
The sending socket for the data.
void HandleAcceptFromApp(Ptr< Socket > s, const Address &from)
Handle an incoming connection from the peer QKD application.
uint32_t GetMethodFromHttp004KMSQuery(std::string uri)
Read the ETSI request method from the URI.
Address m_peerSignaling
The address of the peer for the signaling data transmission.
QKDEncryptor::EncryptionType m_encryptionType
The encryption algorithm.
Ptr< Packet > m_maliciousPacket
The malicious packet.
uint32_t GetEncryptionKeySize()
Get the required key size for the choosen encryption algorithm.
void ConnectionSignalingToAppFailed(Ptr< Socket > socket)
Callback function after the signaling connection to the APP has failed.
Address m_kms
The local KMS address.
EventId m_sendEvent
The data transmission event.
void Close(std::string ksid)
Close the keys stream session (the association).
void HandlePeerErrorSignalingFromApp(Ptr< Socket > socket)
Handle a signaling connection error from the peer QKD application.
Ptr< Socket > m_sinkSocketFromKMS
The receiving socket from the KMS.
void InitializeAssociations()
Initialize the key stream sessions.
uint32_t m_ttl
The time-to-live of the key stream session.
void ProcessPacketsToKMSFromQueue()
Process and send any remaining packets to the KMS.
void CloseSocketToKms()
Close the connecting sockets with the KMS.
uint32_t GetAuthenticationKeySize()
Get the required key size for the choosen authentication algorithm.
std::pair< Association004, Association004 > m_associations
A pair (encryption/authentication) of the establihed key stream session.
bool ConnectionRequestedFromKMS(Ptr< Socket > socket, const Address &address)
Callback function after the connection for response from the KMS has been received.
uint32_t m_dataSent
The amount of the sent data.
void PrepareSendSocketToKMS()
Prepare the send socket to communicate with the KMS Application.
uint64_t GetMaxEncryptionKeyRate()
Get the maximum key rate required for the encryption (QoS settings).
void ProcessCloseResponse(HTTPMessage &header)
Process the CLOSE response.
void PacketReceivedFromKMS(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Check for the tcp segmentation of packets received from the KMS.
std::string GetPacketContent(uint32_t msgLength=0)
Generate a random packet payload (the message).
bool m_replicaQueueEstablished
Is the queue established at the receiver application?
TracedCallback< Ptr< const Packet > > m_rxKmsTrace
A trace for received packets from the KMS.
void Http004KMSQuery(std::string uri, std::string ksid, uint32_t keyType)
Memories the HTTP request made to the local KMS.
void ConnectionSignalingToAppSucceeded(Ptr< Socket > socket)
Callback function after the signaling connection to the APP is complete.
void ConnectionToAppSucceeded(Ptr< Socket > socket)
Callback function after the connection to the APP is complete.
Time m_holdTime
The holding time before closing sockets.
std::map< std::string, std::pair< std::string, uint32_t > > m_httpRequestsKMS
A vector of HTTP requests set to the KMS.
std::vector< std::pair< uint32_t, std::string > > m_httpRequestsApp
A vector of HTTP requests sent to the peer application.
Ptr< Socket > m_sendSocketToKMS
The sending socket to the KMS.
TracedCallback< Ptr< const Packet > > m_txKmsTrace
A trace for transmitted packets to the KMS.
TracedCallback< Ptr< const Packet >, std::string > m_mxTrace
A trace for the missed time slots to send data (due to the lack of keys).
TypeId m_tid
The type identifier.
void SignalingPacketReceivedFromApp(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Check for the tcp segmentation of the signaling packets received from the peer application.
QKDAppState GetAppState() const
Get the current state of the application.
void HandlePeerErrorFromApp(Ptr< Socket > socket)
Handle a connection error from the peer QKD application.
uint64_t GetMaxAuthenticationKeyRate()
Get the maximum key rate required for the authentication (QoS settings).
QKDEncryptor::AuthenticationType m_authenticationType
The authentication algorithm.
void CreateKeyQueuesResponse()
Once the receiving application establishes the queues, it sends a response to the sender application.
Ptr< QKDEncryptor > m_encryptor
The QKD encryptor.
void HandlePeerCloseSignalingFromApp(Ptr< Socket > socket)
Handle a signaling connection close from the peer QKD application.
uint32_t m_priority
The application priority (QoS).
std::string GetKsidFromHttp004KMSQuery(std::string uri)
Map the HTTP response from the KMS and obtain the key stream identifier.
uint32_t m_authenticationTagLengthInBits
The size of the authentication tag in bits (32 by default).
Address m_local
The local address for the data transmission.
void SetEncryptionAndAuthenticationSettings(uint32_t encryptionType, uint32_t authenticationType, uint32_t authenticationTagLengthInBits)
Set the encryption and the authentication algorithms.
void SendKsidResponse(HTTPMessage::HttpStatus httpStatus, std::string msg="")
Send a response on the SEND_KSID request.
uint32_t m_master
Is a master (sender/primary) application?
void CreateKeyQueues()
Create the required key queues to store a set amount of keys from the respective key stream sessions.
void ProcessResponseFromKMS(HTTPMessage &header, Ptr< Packet > packet, Ptr< Socket > socket)
Process a response from the KMS application.
void HandlePeerCloseToKMS(Ptr< Socket > socket)
Handle a connection close to the KMS.
void SwitchAppState(QKDAppState state)
Change the state of the application.
void CheckQueues()
Request new keys from the KMS until the key queues at the application layer are established with a se...
void CheckAssociationsState()
Check if the required key stream sessions are successfuly established.
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer_sig
The buffer for the received signaling packets (fragmentation).
void ConnectionToAppFailed(Ptr< Socket > socket)
Callback function after the connection to the APP has failed.
void CreateKeyStreamAssociations()
void HandlePeerCloseFromKMS(Ptr< Socket > socket)
Handle a connection close from the KMS.
TracedCallback< Ptr< Packet > > m_decryptionTrace
A trace callback for the decryption event.
UUID GetId(void)
Get the application identifier.
uint32_t m_malicious
Is a malicious application?
void AppTransitionTree(void)
Transition through a tree of the application states and trigger actions.
void HandleReadFromKMS(Ptr< Socket > socket)
Handle a packet received by the QKD application from the KMS application.
Ptr< Socket > m_sendSignalingSocketApp
The sending socket for the signaling messages.
std::string PacketToString(Ptr< Packet > packet)
Convert the packet to a string.
DataRate m_minDataRate
The minimum application data rate.
static uint32_t m_applicationCounts
The number of running applications.
QKDAppKey GetEncKey()
Get the encryption key from the queue.
Ptr< Socket > m_sinkDataSocketApp
The receiving socket for the data.
TracedCallback< Ptr< const Packet >, std::string > m_txTrace
void ScheduleTx(void)
Schedule the next time slot to send the data.
uint32_t m_encryptionTypeInt
The encryption algorithm.
TracedCallback< Ptr< const Packet >, std::string > m_rxTrace
A trace for received data packets.
void DataPacketReceivedFromApp(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Check for the tcp segmentation of the signaling packets received from the KMS.
void SendKsidRequest(std::string ksid, uint32_t input)
Inform the peer QKD application of the established key stream session.
void PrepareSendSocketToApp()
Prepare the send socket to communicate with the peer QKD Application.
std::vector< KMSPacket > m_queue_kms
The queue of packets waiting for the transmission to the KMS.
void Http004AppQuery(uint32_t methodType, std::string ksid)
Memories the HTTP request made to the peer QKD application.
void HandlePeerErrorToKMS(Ptr< Socket > socket)
Handle a connection error to the KMS.
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer_kms
The buffer for the received packets from the KMS (fragmentation).
void Setup(std::string socketType, Address src, Address dst, Address kms, UUID dstSaeId, std::string type)
Configure the application.
uint32_t m_authenticationTypeInt
The authentication algorithm.
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...
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now(void)
Return the current simulation virtual time.
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.
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
virtual int Listen(void)=0
Listen for incoming connections.
void SetDataSentCallback(Callback< void, Ptr< Socket >, uint32_t > dataSent)
Notify application when a packet has been sent from transport protocol (non-standard socket call)
virtual int GetPeerName(Address &address) const =0
Get the peer address of a connected socket.
virtual int ShutdownSend(void)=0
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
virtual int Close(void)=0
Close a socket.
void SetCloseCallbacks(Callback< void, Ptr< Socket > > normalClose, Callback< void, Ptr< Socket > > errorClose)
Detect socket recv() events such as graceful shutdown or error.
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
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...
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
static TypeId GetTypeId(void)
Get the type ID.
Simulation virtual time values and global simulation resolution.
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
AttributeValue implementation for TypeId.
Universally unique identifier (UUID)
static UUID Random()
Generate random UUID4 (randomly or pseudo-randomly generated version)
static UUID Sequential()
Generate sequential UUID1 (time based version)
std::string string() const
Get string from the current UUID in format "00000000-0000-0000-0000-000000000000".
static TypeId GetTypeId(void)
Get the type ID.
Hold an unsigned integer type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Ptr< const AttributeAccessor > MakeDataRateAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeDataRateChecker(void)
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeTypeIdChecker(void)
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Callback< R, Ts... > MakeNullCallback(void)
#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.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#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.
Time Seconds(double value)
Construct a Time in the indicated unit.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
basic_json<> json
default JSON class
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
A cryptographic key at the application layer.
static const uint32_t packetSize