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).",
106 MakeDataRateChecker ())
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 );
529 NS_LOG_FUNCTION (
this <<
"QKDApp Connection from KMS requested on socket " << socket);
542 NS_LOG_FUNCTION (
this <<
"QKDApp Connection from KMS accepted on socket " << socket);
555 NS_LOG_FUNCTION (
this <<
"QKDApp Connection from APP accepted on socket " << s);
567 NS_LOG_FUNCTION (
this <<
"QKDApp Signaling Connection from APP accepted on socket " << s);
574 NS_LOG_FUNCTION (
this << socket <<
"QKDApp Connection to KMS succeeded via socket " << socket);
580 NS_LOG_FUNCTION (
this << socket <<
"QKDApp, Connection to KMS Failed via socket " << socket);
586 NS_LOG_FUNCTION (
this << socket <<
"QKDApp Connection to APP succeeded via socket " << socket);
592 NS_LOG_FUNCTION (
this << socket <<
"QKDApp, Connection to APP Failed via socket " << socket);
598 NS_LOG_FUNCTION (
this << socket <<
"QKDApp Signaling Connection to APP succeeded via socket " << socket);
604 NS_LOG_FUNCTION (
this << socket <<
"QKDApp, Connection to APP Failed via socket " << socket);
683 while ((packet = socket->
RecvFrom (from)))
691 << packet <<
"PACKETID: " << packet->
GetUid()
692 <<
" of size: " << packet->
GetSize()
698 <<
"s packet from KMS received "
699 << packet->
GetSize () <<
" bytes from "
762 std::string receivedStatus = p->
ToString();
769 if (receivedStatus.find(
"Fragment") != std::string::npos) {
773 std::make_pair (from, Create<Packet> (0))
776 buffer = itBuffer->second;
787 uint8_t *b1 =
new uint8_t[buffer->
GetSize ()];
789 std::string requestString = std::string((
char*)b1);
797 parser.Parse(&request, requestString);
811 <<
") from buffer of size " << buffer->
GetSize ()
815 uint8_t *b2 =
new uint8_t[completePacket->
GetSize ()];
817 std::string completePacketString = std::string((
char*)b2);
820 parser.Parse(&completePacketHttp, completePacketString);
846 while ((packet = socket->
RecvFrom (from)))
854 <<
"PACKETID: " << packet->
GetUid()
855 <<
" of size: " << packet->
GetSize()
861 <<
"s packet from APP pair received "
862 << packet->
GetSize () <<
" bytes from "
886 itBuffer =
m_buffer_qkdapp.insert (std::make_pair (from, Create<Packet> (0))).first;
889 buffer = itBuffer->second;
933 while ((packet = socket->
RecvFrom (from)))
941 <<
"PACKETID: " << packet->
GetUid()
942 <<
" of size: " << packet->
GetSize()
948 <<
"s signaling packet from APP pair received "
949 << packet->
GetSize () <<
" bytes from "
962 std::string receivedStatus = p->
ToString();
966 if (receivedStatus.find(
"Fragment") != std::string::npos) {
970 std::make_pair (from, Create<Packet> (0))
973 buffer = itBuffer->second;
984 uint8_t *b1 =
new uint8_t[buffer->
GetSize ()];
986 std::string requestString = std::string((
char*)b1);
990 parser.Parse(&request, requestString);
1003 uint8_t *b2 =
new uint8_t[completePacket->
GetSize ()];
1005 std::string s2 = std::string((
char*)b2);
1008 parser.Parse(&request2, s2);
1025 NS_LOG_FUNCTION (
this <<
"QKDApp Data to KMS Sent via socket " << socket);
1070 bool encAssociation =
true;
1071 bool authAssociation =
true;
1073 encAssociation =
false;
1075 authAssociation =
false;
1078 NS_LOG_FUNCTION(
this <<
"All necessary associations are established" );
1082 NS_LOG_FUNCTION(
this <<
"Necessary associations are NOT yet established" );
1090 bool encQueueReady =
false;
1091 bool authQueueReady =
false;
1095 encQueueReady =
true;
1100 authQueueReady =
true;
1102 if(authQueueReady && encQueueReady){
1109 NS_LOG_FUNCTION(
this <<
"Both Primary and Replica QKDApp established queues!" );
1113 NS_LOG_FUNCTION(
this <<
"Primary QKDApp establihed queues! Waiting on Replica QKDApp ..." );
1130 std::map<uint32_t, QKDAppKey>::iterator it =
m_associations.first.buffer.begin();
1133 NS_LOG_FUNCTION(
this <<
"The lifetime of the first key is " << (it->second).lifetime );
1135 output = it->second;
1139 uint32_t counter = 0;
1143 NS_LOG_FUNCTION(
this <<
"Key " << counter++ <<
" of size " << output.
key.size() <<
" and lifetime " << (it2->second).lifetime );
1144 if(int32_t ((it2->second).lifetime) <= 0)
1147 NS_LOG_FUNCTION(
this <<
"Local encryption key erased " << it2->first <<
". Key lifetime expired!" );
1169 encKey = it->second;
1171 std::map<uint32_t, QKDAppKey>::iterator a =
m_associations.first.buffer.begin(),
1174 NS_LOG_FUNCTION(
this <<
"Local encryption key store entry (test - krecS)" << a->first );
1178 NS_LOG_FUNCTION(
this <<
"Local encryption key erased " << it1->first <<
". Synchronization!" );
1195 std::map<uint32_t, QKDAppKey>::iterator it =
m_associations.second.buffer.begin();
1200 std::map<uint32_t, QKDAppKey>::iterator a =
m_associations.second.buffer.begin(),
1203 NS_LOG_FUNCTION(
this <<
"Local authentication key store entry (test - krecM)" << a->first << a->second.key.size());
1207 NS_LOG_FUNCTION(
this <<
"Local authentication key erased " << it->first );
1222 authKey = it->second;
1224 NS_LOG_FUNCTION(
this <<
"Local authentication key erased " << it1->first );
1287 std::make_pair(ksid, keyType)
1297 std::map<std::string, std::pair<std::string, uint32_t> >::iterator it =
m_httpRequestsKMS.find(uri);
1310 std::string delimiter =
"/";
1312 std::vector<std::string> uriParams;
1313 while ((pos = uri.find(delimiter)) != std::string::npos) {
1314 token = uri.substr(0, pos);
1315 if(token.length() > 0){
1316 uriParams.push_back(token);
1318 uri.erase(0, pos + delimiter.length());
1320 if(uri.length() > 0){
1321 uriParams.push_back(uri);
1323 for(uint32_t i=0; i< uriParams.size(); i++){
1324 if(uriParams[i] ==
"open_connect"){
1326 }
else if(uriParams[i] ==
"get_key"){
1328 }
else if(uriParams[i] ==
"close"){
1342 uri =
"http://" + uri;
1343 std::map<std::string, std::pair<std::string, uint32_t> >::iterator it =
m_httpRequestsKMS.find(uri);
1345 return it->second.first;
1350 std::string delimiter =
"/";
1352 std::vector<std::string> uriParams;
1353 while ((pos = uri.find(delimiter)) != std::string::npos) {
1354 token = uri.substr(0, pos);
1355 if(token.length() > 0){
1356 uriParams.push_back(token);
1358 uri.erase(0, pos + delimiter.length());
1360 if(uri.length() > 0){
1361 uriParams.push_back(uri);
1363 for(uint32_t i=0; i< uriParams.size(); i++){
1365 if(uriParams[i] ==
"open_connect" || uriParams[i] ==
"get_key" || uriParams[i] ==
"close"){
1366 return uriParams[i-1];
1378 uri =
"http://" + uri;
1380 std::map<std::string, std::pair<std::string, uint32_t> >::iterator it =
m_httpRequestsKMS.find(uri);
1382 return it->second.second;
1409 std::string message;
1419 std::ostringstream lkmsAddressTemp;
1420 lkmsAddress.
Print(lkmsAddressTemp);
1421 std::string headerUri =
"http://" + lkmsAddressTemp.str();
1436 {
"key_chunk_size", 100},
1440 message = msgBody.dump();
1445 std::string hMessage = httpMessage.
ToString();
1447 (uint8_t*) (hMessage).c_str(),
1457 <<
" with payload: " << message
1487 if(m_encryptionTypeInt < 0 || m_encryptionTypeInt > 2){
1489 <<
". Allowed values are (0-unencrypted, 1-OTP, 2-AES)" );
1491 if(m_authenticationTypeInt < 0 || m_authenticationTypeInt > 3){
1493 <<
". Allowed values are (0-unauthenticated, 1-VMAC, 2-MD5, 3-SHA1)" );
1497 <<
". The value must be larger than zero." );
1500 <<
". The value must be larger than one packet size " <<
m_packetSize );
1516 <<
" for StartApplication()." );
1555 NS_LOG_FUNCTION(
this <<
"Data and signaling sockets are closed. Data transmission is stopped ..." );
1583 if(encKey.
key ==
""){
1592 if(authKey.
key ==
""){
1600 NS_LOG_FUNCTION(
this <<
"\nEncryption Key (krec)" << encKey.
key <<
"\nAuthentication Key (krec)" << authKey.
key);
1604 NS_LOG_FUNCTION(
this <<
"Confidential message" << confidentialMsg.size() << confidentialMsg );
1606 std::string encryptedMsg;
1607 std::string authTag;
1610 encryptedMsg =
m_encryptor->EncryptMsg(confidentialMsg, encKey.
key);
1612 <<
"Encrypted message" <<
m_encryptor->Base64Encode(encryptedMsg));
1618 <<
"Authentication tag" << authTag );
1622 encryptedMsg = confidentialMsg;
1631 std::string msg = encryptedMsg;
1632 Ptr<Packet> packet = Create<Packet> ( (uint8_t*) msg.c_str(), msg.length() );
1685 std::string decryptedMsg;
1686 bool authSuccessful =
false;
1688 NS_LOG_FUNCTION(
this <<
"Executing authentication check on received packet!" );
1693 NS_LOG_FUNCTION(
this <<
"Synchronization - calling get_key request" );
1698 if(authKey.
key ==
""){
1704 NS_LOG_FUNCTION(
this <<
"Authentication key obtained from the local key store" << authKey.
index << authKey.
key );
1708 authSuccessful =
true;
1711 authSuccessful =
true;
1716 authSuccessful =
true;
1719 authSuccessful =
true;
1722 authSuccessful =
true;
1725 NS_LOG_FUNCTION(
this <<
"Packet is successfully authenticated! Processing ... " );
1727 NS_LOG_FUNCTION(
this <<
"Authentication of received packet FAILED. Packet is dropped!" );
1734 NS_LOG_FUNCTION(
this <<
"Synchronization - calling get_key request" );
1739 if(encKey.
key ==
""){
1749 NS_LOG_FUNCTION(
this <<
"Packet decrypted! Decrypted message: \n" << decryptedMsg );
1757 NS_LOG_FUNCTION(
this <<
"Packet received unprotected! Received message: \n" << payload );
1762 NS_FATAL_ERROR(
this <<
"Only Replica QKDApp receives protected packets! Only unidirectional secure data communication!" );
1786 NS_FATAL_ERROR (
this <<
"Invalid ETSI QKD GS 004 function used in request");
1821 uint32_t keySize {0};
1837 {
"max_bps", maxRate},
1838 {
"min_bps", minRate},
1841 {
"key_chunk_size", keySize},
1846 msgBody[
"Key_stream_ID"] = ksid;
1848 msgBody[
"QoS"][
"key_chunk_size"] = keySize;
1851 std::string message = msgBody.dump();
1854 std::ostringstream lkmsAddressTemp;
1855 lkmsAddress.
Print(lkmsAddressTemp);
1856 std::string headerUri =
"http://" + lkmsAddressTemp.str();
1862 std::string hMessage = httpMessage.
ToString();
1864 (uint8_t*) (hMessage).c_str(),
1870 <<
" of size: " << packet->
GetSize()
1878 kmsPacket.
packet = packet;
1880 kmsPacket.
uri = headerUri;
1883 kmsPacket.
ksid =
"";
1886 kmsPacket.
ksid = ksid;
1907 std::ostringstream lkmsAddressTemp;
1908 lkmsAddress.
Print(lkmsAddressTemp);
1909 std::string headerUri =
"http://" + lkmsAddressTemp.str();
1913 msgBody[
"Key_stream_ID"] = ksid;
1914 std::string message = msgBody.dump();
1919 std::string hMessage = httpMessage.
ToString();
1921 (uint8_t*) (hMessage).c_str(),
1927 <<
" of size: " << packet->
GetSize()
1936 kmsPacket.
packet = packet;
1939 kmsPacket.
ksid = ksid;
1940 kmsPacket.
uri = headerUri;
1958 NS_LOG_FUNCTION(
this <<
"Encryption key stream association closed on QKDApp side!");
1961 NS_LOG_FUNCTION(
this <<
"Authentication key stream association closed on QKDApp side!");
1963 NS_FATAL_ERROR(
this <<
"Closing association failed. Ksid not registered" << ksid );
1967 std::ostringstream lkmsAddressTemp;
1968 lkmsAddress.
Print(lkmsAddressTemp);
1969 std::string headerUri =
"http://" + lkmsAddressTemp.str ();
1970 headerUri +=
"/api/v1/keys/" + ksid +
"/close";
1975 std::string hMessage = httpMessage.
ToString();
1977 (uint8_t*) (hMessage).c_str(),
1983 <<
" of size: " << packet->
GetSize()
1992 kmsPacket.
packet = packet;
1995 kmsPacket.
ksid = ksid;
1996 kmsPacket.
uri = headerUri;
2016 if(!payload.empty()){
2018 jOpenConnect = nlohmann::json::parse(payload);
2029 responseStatus == HTTPMessage::HttpStatus::BadRequest ||
2030 responseStatus == HTTPMessage::HttpStatus::Unauthorized ||
2031 responseStatus == HTTPMessage::HttpStatus::ServiceUnavailable
2051 }
else if(responseStatus == HTTPMessage::HttpStatus::Ok){
2056 if(jOpenConnect.contains(
"Key_stream_ID")) ksid = jOpenConnect[
"Key_stream_ID"];
2061 NS_LOG_FUNCTION(
this <<
"KSID " << ksid <<
" registered for encryption" );
2064 NS_LOG_FUNCTION(
this <<
"KSID " << ksid <<
" registered for authentication" );
2078 <<
"Unknown ksid: " << ksid <<
"\t"
2087 NS_FATAL_ERROR(
this <<
"Unsupported error status code" << responseStatus <<
"of response.");
2100 if(!payload.empty()){
2102 jGetKeyResponse = nlohmann::json::parse(payload);
2110 responseStatus == HTTPMessage::HttpStatus::BadRequest ||
2111 responseStatus == HTTPMessage::HttpStatus::Unauthorized ||
2112 responseStatus == HTTPMessage::HttpStatus::ServiceUnavailable
2127 }
else if(responseStatus == HTTPMessage::HttpStatus::Ok){
2128 uint32_t index = -1;
2130 if (jGetKeyResponse.contains(
"index"))
2131 index = jGetKeyResponse[
"index"];
2132 if (jGetKeyResponse.contains(
"Key_buffer"))
2133 key = jGetKeyResponse[
"Key_buffer"];
2142 appKey.
index = index;
2146 m_associations.first.buffer.insert( std::make_pair(index, appKey) );
2148 m_associations.second.buffer.insert( std::make_pair(index, appKey) );
2150 NS_FATAL_ERROR(
this <<
"Association with ksid" << ksid <<
"does not exist on QKDApp" );
2165 NS_FATAL_ERROR(
this <<
"Unsupported status code" << responseStatus <<
" of the response.");
2185 responseStatus == HTTPMessage::HttpStatus::BadRequest ||
2186 responseStatus == HTTPMessage::HttpStatus::Unauthorized ||
2187 responseStatus == HTTPMessage::HttpStatus::ServiceUnavailable
2189 NS_LOG_FUNCTION(
this <<
"QKDApp received error message on CLOSE method" );
2192 }
else if(responseStatus == HTTPMessage::HttpStatus::Ok){
2193 NS_LOG_FUNCTION(
this <<
"Application successfully closed association " << ksid );
2197 NS_FATAL_ERROR(
this <<
"Unsupported error status code" << responseStatus <<
"of response.");
2205 NS_LOG_FUNCTION(
this <<
"Processing singnaling packet received from peer QKDApp" );
2211 if(methodType == 0){
2212 NS_LOG_FUNCTION(
this <<
"SEND_KSID: Primary QKDApp received response from Replica QKDApp." );
2215 }
else if (methodType == 1){
2216 NS_LOG_FUNCTION(
this <<
"ESTABLISH_QUEUES: Primary QKDApp received response from Replica QKDApp. Packet ID" );
2223 std::string s = header.
GetUri();
2224 std::string delimiter =
"/";
2228 std::vector<std::string> uriParams;
2229 while((pos = s.find(delimiter)) != std::string::npos){
2230 token = s.substr(0, pos);
2231 if(token.length() > 0){
2232 uriParams.push_back(token);
2234 s.erase(0, pos + delimiter.length());
2237 uriParams.push_back(s);
2240 std::string requestType;
2242 uriParams.size() > 3 &&
2243 uriParams[1] ==
"api" &&
2244 uriParams[2] ==
"v1"
2246 requestType = uriParams[4];
2251 if(requestType ==
"connect"){
2254 std::string ksid = uriParams[5];
2256 std::string cryptoT = uriParams[6];
2261 else if(cryptoT ==
"1")
2271 }
else if(requestType ==
"establish_queues") {
2277 NS_FATAL_ERROR(
this <<
"Invalid method received on app. RequestType:" << requestType << s );
2304 std::stringstream ss;
2305 m_peerAddress.
Print(ss);
2306 std::string headerUri =
"http://" + ss.str();
2316 std::string hMessage = httpMessage.
ToString();
2318 (uint8_t*) (hMessage).c_str(),
2329 NS_LOG_FUNCTION(
this <<
"SEND_KSID: Primary QKDApp sends KSID to Replica QKDApp" <<
2330 headerUri <<
". Packet ID" << packet->
GetUid() );
2336 NS_LOG_FUNCTION(
this <<
"Sending response on SEND_KSID to Primary QKDApp" << httpStatus << msg );
2347 {
"Content-Type",
"application/json; charset=utf-8"}
2353 std::string hMessage = httpMessage.
ToString();
2355 (uint8_t*) (hMessage).c_str(),
2365 NS_LOG_FUNCTION(
this <<
"SEND_KSID: Replica QKDApp sends respose to Primary QKDApp. Packet ID"
2372 NS_LOG_FUNCTION(
this <<
"Processing /connect response (send_ksid)" );
2374 if(header.
GetStatus() == HTTPMessage::HttpStatus::Ok){
2381 NS_LOG_FUNCTION(
this <<
"Association successfully established between QKDApps " << ksid );
2393 NS_LOG_FUNCTION(
this <<
"Primary QKDApp sending establish_queues notification to Replica QKDApp" );
2397 std::stringstream ss;
2398 m_peerAddress.
Print(ss);
2399 std::string headerUri =
"http://" + ss.str();
2400 headerUri +=
"/api/v1/" + this->
GetId().
string() +
"/establish_queues";
2405 std::string hMessage = httpMessage.
ToString();
2407 (uint8_t*) (hMessage).c_str(),
2426 NS_LOG_FUNCTION(
this <<
"Replica QKDApp sending response on /fill indicating success" );
2432 std::string hMessage = httpMessage.
ToString();
2434 (uint8_t*) (hMessage).c_str(),
2476 NS_LOG_FUNCTION(
this <<
"Clearing key stream association on QKDApp" << ksid );
2488 NS_LOG_FUNCTION(
this <<
"Key stream association " << ksid <<
" cleared!" );
2531 "for AppTransitionTree()!" );
2546 "for AppTransitionTree()!" );
2566 return "NOT_STARTED";
2569 return "INITIALIZED";
2572 return "ESTABLISHING_ASSOCIATIONS";
2575 return "ASSOCIATIONS_ESTABLISHED";
2578 return "ESTABLISHING_KEY_QUEUES";
2581 return "KEY_QUEUES_ESTABLISHED";
2593 return "DECRYPT_DATA";
2600 return "FATAL_ERROR";
2620 if (oldState ==
"SEND_DATA" && newState ==
"READY") {
2624 state = QKDApp004::QKDAppState::WAIT;
2643 uint32_t encryptionType,
2644 uint32_t authenticationType,
2645 uint32_t authenticationTagLengthInBits
2648 NS_LOG_FUNCTION (
this << encryptionType << authenticationType << authenticationTagLengthInBits);
2650 switch (encryptionType){
2662 switch (authenticationType){
2681 authenticationTagLengthInBits
2687 authenticationTagLengthInBits
2702 std::string confidentialMessage;
2703 static const char alphanum[] =
2705 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2706 "abcdefghijklmnopqrstuvwxyz";
2708 uint32_t randVal = 0;
2709 for (uint32_t i = 0; i < msgLength; ++i){
2711 confidentialMessage += alphanum[ randVal ];
2714 return confidentialMessage;
2729 return CryptoPP::AES::MAX_KEYLENGTH * 8;
2756 rate = CryptoPP::AES::MAX_KEYLENGTH * 8;
2783 rate = CryptoPP::AES::DEFAULT_KEYLENGTH * 8;
2821 rate = CryptoPP::AES::DEFAULT_KEYLENGTH * 8;
2832 rate = CryptoPP::AES::DEFAULT_KEYLENGTH * 8;
2858 uint8_t *buffer =
new uint8_t[packet->
GetSize ()];
2860 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.
An identifier for simulation events.
bool IsRunning() 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.
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.
void Print(std::ostream &os) const
Print this address to the given output stream.
static Ipv4Address GetAny()
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 GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
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.
uint64_t GetUid() const
Returns the packet's Uid.
std::string ToString() const
Return a string representation of the packet.
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 EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
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 Time Now()
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 SetCloseCallbacks(Callback< void, Ptr< Socket >> normalClose, Callback< void, Ptr< Socket >> errorClose)
Detect socket recv() events such as graceful shutdown or error.
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
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()=0
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
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 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.
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.
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()
Get the type ID.
Simulation virtual time values and global simulation resolution.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent 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()
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,...
Callback< R, Args... > MakeNullCallback()
#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.
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
basic_json<> json
default JSON class
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
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...
Ptr< const AttributeChecker > MakeTypeIdChecker()
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
A cryptographic key at the application layer.
static const uint32_t packetSize
Packet size generated at the AP.