23 #include "ns3/address.h"
25 #include "ns3/nstime.h"
26 #include "ns3/socket.h"
27 #include "ns3/simulator.h"
28 #include "ns3/tcp-socket-factory.h"
29 #include "ns3/packet.h"
30 #include "ns3/uinteger.h"
31 #include "ns3/trace-source-accessor.h"
32 #include "ns3/qkd-control.h"
51 static TypeId tid =
TypeId (
"ns3::QKDKeyManagerSystemApplication")
53 .SetGroupName(
"Applications")
56 .AddAttribute (
"Protocol",
"The type of protocol to use.",
60 .AddAttribute (
"LocalAddress",
"The ipv4 address of the application",
64 .AddAttribute (
"MaximalKeysPerRequest",
65 "The maximal number of keys per request (ESTI QKD 014)",
68 MakeUintegerChecker<uint32_t> ())
69 .AddAttribute (
"MinimalKeySize",
70 "The minimal size of key QKDApp can request",
73 MakeUintegerChecker<uint32_t> ())
74 .AddAttribute (
"MaximalKeySize",
75 "The maximal size of key QKDApp can request",
78 MakeUintegerChecker<uint32_t> ())
79 .AddAttribute (
"DefaultKeySize",
80 "The default size of the key",
83 MakeUintegerChecker<uint32_t> ())
84 .AddAttribute (
"MaliciousRequestBlocking",
85 "Does KMS detects and blocks malicious get_key_004 request?",
88 MakeUintegerChecker<uint32_t> ())
89 .AddAttribute (
"ETSI004_DefaultTTL",
90 "Default value of ETSI004 TTL (in seconds)",
93 MakeUintegerChecker<uint32_t> ())
94 .AddAttribute (
"MaxKeyRate",
"The maximal key rate (encryption+authentication) provided by the KMS (QoS settings).",
98 .AddAttribute (
"MinKeyRate",
"The minimal key rate (encryption+authentication) provided by the KMS (QoS settings).",
102 .AddAttribute (
"QoS_maxrate_threshold",
103 "The treshold for processing low-priority requests",
106 MakeDoubleChecker<double> ())
108 .AddTraceSource (
"Tx",
"A new packet is created and is sent to the APP",
110 "ns3::QKDKeyManagerSystemApplication::Tx")
111 .AddTraceSource (
"Rx",
"A packet from the APP has been received",
113 "ns3::QKDKeyManagerSystemApplication::Rx")
114 .AddTraceSource (
"TxKMSs",
"A new packet is created and is sent to the APP",
116 "ns3::QKDKeyManagerSystemApplication::TxKMSs")
117 .AddTraceSource (
"RxKMSs",
"A packet from the APP has been received",
119 "ns3::QKDKeyManagerSystemApplication::RxKMSs")
121 .AddTraceSource (
"NewKeyGeneratedEmir",
"The trace to monitor key material received from QL",
123 "ns3::QKDKeyManagerSystemApplication::NewKeyGeneratedEmir")
124 .AddTraceSource (
"KeyServedEmir",
"The trace to monitor key material served to QKD Apps",
126 "ns3:QKDKeyManagerSystemApplication::KeyServedEmir")
128 .AddTraceSource (
"NewKeyGenerated",
"The trace to monitor key material received from QL",
130 "ns3::QKDKeyManagerSystemApplication::NewKeyGenerated")
132 .AddTraceSource (
"KeyServedEtsi014",
"The thece to monitor key usage by etsi 014",
134 "ns3::QKDKeyManagerSystemApplication::KeyServedEtsi014")
136 .AddTraceSource (
"KeyServedEtsi004",
"The thece to monitor key usage by etsi 004",
138 "ns3::QKDKeyManagerSystemApplication::KeyServedEtsi004")
140 .AddTraceSource (
"DropKMSRequest",
"Drop a request from the queue disc",
142 "ns3::QKDKeyManagerSystemApplication::TracedCallback")
144 .AddTraceSource (
"ProvidedQoSResponse",
"Provide QoS response to key material request",
146 "ns3::QKDKeyManagerSystemApplication::ProvidedQoSResponse")
162 m_random = CreateObject<UniformRandomVariable> ();
255 sendSocket->
Connect ( receiveAddress );
260 <<
"Create the response socket " << sendSocket
283 it->second.first = s;
307 NS_LOG_FUNCTION (
this <<
"QKDKeyManagerSystemApplication Connection succeeded");
311 if(j->first == socket){
312 uint32_t response = j->first->Send(j->second);
313 response = j->first->Send(j->second);
316 NS_LOG_FUNCTION(
this << j->first <<
"Sending packet from the queue!" << response );
327 NS_LOG_FUNCTION (
this <<
"QKDKeyManagerSystemApplication KMSs Connection succeeded");
334 NS_LOG_FUNCTION (
this <<
"QKDKeyManagerSystemApplication, Connection Failed");
341 NS_LOG_FUNCTION (
this <<
"QKDKeyManagerSystemApplication, Connection Failed");
360 NS_LOG_FUNCTION (
this <<
"QKDKeyManagerSystemApplication KMS-SDN Connection succeeded");
368 if(j->first == socket || j->first == 0){
383 NS_LOG_FUNCTION (
this <<
"QKDKeyManagerSystemApplication KMS-SDN Connection failed");
442 if(sendingSocket->
GetPeerName(connectedAddress) == 0){
443 sendingSocket->
Send(packet);
460 std::map<Ipv4Address, std::pair<Ptr<Socket>,
Ptr<Socket> > >::iterator it;
463 if ( it->second.first == socket )
466 sendingSocket->
Send(packet);
485 std::pair<Ptr<Socket>,
Ptr<Socket> > pair = i->second;
486 if(pair.second == 0){
488 NS_LOG_FUNCTION(
this <<
"Let's create a new send socket to reach KMS!");
513 sendSocket->
Connect ( peerAddress );
516 i->second.second = sendSocket;
519 <<
"Create the send socket " << sendSocket
520 <<
" from KMS to KMS which is on " << kmsDstAddress
524 NS_LOG_FUNCTION(
this <<
"Socket to peer KMS exist. No action required");
546 std::pair<Ptr<Socket>,
Ptr<Socket> > pair = i->second;
564 while ((packet = socket->
RecvFrom (from)))
566 if (packet->
GetSize () == 0)
break;
574 <<
"s KMS received packet ID: "
575 << packet->
GetUid () <<
" of "
576 << packet->
GetSize () <<
" bytes from "
579 <<
" total Rx " <<
m_totalRx <<
" bytes");
594 while ((packet = socket->
RecvFrom (from)))
607 <<
"s KMS received packet ID: "
608 << packet->
GetUid () <<
" of "
609 << packet->
GetSize () <<
" bytes from KMS "
612 <<
" total Rx " <<
m_totalRx <<
" bytes");
627 while ((packet = socket->
RecvFrom (from)))
640 <<
"s KMS received packet ID: "
641 << packet->
GetUid () <<
" of "
642 << packet->
GetSize () <<
" bytes from KMS "
645 <<
" total Rx " <<
m_totalRx <<
" bytes");
656 std::string receivedStatus = p->
ToString();
660 if (receivedStatus.find(
"Fragment") != std::string::npos) {
664 std::make_pair (from, Create<Packet> (0))
667 buffer = itBuffer->second;
678 uint8_t *b1 =
new uint8_t[buffer->
GetSize ()];
680 std::string requestString = std::string((
char*)b1);
685 parser.
Parse(&request, requestString);
698 uint8_t *b2 =
new uint8_t[completePacket->
GetSize ()];
700 std::string s2 = std::string((
char*)b2);
703 parser.
Parse(&request2, s2);
721 std::string receivedStatus = p->
ToString();
725 if (receivedStatus.find(
"Fragment") != std::string::npos) {
729 std::make_pair (from, Create<Packet> (0))
732 buffer = itBuffer->second;
743 uint8_t *b1 =
new uint8_t[buffer->
GetSize ()];
745 std::string requestString = std::string((
char*)b1);
749 parser.
Parse(&request, requestString);
762 uint8_t *b2 =
new uint8_t[completePacket->
GetSize ()];
764 std::string s2 = std::string((
char*)b2);
767 parser.
Parse(&request2, s2);
785 std::string receivedStatus = p->
ToString();
789 if (receivedStatus.find(
"Fragment") != std::string::npos) {
793 std::make_pair (from, Create<Packet> (0))
796 buffer = itBuffer->second;
807 uint8_t *b1 =
new uint8_t[buffer->
GetSize ()];
809 std::string requestString = std::string((
char*)b1);
813 parser.
Parse(&request, requestString);
828 uint8_t *b2 =
new uint8_t[completePacket->
GetSize ()];
830 std::string s2 = std::string((
char*)b2);
833 parser.
Parse(&request2, s2);
840 if(request2.
GetUri() !=
""){
939 <<
"Sink KMS socket listens on "
941 <<
" and port " << sdnPort
942 <<
" for SDN packets"
980 if(j->second != 0) j->second->Close();
993 NS_LOG_FUNCTION(
this <<
"Scheduling new event in an attempt to fill association buffer " << ksid <<
" ...");
994 uint32_t scheduleID {0};
996 if(action ==
"CheckAssociation"){
1002 NS_FATAL_ERROR(
this <<
"Invalid action as the function input recived " << action);
1021 std::string slave_SAE_ID;
1026 uriParams.size() > 3 &&
1027 uriParams[1] ==
"api" &&
1028 uriParams[2] ==
"v1" &&
1029 uriParams[3] ==
"keys"
1032 std::string receivedAddressStr (uriParams[0]);
1034 NS_LOG_FUNCTION(
this <<
"received address" << receivedAddressStr << receivedAddress);
1039 slave_SAE_ID = uriParams[4];
1040 ksid = uriParams[4];
1045 NS_LOG_FUNCTION (
this <<
"slave_SAE_ID: " << slave_SAE_ID <<
"requestType: " << requestType );
1052 NS_LOG_FUNCTION (
this <<
"Fetch status from QKD buffers for connection to destination node" << slave_SAE_ID );
1063 std::ostringstream srcKmsAddressTemp;
1064 srcKmsAddress.
Print(srcKmsAddressTemp);
1065 std::string srcKME = srcKmsAddressTemp.str ();
1068 std::ostringstream dstKmsAddressTemp;
1069 dstKmsAddress.
Print(dstKmsAddressTemp);
1070 std::string dstKME = dstKmsAddressTemp.str ();
1074 j[
"source_KME_ID"] = srcKME;
1075 j[
"target_KME_ID"] = dstKME;
1077 j[
"slave_SAE_ID"] = slave_SAE_ID;
1082 j[
"stored_key_count"] = buffer->GetKeyCountBit();
1083 j[
"max_key_count"] = buffer->GetMaxKeyCount();
1085 j[
"stored_key_count"] = 0;
1086 j[
"max_key_count"] = 0;
1092 j[
"max_SAE_ID_count"] = 0;
1094 std::string msg = j.dump();
1099 {
"Content-Type",
"application/json; charset=utf-8"},
1100 {
"Request URI", headerIn.
GetUri() }
1102 std::string hMessage = httpMessage.
ToString();
1104 (uint8_t*) (hMessage).c_str(),
1109 NS_LOG_FUNCTION (
this <<
"Sending Response to ETSI_QKD_014_GET_STATUS\n PacketID: " << packet->
GetUid() <<
" of size: " << packet->
GetSize() << hMessage );
1119 uint32_t keyNumber = 1;
1134 if(headerIn.
GetMethod() == HTTPMessage::HttpMethod::GET){
1136 while(
k <
int(uriParams.size())){
1137 if(uriParams[
k] ==
"number")
1138 keyNumber = std::stoi(uriParams[
k+1]);
1139 else if(uriParams[
k] ==
"size")
1140 keySize = std::stoi(uriParams[
k+1]);
1143 jrequest = {{
"number", keyNumber}, {
"size", keySize}};
1145 }
else if(headerIn.
GetMethod() == HTTPMessage::HttpMethod::POST){
1148 jrequest = nlohmann::json::parse(payload);
1149 if (jrequest.contains(
"number"))
1150 keyNumber = jrequest[
"number"];
1151 if (jrequest.contains(
"size"))
1152 keySize = uint32_t(jrequest[
"size"]);
1154 NS_FATAL_ERROR(
this <<
"JSON parse error of the received payload: " << payload <<
"\t" << payload.length() );
1161 if(!errorDataStructure.empty()){
1163 NS_LOG_FUNCTION(
this <<
"Get key request error" << errorDataStructure.dump() );
1165 if(errorDataStructure.contains(
"message")){
1166 if(errorDataStructure[
"message"] ==
"keys are being transformed"){
1167 statusCode = HTTPMessage::HttpStatus::ServiceUnavailable;
1170 }
else if(errorDataStructure[
"message"] ==
"insufficient amount of key material")
1171 statusCode = HTTPMessage::HttpStatus::ServiceUnavailable;
1173 errorDataStructure[
"ksid"] = ksid;
1174 std::string msg = errorDataStructure.dump();
1179 {
"Content-Type",
"application/json; charset=utf-8"},
1180 {
"Request URI", headerIn.
GetUri() }
1182 std::string hMessage = httpMessage.
ToString();
1184 (uint8_t*) (hMessage).c_str(),
1189 NS_LOG_FUNCTION (
this <<
"1185 Sending Response to ETSI_QKD_014_GET_KEY\n PacketID: " << packet->
GetUid() <<
" of size: " << packet->
GetSize() << hMessage );
1194 std::vector<Ptr<QKDKey>> keys {};
1197 buffer->RecordTargetSize(keySize);
1198 for(uint32_t i = 0; i < keyNumber; i++){
1199 keys.push_back(buffer->FetchKeyBySize(keySize));
1207 jkeys[
"ksid"] = ksid;
1208 std::string msg = jkeys.dump();
1216 {
"Content-Type",
"application/json; charset=utf-8"},
1217 {
"Request URI", headerIn.
GetUri() }
1219 std::string hMessage = httpMessage.
ToString();
1221 (uint8_t*) (hMessage).c_str(),
1226 NS_LOG_FUNCTION(
this <<
"1221 Sending Response to ETSI_QKD_014_GET_KEY\n PacketID: " << packet->
GetUid() <<
" of size: " << packet->
GetSize() << hMessage );
1230 for(uint32_t i=0; i<keys.size(); i++){
1245 NS_LOG_FUNCTION(
this <<
"Processing ETSI 014 get_key_with_key_ids request" );
1258 jkeyIDs = nlohmann::json::parse(payload);
1263 std::vector<std::string> keyIDs;
1264 for (nlohmann::json::iterator it = jkeyIDs[
"key_IDs"].begin(); it != jkeyIDs[
"key_IDs"].end(); ++it)
1265 keyIDs.push_back((it.value())[
"key_ID"]);
1270 std::vector<Ptr<QKDKey>> keys {};
1272 for(uint32_t i = 0; i < keyIDs.size(); i++){
1275 if(keys[i] == NULL){
1286 uint32_t number = keys.size();
1287 uint32_t size = keys[0]->GetSizeInBits();
1291 std::string msg = jkeys.dump();
1296 {
"Content-Type",
"application/json; charset=utf-8"},
1297 {
"Request URI", headerIn.
GetUri() }
1299 std::string hMessage = httpMessage.
ToString();
1301 (uint8_t*) (hMessage).c_str(),
1306 NS_LOG_FUNCTION (
this <<
"Sending Response to ETSI_QKD_014_GET_KEY\n PacketID: " << packet->
GetUid() <<
" of size: " << packet->
GetSize() << hMessage );
1310 for(uint32_t i=0; i<keys.size(); i++){
1317 nlohmann::json errorDataStructure = {{
"messsage",
"key access error"}};
1318 std::string msg = errorDataStructure.dump();
1322 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::BadRequest, msg, {
1323 {
"Content-Type",
"application/json; charset=utf-8"},
1324 {
"Request URI", headerIn.
GetUri() }
1326 std::string hMessage = httpMessage.
ToString();
1328 (uint8_t*) (hMessage).c_str(),
1333 NS_LOG_FUNCTION(
this <<
"Sending Response to ETSI_QKD_014_GET_KEY\n PacketID: " << packet->
GetUid() <<
" of size: " << packet->
GetSize() << hMessage );
1379 std::cout <<
"packet dropped! \n";
1401 std::string keyId = payloadContent[
"key_id"];
1402 std::string keyValue = payloadContent[
"key"];
1403 uint32_t srcNodeId = payloadContent[
"src_id"];
1404 uint32_t dstNodeId = payloadContent[
"dst_id"];
1409 Ptr<QKDKey> newKey = Create<QKDKey> (keyId, keyValue);
1410 AddNewKey(newKey, srcNodeId, dstNodeId);
1426 if(headerIn.
GetUri() !=
"")
1441 uriParams.size() > 3 &&
1442 uriParams[1] ==
"api" &&
1443 uriParams[2] ==
"v1" &&
1444 uriParams[3] ==
"keys" &&
1445 uriParams[5] ==
"register_qkd_link"
1453 sdnResponse = nlohmann::json::parse(payload);
1454 double QKDLinkStatsUpdateInterval = 0;
1455 std::string keyAssociationIdString;
1456 uint32_t registrationAccepted = 0;
1458 if (sdnResponse.contains(
"accepted")) registrationAccepted = sdnResponse[
"accepted"];
1459 if (sdnResponse.contains(
"qkd_link_update_interval")) QKDLinkStatsUpdateInterval = sdnResponse[
"qkd_link_update_interval"];
1460 if (sdnResponse.contains(
"key_association_id")) keyAssociationIdString = sdnResponse[
"key_association_id"];
1462 NS_ASSERT(QKDLinkStatsUpdateInterval > 1);
1463 NS_LOG_FUNCTION(
this << keyAssociationIdString << registrationAccepted << QKDLinkStatsUpdateInterval);
1464 UUID keyAssociationId =
UUID{keyAssociationIdString};
1466 if(registrationAccepted){
1474 NS_LOG_FUNCTION(
this <<
"SDN approved registration of QKD LINK between nodes " << keyAssociationId);
1476 Seconds(QKDLinkStatsUpdateInterval),
1480 QKDLinkStatsUpdateInterval
1485 NS_LOG_FUNCTION(
this <<
"SDN FORBIDES registration of QKD LINK between nodes " << keyAssociationId);
1515 keyAssociation.
SetSKR(buffer->GetAverageKeyGenerationRate());
1521 double ratio = buffer->GetAverageKeyGenerationRate() - buffer->GetAverageKeyConsumptionRate();
1534 j[
"key_association_id"] = keyAssociation.
GetId().
string();
1538 double skr = keyAssociation.
GetSKR();
1540 j[
"qkdl_performance_skr"] = skr;
1544 j[
"qkdl_performance_expected_consumption"] = expectedConsumption;
1548 j[
"qkdl_performance_eskr"] = eskr;
1550 NS_LOG_FUNCTION(
this <<
"Prepared JSON_PACKET_TO_SDN:" << j.dump() << skr << expectedConsumption << eskr );
1552 std::string msg = j.dump();
1556 std::ostringstream sdnAddressTemp;
1557 sdnAddress.
Print(sdnAddressTemp);
1559 std::ostringstream skmsAddressTemp;
1561 std::string skmsAddressString = skmsAddressTemp.str();
1563 std::string headerUri =
"http://" + sdnAddressTemp.str ();
1564 headerUri +=
"/api/v1/keys/" + skmsAddressString +
"/key_association_status";
1569 std::string hMessage = httpMessage.
ToString();
1571 (uint8_t*) (hMessage).c_str(),
1576 NS_LOG_FUNCTION (
this <<
"Sending KEY_ASSOCIATION_STATUS to SDN CONTROLLER\n PacketID: "
1590 keyAssociation.
GetId(),
1608 uriParams.size() > 3 &&
1609 uriParams[1] ==
"api" &&
1610 uriParams[2] ==
"v1" &&
1611 uriParams[3] ==
"keys" &&
1612 uriParams[5] ==
"register_qkd_link"
1623 std::vector<std::string>
1627 std::vector<std::string> uriParams;
1630 std::string delimiter =
"/";
1633 while ((pos = s.find(delimiter)) != std::string::npos) {
1634 token = s.substr(0, pos);
1635 if(token.length() > 0){
1636 uriParams.push_back(token);
1638 s.erase(0, pos + delimiter.length());
1641 uriParams.push_back(s);
1657 NS_LOG_FUNCTION(
this <<
"krecA" << uriParams[0] << uriParams[1] << uriParams[2] << uriParams[3] );
1659 uriParams.size() > 3 &&
1660 uriParams[1] ==
"api" &&
1661 uriParams[2] ==
"v1" &&
1662 (uriParams[3] ==
"associations" ||
1663 uriParams[3] ==
"keys")
1671 std::string ksid = uriParams[5];
1674 }
else if(requestType ==
FILL){
1675 std::string ksid = uriParams[5];
1681 std::string ksid = uriParams[5];
1699 else if(methodType ==
FILL)
1732 std::map<Ipv4Address, uint32_t>::iterator it =
m_flagedIPAdr.find(ipAdr);
1735 NS_LOG_FUNCTION (
this <<
"This request has been flaged as potentialy malicious!"
1736 <<
"This IPAddress" << ipAdr <<
"will be penalized after the next offense!");
1738 NS_LOG_FUNCTION (
this <<
"KMS identified request coming from" << ipAdr <<
"as malicious request."
1739 <<
"This IPAddress is now blocked!");
1758 NS_LOG_FUNCTION(
this <<
"Checking the state of the association " << ksid <<
" ...");
1759 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
1761 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
1764 (it->second).tempBuffer.empty() &&
1765 ((it->second).buffer.empty() || !(it->second).buffer.begin()->second.ready)
1768 std::map<std::string, uint32_t>::iterator it2 =
m_sessionList.find(ksid);
1771 NS_LOG_FUNCTION(
this <<
"SESSION with KSID " << ksid <<
" was favored in the m_session_list!");
1773 NS_LOG_FUNCTION(
this <<
"SESSION with KSID " << ksid <<
" was not located in m_session_list!");
1777 std::map<std::string, uint32_t>::iterator it2 =
m_sessionList.find(ksid);
1780 NS_LOG_FUNCTION(
this <<
"SESSION with KSID " << ksid <<
" was removed from the m_session_list!");
1782 NS_LOG_FUNCTION(
this <<
"SESSION with KSID " << ksid <<
" was not located in m_session_list!");
1800 jOpenConnectRequest = nlohmann::json::parse(payload);
1806 std::string dstSaeId;
1807 std::string srcSaeId;
1809 if(jOpenConnectRequest.contains(
"Key_stream_ID")) ksid = jOpenConnectRequest[
"Key_stream_ID"];
1810 if(jOpenConnectRequest.contains(
"Source")) srcSaeId = jOpenConnectRequest[
"Source"];
1811 if(jOpenConnectRequest.contains(
"Destination")) dstSaeId = jOpenConnectRequest[
"Destination"];
1821 bool callByMaster {ksid.empty()};
1825 uint32_t type = std::stoi(uriParams[6]);
1830 }
else if(type == 1) {
1855 NS_LOG_FUNCTION(
this <<
"Processing OPEN_CONNECT request submitted by the primary QKDApp ...");
1860 bool acceptRequest =
ProcessQoSRequest(appConnection, conn, inQos, providedQoS, ksid);
1876 jOpenConnectResponse[
"Key_stream_ID"] = ksid;
1877 jOpenConnectResponse[
"QoS"] = {
1878 {
"priority", providedQoS.
priority},
1879 {
"max_bps", providedQoS.
maxRate},
1880 {
"min_bps", providedQoS.
minRate},
1881 {
"jitter", providedQoS.
jitter},
1882 {
"timeout", providedQoS.
timeout},
1883 {
"key_chunk_size", providedQoS.
chunkSize},
1884 {
"TTL", providedQoS.
TTL}
1886 std::string msg = jOpenConnectResponse.dump();
1891 {
"Content-Type",
"application/json; charset=utf-8"},
1892 {
"Request URI", headerIn.
GetUri() }
1894 std::string hMessage = httpMessage.
ToString();
1896 (uint8_t*) (hMessage).c_str(),
1915 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::BadRequest,
"", {
1916 {
"Request URI", headerIn.
GetUri() }
1918 std::string hMessage = httpMessage.
ToString();
1920 (uint8_t*) (hMessage).c_str(),
1933 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
1935 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
1937 }
else if ((it->second).srcSaeId !=
UUID{srcSaeId}) {
1938 NS_LOG_FUNCTION(
this <<
"KSID is not registered for this application" << (it->second).dstSaeId << srcSaeId );
1942 (it->second).peerRegistered =
true;
1950 {
"Request URI", headerIn.
GetUri() }
1952 std::string hMessage = httpMessage.
ToString();
1954 (uint8_t*) (hMessage).c_str(),
1969 NS_LOG_FUNCTION(
this <<
"Processing get_key request (ETSI 004)" << ksid );
1971 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
1976 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
1980 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::BadRequest,
"", {
1981 {
"Request URI", headerIn.
GetUri() }
1983 std::string hMessage = httpMessage.
ToString();
1985 (uint8_t*) (hMessage).c_str(),
1995 if( !(it->second).buffer.empty() && (it->second).buffer.begin()->second.ready )
2005 index = (it->second).buffer.begin()->first;
2006 key = (it->second).buffer.begin()->second.key;
2007 (it->second).buffer.erase((it->second).buffer.begin());
2008 if(it->second.associationDirection == 0){
2013 jresponse[
"index"] = index;
2014 jresponse[
"Key_buffer"] = key;
2016 std::string msg = jresponse.dump();
2021 {
"Content-Type",
"application/json; charset=utf-8"},
2022 {
"Request URI", headerIn.
GetUri() }
2024 std::string hMessage = httpMessage.
ToString();
2026 (uint8_t*) (hMessage).c_str(),
2041 <<
"AverageKeyGenerationRate:" << conn.
GetSKR()
2053 NS_LOG_FUNCTION(
this <<
"Association was not found!" << it->second.dstSaeId.string() );
2057 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::BadRequest,
"", {
2058 {
"Request URI", headerIn.
GetUri() }
2060 std::string hMessage = httpMessage.
ToString();
2062 (uint8_t*) (hMessage).c_str(),
2074 NS_LOG_FUNCTION(
this <<
"No keys available in the association buffer. Responding on the request ...");
2078 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::BadRequest,
"", {
2079 {
"Request URI", headerIn.
GetUri() }
2081 std::string hMessage = httpMessage.
ToString();
2083 (uint8_t*) (hMessage).c_str(),
2116 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
2118 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
2125 if(!it->second.buffer.empty()){
2127 query.
sync_index = it->second.buffer.begin()->first;
2138 NS_LOG_FUNCTION(
this <<
"Releasing key stream association buffer. Synchronizing with peed KMS ... ");
2148 std::string msg = msgBody.dump();
2150 std::ostringstream peerkmsAddressTemp;
2151 (it->second).dstKmsNode.Print(peerkmsAddressTemp);
2152 std::string headerUri =
"http://" + peerkmsAddressTemp.str();
2153 headerUri +=
"/api/v1/associations/close_kms/" + ksid;
2158 std::string hMessage = httpMessage.
ToString();
2160 (uint8_t*) (hMessage).c_str(),
2167 sendSocket->
Send(packet);
2168 NS_LOG_FUNCTION(
this <<
"Synchronization information for releasing key stream association sent to peer KMS"
2185 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
2187 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
2196 msgBody[
"Source"] = (it->second).srcSaeId.string();
2197 msgBody[
"Destination"] = (it->second).dstSaeId.string();
2198 msgBody[
"QoS"][
"key_chunk_size"] = (it->second).qos.chunkSize;
2199 msgBody[
"QoS"][
"max_bps"] = (it->second).qos.maxRate;
2200 msgBody[
"QoS"][
"min_bps"] = (it->second).qos.minRate;
2201 msgBody[
"QoS"][
"jitter"] = (it->second).qos.jitter;
2202 msgBody[
"QoS"][
"priority"] = (it->second).qos.priority;
2203 msgBody[
"QoS"][
"timeout"] = (it->second).qos.timeout;
2204 msgBody[
"QoS"][
"TTL"] = (it->second).qos.TTL;
2207 msgBody[
"Key_stream_ID"] = ksid;
2208 std::string msg = msgBody.dump();
2210 std::ostringstream peerkmsAddressTemp;
2211 (it->second).dstKmsNode.Print(peerkmsAddressTemp);
2212 std::string headerUri =
"http://" + peerkmsAddressTemp.str();
2213 headerUri +=
"/api/v1/associations/new_app";
2218 std::string hMessage = httpMessage.
ToString();
2220 (uint8_t*) (hMessage).c_str(),
2232 sendSocket->
Send(packet);
2233 NS_LOG_FUNCTION(
this <<
"NEW_APP: KMS informs peer KMS on new association established!" );
2243 jNewAppRequest = nlohmann::json::parse(payload);
2248 std::string srcSaeId;
2249 std::string dstSaeId;
2252 if(jNewAppRequest.contains(
"Destination")) dstSaeId = jNewAppRequest[
"Destination"];
2253 if(jNewAppRequest.contains(
"Source")) srcSaeId = jNewAppRequest[
"Source"];
2254 if(jNewAppRequest.contains(
"Key_stream_ID")) ksid = jNewAppRequest[
"Key_stream_ID"];
2257 NS_ASSERT(srcSaeId.length()>0 || dstSaeId.length()>0 || !ksid.empty());
2259 bool qosAgreed {
true};
2290 {
"Request URI", headerIn.
GetUri() }
2292 std::string hMessage = httpMessage.
ToString();
2294 (uint8_t*) (hMessage).c_str(),
2299 NS_LOG_FUNCTION(
this <<
"NEW_APP request accepted. Association created." );
2318 NS_FATAL_ERROR(
this <<
"Response cannot be mapped! HttpQuery empty!" );
2320 std::string ksid = it->second[0].ksid;
2339 jOpenConnectResponse[
"Key_stream_ID"] = it->second[0].ksid;
2340 std::string msg = jOpenConnectResponse.dump();
2345 {
"Content-Type",
"application/json; charset=utf-8"},
2346 {
"Request URI", headerIn.
GetUri() }
2348 std::string hMessage = httpMessage.
ToString();
2350 (uint8_t*) (hMessage).c_str(),
2366 std::string ksid = it->second[0].ksid;
2381 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
2395 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
2397 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
2406 std::ostringstream peerkmsAddressTemp;
2407 dstKms.
Print(peerkmsAddressTemp);
2408 std::string headerUri =
"http://" + peerkmsAddressTemp.str ();
2409 headerUri +=
"/api/v1/associations/register/" + ksid;
2414 std::string hMessage = httpMessage.
ToString();
2416 (uint8_t*) (hMessage).c_str(),
2426 sendSocket->
Send(packet);
2433 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
2435 (it->second).peerRegistered =
true;
2441 {
"Content-Type",
"application/json; charset=utf-8"},
2442 {
"Request URI", headerIn.
GetUri() }
2444 std::string hMessage = httpMessage.
ToString();
2446 (uint8_t*) (hMessage).c_str(),
2455 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
2457 }
else if((it->second).peerRegistered ==
true){
2458 NS_LOG_FUNCTION(
this <<
"The peer application for asscotiation " << ksid <<
" has already been connected.");
2469 NS_FATAL_ERROR(
this <<
"Response cannot be mapped! HttpQuery empty!" );
2474 NS_LOG_FUNCTION(
this <<
"/register error! Releasing established association" << it->second[0].ksid );
2475 std::map<std::string, Association004>::iterator it1 =
m_associations004.find(it->second[0].ksid);
2494 jAddKeysRequest = nlohmann::json::parse(payload);
2499 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
2501 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
2505 UUID dstSaeId = it->second.dstSaeId;
2517 for(nlohmann::json::iterator it = jAddKeysRequest[
"keys"].begin(); it != jAddKeysRequest[
"keys"].end(); ++it){
2518 if(buffer->ProbeKeyStatus( (it.value())[
"key_ID"],
QKDKey::READY ))
2527 for(nlohmann::json::iterator it = jAddKeysRequest[
"keys"].begin(); it != jAddKeysRequest[
"keys"].end(); ++it){
2528 Ptr<QKDKey> key = buffer->FetchKeyByID( (it.value())[
"key_ID"]);
2533 NS_LOG_FUNCTION(
this <<
"Replica KMS added keys " << jAddKeysRequest.dump()
2534 <<
" to dedicated association key store " << ksid );
2539 {
"Request URI", headerIn.
GetUri() }
2541 std::string hMessage = httpMessage.
ToString();
2543 (uint8_t*) (hMessage).c_str(),
2548 NS_LOG_FUNCTION(
this <<
"Replica KMS sending response on FILL request "
2553 NS_LOG_FUNCTION(
this <<
"Replica KMS reject FILL request " << jAddKeysRequest.dump()
2554 <<
" for association " << ksid );
2558 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::BadRequest,
"", {
2559 {
"Request URI", headerIn.
GetUri() }
2561 std::string hMessage = httpMessage.
ToString();
2563 (uint8_t*) (hMessage).c_str(),
2568 NS_LOG_FUNCTION(
this <<
"Replica KMS sending response on FILL request "
2584 NS_FATAL_ERROR(
this <<
"Response cannot be mapped! HttpQuery empty!" );
2586 std::string ksid = it->second[0].ksid;
2588 std::map<std::string, Association004>::iterator a =
m_associations004.find(ksid);
2590 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
2605 NS_FATAL_ERROR(
this <<
"QKDBuffer for this connection cannot be found" );
2608 NS_LOG_FUNCTION(
this <<
"Filling association dedicated key store" << ksid );
2609 for(std::vector<std::string>::iterator i = a->second.tempBuffer.begin(); i < a->
second.tempBuffer.end(); ++i){
2614 a->second.tempBuffer.clear();
2617 NS_LOG_FUNCTION(
this <<
"Releasing reservation of keys " << a->second.tempBuffer );
2618 for(std::vector<std::string>::iterator i = a->second.tempBuffer.begin(); i < a->
second.tempBuffer.end(); ++i)
2619 buffer->ReleaseReservation(*i);
2620 a->second.tempBuffer.clear();
2630 NS_LOG_FUNCTION(
this <<
"target size" << keySize <<
"target number" << keyNumber <<
"ksid SAE" << ksid.
string() );
2641 buffer->RecordTargetSize(keySize);
2643 bool transformSetReady =
false;
2645 std::vector<std::string> toTransformKeyIDs {};
2646 uint32_t targetSize {keySize*keyNumber};
2647 while(!transformSetReady){
2648 Ptr<QKDKey> key = buffer->SearchOptimalKeyToTransform(targetSize);
2651 buffer->ReserveKey(key->GetId());
2652 toTransformKeyIDs.push_back(key->GetId());
2653 if(key->GetSizeInBits() >= targetSize)
2654 transformSetReady =
true;
2656 targetSize -= key->GetSizeInBits();
2660 std::vector<std::string> transformKeyIDs;
2662 while(
k++<keyNumber){
2670 NS_LOG_FUNCTION(
this <<
"to_transform_key_IDs" << toTransformKeyIDs );
2674 jtransform[
"ksid"] = ksid.
string();
2675 jtransform[
"transform_key_size"] = keySize;
2676 jtransform[
"transform_key_number"] = keyNumber;
2677 for(
size_t i = 0; i < transformKeyIDs.size(); i++)
2678 jtransform[
"transform_key_IDs"].push_back({{
"key_ID", transformKeyIDs[i]}});
2679 jtransform[
"surplus_key_ID"] = surplusKeyId;
2680 for(
size_t i = 0; i < toTransformKeyIDs.size(); i++)
2681 jtransform[
"to_transform_key_IDs"].push_back({{
"key_ID", toTransformKeyIDs[i]}});
2683 std::string msg = jtransform.dump();
2692 std::ostringstream peerkmsAddressTemp;
2693 dstKms.
Print(peerkmsAddressTemp);
2694 std::string headerUri =
"http://" + peerkmsAddressTemp.str ();
2695 headerUri +=
"/api/v1/keys/transform_keys";
2700 std::string hMessage = httpMessage.
ToString();
2702 (uint8_t*) (hMessage).c_str(),
2709 httpRequest.
method_type = RequestType::TRANSFORM_KEYS;
2717 sendSocket->
Send(packet);
2721 NS_FATAL_ERROR(
this <<
"QKD buffer for this connection was not found!" );
2734 jtransformRequest = nlohmann::json::parse(payload);
2739 uint32_t keySize {0}, keyNumber {0};
2740 std::vector<std::string> toTransformKeyIDs {}, transformKeyIDs {};
2741 std::string surplusKeyId {};
2744 if(jtransformRequest.contains(
"transform_key_size"))
2745 keySize = jtransformRequest[
"transform_key_size"];
2746 if(jtransformRequest.contains(
"transform_key_number"))
2747 keyNumber = jtransformRequest[
"transform_key_number"];
2748 if(jtransformRequest.contains(
"surplus_key_ID"))
2749 surplusKeyId = jtransformRequest[
"surplus_key_ID"];
2750 if(jtransformRequest.contains(
"transform_key_IDs")){
2752 nlohmann::json::iterator it = jtransformRequest[
"transform_key_IDs"].begin();
2753 it != jtransformRequest[
"transform_key_IDs"].end();
2756 transformKeyIDs.push_back((it.value())[
"key_ID"]);
2758 if(jtransformRequest.contains(
"to_transform_key_IDs")){
2760 nlohmann::json::iterator it = jtransformRequest[
"to_transform_key_IDs"].begin();
2761 it != jtransformRequest[
"to_transform_key_IDs"].end();
2764 toTransformKeyIDs.push_back((it.value())[
"key_ID"]);
2766 if(jtransformRequest.contains(
"ksid")){
2767 ksid = jtransformRequest[
"ksid"];
2775 NS_LOG_FUNCTION(
this << keySize << keyNumber <<
"\ntransform_key_IDs"<< transformKeyIDs
2776 <<
"\nto_transform_key_IDs" << toTransformKeyIDs <<
"\nsurplus_key_ID" << surplusKeyId <<
"\nksid" << ksid );
2778 if(ksid.size() == 0){
2779 NS_FATAL_ERROR(
this <<
"No ksid specified!" << jtransformRequest.dump() );
2793 bool keysExist {
true};
2794 for(
size_t i = 0; i < toTransformKeyIDs.size(); i++){
2795 keysExist = buffer->ProbeKeyStatus(toTransformKeyIDs[i],
QKDKey::READY);
2801 uint32_t keySizeInBytes = keySize/8;
2802 std::string mergedKey {};
2803 for(
size_t i = 0; i < toTransformKeyIDs.size(); i++){
2804 mergedKey += (buffer->FetchKeyByID(toTransformKeyIDs[i], 1))->GetKeyString();
2806 for(
size_t i = 0; i < transformKeyIDs.size(); i++){
2807 std::string keyString = mergedKey.substr(0, keySizeInBytes);
2808 mergedKey.erase(0, keySizeInBytes);
2809 Ptr<QKDKey> key = CreateObject<QKDKey> (transformKeyIDs[i], keyString);
2810 buffer->AddNewKey(key,1);
2812 if(!mergedKey.empty()){
2813 Ptr<QKDKey> key = CreateObject<QKDKey> (surplusKeyId, mergedKey);
2814 buffer->AddNewKey(key,1);
2819 std::string msg = jResponse.dump();
2824 {
"Content-Type",
"application/json; charset=utf-8"},
2825 {
"Request URI", headerIn.
GetUri() }
2827 std::string hMessage = httpMessage.
ToString();
2829 (uint8_t*) (hMessage).c_str(),
2840 std::string msg = jResponse.dump();
2844 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::BadRequest, msg, {
2845 {
"Content-Type",
"application/json; charset=utf-8"},
2846 {
"Request URI", headerIn.
GetUri() }
2848 std::string hMessage = httpMessage.
ToString();
2850 (uint8_t*) (hMessage).c_str(),
2859 NS_FATAL_ERROR(
this <<
"No QKD buffer found for this connection!" );
2873 jTransformResponse = nlohmann::json::parse(payload);
2875 NS_FATAL_ERROR(
this <<
"JSON parse error! Received payload:" << payload );
2878 std::string ksid =
"";
2879 if(jTransformResponse.contains(
"sae_id")) ksid = jTransformResponse[
"sae_id"];
2880 if(ksid.empty() && jTransformResponse.contains(
"ksid")) ksid = jTransformResponse[
"ksid"];
2894 HttpQuery transformPar = (it->second)[0];
2898 NS_FATAL_ERROR(
this <<
"HTTP response cannot be mapped: HTTP query to destination KMS does not exist!" );
2899 else if(it->second.empty())
2900 NS_FATAL_ERROR(
this <<
"HTTP response cannot be mapped: HTTP query is empty!" );
2907 bool keysExist {
true};
2908 for(
size_t i = 0; i < toTransformKeyIDs.size(); i++){
2909 keysExist = buffer->ProbeKeyStatus(toTransformKeyIDs[i],
QKDKey::RESERVED);
2914 uint32_t keySizeInBytes = keySize/8;
2915 std::string mergedKey {};
2916 for(
size_t i = 0; i < toTransformKeyIDs.size(); i++){
2917 mergedKey += (buffer->FetchKeyByID(toTransformKeyIDs[i], 1))->GetKeyString();
2919 for(
size_t i = 0; i < keyNumber; i++){
2920 std::string keyString = mergedKey.substr(0, keySizeInBytes);
2921 mergedKey.erase(0, keySizeInBytes);
2922 Ptr<QKDKey> key = CreateObject<QKDKey> (transformKeyIDs[i], keyString);
2923 buffer->AddNewKey(key,1);
2925 if(!mergedKey.empty()){
2926 Ptr<QKDKey> key = CreateObject<QKDKey> (surplusKeyId, mergedKey);
2927 buffer->AddNewKey(key,1);
2932 NS_FATAL_ERROR(
this <<
"KMS mistreated reserved keys: keys not found!" );
2935 NS_LOG_FUNCTION(
this <<
"Releasing reserved keys for failed transformation!");
2938 for(
size_t i = 0; i < toTransformKeyIDs.size(); i++){
2939 buffer->ReleaseReservation(toTransformKeyIDs[i]);
2941 NS_LOG_FUNCTION(
this <<
"Reserved keys are released" << toTransformKeyIDs );
2954 jcloseRequest = nlohmann::json::parse(payload);
2959 std::string surplusKeyId {};
2960 uint32_t syncIndex {0};
2961 if(jcloseRequest.contains(
"surplus_key_ID"))
2962 surplusKeyId = jcloseRequest[
"surplus_key_ID"];
2963 if(jcloseRequest.contains(
"sync_index"))
2964 syncIndex = jcloseRequest[
"sync_index"];
2966 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
2968 NS_LOG_FUNCTION(
this <<
"KSID not registered on KMS, or is already closed!" );
2972 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::NotAcceptable,
"", {
2973 {
"Request URI", headerIn.
GetUri() }
2975 std::string hMessage = httpMessage.
ToString();
2977 (uint8_t*) (hMessage).c_str(),
2986 it->second.peerRegistered =
false;
2988 uint32_t localSyncIndex {0};
2989 if(it->second.buffer.begin() != it->second.buffer.end())
2990 localSyncIndex = it->second.buffer.begin()->first;
2995 if(!surplusKeyId.empty() && syncIndex > localSyncIndex){
2998 uint32_t presentKeyMaterial {0};
2999 for (std::map<uint32_t, ChunkKey>::iterator it2 = it->second.buffer.begin(); it2 != it->second.buffer.find(syncIndex); ++it2){
3002 presentKeyMaterial += it2->second.chunkSize;
3010 if(!surplusKeyId.empty() && syncIndex < localSyncIndex)
3011 syncIndex = localSyncIndex;
3014 if(
empty && !surplusKeyId.empty())
3021 if(!surplusKeyId.empty())
3022 jresponse[
"sync_index"] = syncIndex;
3024 jresponse[
"flag_empty"] =
true;
3027 std::string msg = jresponse.dump();
3032 {
"Content-Type",
"application/json; charset=utf-8"},
3033 {
"Request URI", headerIn.
GetUri() }
3035 std::string hMessage = httpMessage.
ToString();
3037 (uint8_t*) (hMessage).c_str(),
3052 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
3054 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
3058 if(surplusKeyId.empty()){
3061 std::string preservedKeyString {};
3062 std::map<uint32_t, ChunkKey>::iterator a = it->second.buffer.find(syncIndex);
3063 while(a != it->second.buffer.end()){
3064 preservedKeyString += a->second.key;
3068 if(!preservedKeyString.empty()){
3070 UUID ksid = it->second.ksid;
3082 NS_LOG_FUNCTION(
this <<
"Releasing dedicated association buffer ... " );
3084 NS_LOG_FUNCTION(
this << preservedKeyString.size() <<
" bit of key material preserved ... " );
3085 NS_LOG_FUNCTION(
this <<
"Assigning ID to preserved key material ... " );
3086 Ptr<QKDKey> key = CreateObject<QKDKey> (surplusKeyId, preservedKeyString);
3087 buffer->AddNewKey(key, 1);
3088 NS_LOG_FUNCTION(
this <<
"Preserved key material added to the QKD buffer "
3089 << surplusKeyId << preservedKeyString.size() );
3096 NS_LOG_FUNCTION(
this <<
"Key stream association identified with " << ksid <<
"is removed!" );
3103 NS_LOG_FUNCTION(
this <<
"Processing response on KMS /close request ... " );
3107 jcloseResponse = nlohmann::json::parse(payload);
3117 std::string ksid = it->second[0].ksid;
3118 std::map<std::string, Association004>::iterator a =
m_associations004.find(ksid);
3120 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
3126 uint32_t presentKeyMaterial {0};
3127 for (std::map<uint32_t, ChunkKey>::iterator it2 = a->second.buffer.begin(); it2 != a->second.buffer.end(); ++it2){
3128 presentKeyMaterial += it2->second.chunkSize;
3137 uint32_t peerSyncIndex {0};
3138 uint32_t localSyncIndex {it->second[0].sync_index};
3139 if(jcloseResponse.contains(
"sync_index")){
3140 peerSyncIndex = jcloseResponse[
"sync_index"];
3141 if(peerSyncIndex > localSyncIndex)
3142 localSyncIndex = peerSyncIndex;
3145 uint32_t presentKeyMaterial {0};
3146 for (std::map<uint32_t, ChunkKey>::iterator it2 = a->second.buffer.begin(); it2 != a->second.buffer.find(localSyncIndex); ++it2){
3148 presentKeyMaterial += it2->second.chunkSize;
3154 ReleaseAssociation(it->second[0].ksid, it->second[0].surplus_key_ID, localSyncIndex);
3158 uint32_t presentKeyMaterial {0};
3159 for (std::map<uint32_t, ChunkKey>::iterator it2 = a->second.buffer.begin(); it2 != a->second.buffer.end(); ++it2){
3160 presentKeyMaterial += it2->second.chunkSize;
3191 it->second.push_back(request);
3202 if(!it->second.empty())
3203 it->second.erase(it->second.begin());
3207 NS_FATAL_ERROR(
this <<
"HTTP query to destination KMS does not exist!" );
3217 methodType = it->second.begin()->method_type;
3219 NS_FATAL_ERROR(
this <<
"HTTP response cannot be mapped: HTTP query is empty!" );
3235 std::pair<std::multimap<UUID, Ptr<Socket> >::iterator, std::multimap<uint32_t, Ptr<Socket> >::iterator > ret;
3239 std::multimap<UUID, Ptr<Socket> >::iterator it = ret.first;
3249 std::pair<std::multimap<UUID, Ptr<Socket> >::iterator, std::multimap<UUID, Ptr<Socket> >::iterator > ret;
3253 std::multimap<UUID, Ptr<Socket> >::iterator it = ret.first;
3266 std::map<Ipv4Address, std::pair<Ptr<Socket>,
Ptr<Socket> > >::iterator it;
3269 if ((it->second).first == socket) {
3270 dstKMSAddress = it->first;
3275 return dstKMSAddress;
3293 }
else if(s ==
"enc_keys") {
3297 }
else if(s ==
"dec_keys"){
3301 }
else if (s ==
"open_connect"){
3305 }
else if (s ==
"get_key") {
3309 }
else if (s ==
"close") {
3313 }
else if (s ==
"new_app") {
3317 }
else if (s ==
"register") {
3321 }
else if (s ==
"fill") {
3325 }
else if (s ==
"store_pp_key") {
3329 }
else if (s ==
"transform_keys") {
3333 }
else if (s ==
"close_kms") {
3372 std::string keyAssociationIdParam
3376 <<
"srcNodeId: " << srcNodeId
3377 <<
"dstNodeId: " << dstNodeId
3379 <<
"kmsDstAddress: " << kmsDstAddress
3380 <<
"keyAssociationIdParam: " << keyAssociationIdParam
3386 std::string keyAssociationId = keyAssociationIdParam;
3387 if(keyAssociationId.empty()){
3399 lr->AddKeyAssociationEntry(newEntry);
3404 UUID{keyAssociationId},
3414 lr->AddKeyAssociationEntry(newEntry);
3417 NS_LOG_FUNCTION (
this <<
"Create sink socket to listen requests exchanged between KMSs!" );
3421 sinkSocket->
Bind (sinkAddress);
3439 std::make_pair(sinkSocket, sendSocket)
3451 std::ostringstream mkmsAddressTemp;
3453 std::string mkmsAddressString = mkmsAddressTemp.str();
3455 std::ostringstream skmsAddressTemp;
3456 kmsDstAddress.
Print(skmsAddressTemp);
3457 std::string skmsAddressString = skmsAddressTemp.str();
3461 j[
"master_SAE_ID"] = srcNodeId;
3462 j[
"slave_SAE_ID"] = dstNodeId;
3463 j[
"next_hop_id"] = dstNodeId;
3464 j[
"key_association_id"] = keyAssociationId;
3466 j[
"master_kms_address"] = mkmsAddressString;
3467 j[
"slave_kms_address"] = skmsAddressString;
3469 NS_LOG_FUNCTION(
this <<
"Prepared JSON_PACKET_TO_SDN:" << j.dump() );
3471 std::string msg = j.dump();
3475 std::ostringstream sdnAddressTemp;
3476 sdnAddress.
Print(sdnAddressTemp);
3478 std::string headerUri =
"http://" + sdnAddressTemp.str ();
3479 headerUri +=
"/api/v1/keys/" + skmsAddressString +
"/register_qkd_link";
3484 std::string hMessage = httpMessage.
ToString();
3486 (uint8_t*) (hMessage).c_str(),
3492 NS_LOG_FUNCTION (
this <<
"Sending QKD_LINK_REGISTER to SDN CONTROLLER\n PacketID: "
3493 << packetToSdn->
GetUid() <<
" of size: " << packetToSdn->
GetSize()
3505 return keyAssociationId;
3518 uint32_t priority = 0,
3519 double expirationTime = 100
3522 NS_LOG_FUNCTION(
this <<
"keyId: \t" <<
"srcSaeId:" << srcSaeId <<
"dstSaeId:" << dstSaeId <<
"type:" << type);
3528 lr->AssignKeyAssociation( srcSaeId, dstSaeId, type, priority, conn );
3554 UUID keyAssociationId,
3555 UUID applicationEntryId,
3560 uint32_t priority = 0,
3561 double expirationTime = 100
3565 <<
"keyId:" << keyAssociationId
3566 <<
"applicationEntryId:" << applicationEntryId
3567 <<
"srcSaeId:" << srcSaeId
3568 <<
"dstSaeId:" << dstSaeId
3573 if(type ==
"etsi004_enc") {
3575 }
else if(type ==
"etsi004_auth") {
3577 }
else if(type ==
"etsi014_enc") {
3579 }
else if(type ==
"etsi014_auth") {
3611 newEntry.
SetId(applicationEntryId);
3613 lr->AddApplicationEntry(newEntry);
3614 lr->UpdateQKDApplications(connectionId, newEntry.
GetId());
3621 std::ostringstream mkmsAddressTemp;
3623 std::string mkmsAddressString = mkmsAddressTemp.str();
3625 std::ostringstream skmsAddressTemp;
3627 std::string skmsAddressString = skmsAddressTemp.str();
3631 j[
"key_association_id"] = connectionId.
string();
3632 j[
"application_entry_id"] = appId.
string();
3633 j[
"client_SAE_ID"] = srcSaeId.
string();
3634 j[
"server_SAE_ID"] = dstSaeId.
string();
3636 j[
"priority"] = priority;
3637 j[
"expirationTime"] = expirationTime;
3638 j[
"master_kms_address"] = mkmsAddressString;
3639 j[
"slave_kms_address"] = skmsAddressString;
3641 NS_LOG_FUNCTION(
this <<
"Prepared JSON_PACKET_TO_SDN:" << j.dump() );
3643 std::string msg = j.dump();
3647 std::ostringstream sdnAddressTemp;
3648 sdnAddress.
Print(sdnAddressTemp);
3650 std::string headerUri =
"http://" + sdnAddressTemp.str ();
3651 headerUri +=
"/api/v1/keys/" + skmsAddressString +
"/register_sae_link";
3656 std::string hMessage = httpMessage.
ToString();
3658 (uint8_t*) (hMessage).c_str(),
3665 NS_LOG_FUNCTION (
this <<
"Sending SAE_REGISTER to SDN CONTROLLER\n PacketID: "
3688 std::string srcSaeId,
3689 std::string dstSaeId,
3694 UUID srcId (srcSaeId);
3695 UUID dstId (dstSaeId);
3701 lr->LookupApplicationBySaeIDsAndType(srcId, dstId, type, output);
3722 lr->LookupApplication(tempId, output);
3738 UUID tempId (appId);
3742 lr->LookupKeyAssociationByApplicationId(tempId, output);
3759 lr->LookupKeyAssociationByDestinationNodeId(srcNodeId, dstNodeId, output);
3775 lr->LookupKeyAssociationById(keyAssociationId, output);
3786 lr->SaveKeyAssociation(entry);
3820 uint32_t keyNumber = 1;
3822 if(jrequest.contains(
"number")){
3823 keyNumber = jrequest[
"number"];
3825 if(jrequest.contains(
"size")){
3826 keySize = jrequest[
"size"];
3836 jError[
"message"] = std::string {
"requested parameters do not adhere to KMS rules"};
3841 jError[
"details"].push_back({{
"number_unsupported", msgDetail}});
3842 }
else if(keyNumber <= 0){
3843 std::string msgDetail =
"requested number of keys can not be lower or equal to zero";
3845 jError[
"details"].push_back({{
"number_unsupported", msgDetail}});
3850 jError[
"details"].push_back({{
"size_unsupported", msgDetail}});
3854 jError[
"details"].push_back({{
"size_unsupported", msgDetail}});
3855 }
else if(keySize % 8 != 0){
3856 std::string msgDetail =
"size shall be a multiple of 8";
3858 jError[
"details"].push_back({{
"size_unsupported", msgDetail}});
3866 NS_LOG_FUNCTION(
this << conn.
GetId() <<
"\nTarget key size: " << keySize <<
"\nTarget number: "
3867 << keyNumber <<
"\nRequired amount of key material: " << keySize*keyNumber);
3868 NS_LOG_FUNCTION(
this << conn.
GetId() <<
"\nAmount of key material in buffer: " << buffer->GetKeyCountBit()
3869 <<
"\nAmount of key material ready to be served: " << buffer->GetReadyKeyCountBit()
3870 <<
"\nAmount of key material part of target set: " << buffer->GetTargetKeyCountBit());
3871 if(buffer && keySize*keyNumber > buffer->GetReadyKeyCountBit()){
3872 jError[
"message"] = std::string {
"insufficient amount of key material"};
3874 }
else if(buffer && buffer->GetKeyCount(keySize) < keyNumber){
3876 if(buffer->GetReadyKeyCountBit() - buffer->GetTargetKeyCountBit() < keySize*keyNumber){
3877 jError[
"message"] =
"insufficient amount of key material";
3880 jError[
"message"] =
"keys are being transformed";
3894 NS_LOG_FUNCTION(
this << key->GetId() << key->GetSizeInBits() << srcNodeId << dstNodeId );
3896 bool output =
false;
3903 output = buffer->AddNewKey(key,0);
3906 double generationRate = buffer->GetAverageKeyGenerationRate();
3907 keyAssociation.
SetSKR(generationRate);
3910 double averageConsumptionRate = buffer->GetAverageKeyConsumptionRate();
3915 double ratio = generationRate - expectedConsumptionRate;
3921 <<
"keyAssociationId:" << keyAssociation.
GetId()
3922 <<
"AverageKeyGenerationRate:" << keyAssociation.
GetSKR()
3948 NS_LOG_FUNCTION(
this <<
"Create JSON Key Container data structure!");
3950 for(uint32_t i = 0; i < keys.size(); i++){
3952 std::string encodedKey =
Base64Encode(keys[i]->ConsumeKeyString());
3954 jkeys[
"keys"].push_back({ {
"key_ID", keys[i]->GetId()}, {
"key", encodedKey} });
3975 output = ksidRaw.
string();
3986 NS_LOG_FUNCTION(
this <<
"Checking the state of the association " << ksid <<
" ...");
3987 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
3989 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
3993 if(it->second.associationDirection == 0 && it->second.peerRegistered){
3995 (it->second).tempBuffer.empty() &&
3996 ((it->second).buffer.empty() || !(it->second).buffer.begin()->second.ready)
4000 it->second.qos.maxRate,
4001 it->second.qos.priority
4005 }
else if(it->second.associationDirection == 1){
4006 NS_FATAL_ERROR(
this <<
"This function must not be called on replica KMS for a given association " << ksid);
4014 std::map<std::string, Association004>::iterator it;
4018 if( it->second.qos.TTL < currentTime ) {
4020 <<
"ksid: " << (it->second).ksid
4021 <<
"srcSaeId: " << (it->second).srcSaeId
4022 <<
"dstSaeId: " << (it->second).dstSaeId
4023 <<
" with TTL time: " << it->second.qos.TTL
4039 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
4041 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
4045 UUID dstSae = (it->second).dstSaeId;
4058 buffer->GetReadyKeyCountBit() - buffer->GetTargetKeyCountBit() < keyAmount &&
4059 buffer->GetReadyKeyCountBit() - buffer->GetTargetKeyCountBit() >= it->second.qos.chunkSize
4062 keyAmount = it->second.qos.chunkSize;
4063 }
else if(buffer->GetReadyKeyCountBit() - buffer->GetTargetKeyCountBit() < it->second.qos.chunkSize){
4064 NS_LOG_FUNCTION(
this <<
"Not enough key material to assign to the association dedicated buffer!" );
4070 bool addKeysReady =
false;
4071 while(!addKeysReady){
4072 Ptr<QKDKey> key = buffer->SearchOptimalKeyToTransform(keyAmount);
4075 buffer->ReserveKey(key->GetId());
4076 jkeyIDs[
"keys"].push_back({ {
"key_ID", key->GetId()} });
4077 (it->second).tempBuffer.push_back(key->GetId());
4079 if(key->GetSizeInBits() >= keyAmount){
4080 addKeysReady =
true;
4083 keyAmount -= key->GetSizeInBits();
4085 NS_LOG_FUNCTION(
this <<
"Found key " << key->GetId() <<
" of size " << key->GetSizeInBits() <<
" to transform.\n Remaining key ammount to find: " << keyAmount);
4089 std::ostringstream peerkmsAddressTemp;
4090 dstKms.
Print(peerkmsAddressTemp);
4091 std::string headerUri =
"http://" + peerkmsAddressTemp.str ();
4092 headerUri +=
"/api/v1/associations/fill/" + ksid;
4094 std::string msg = jkeyIDs.dump();
4099 std::string hMessage = httpMessage.
ToString();
4101 (uint8_t*) (hMessage).c_str(),
4115 sendSocket->
Send(packet);
4116 NS_LOG_FUNCTION(
this <<
"Proposal of keys to fill association " << ksid
4117 <<
" dedicated store is sent!" << packet->
GetUid() << packet->
GetSize() << headerUri << msg );
4119 NS_FATAL_ERROR(
this <<
"QKD Buffer for this connection is not found!" );
4128 std::map<std::string, Association004>::iterator it =
m_associations004.find(ksid);
4130 NS_LOG_DEBUG(
this <<
" Key stream association identified with " << ksid <<
" does not exists!" );
4134 uint32_t keyChunkSize = (it->second).qos.chunkSize /8;
4135 std::string secretKey = key->ConsumeKeyString();
4137 NS_LOG_FUNCTION(
this <<
"Secret key size (bytes) " << secretKey.size() );
4139 uint32_t startingIndex = (it->second).lastIndex;
4140 bool startingInReady =
true;
4142 if((it->second).buffer.rbegin() != (it->second).buffer.rend()){
4143 startingIndex = (it->second).buffer.rbegin()->first;
4144 if( ((it->second).buffer.rbegin()->second).ready !=
true )
4145 startingInReady =
false;
4148 }
else if((it->second).lastIndex != 0)
4151 NS_LOG_FUNCTION (
this <<
"Chunk size (bytes), Start Index, Start Ready" << keyChunkSize << startingIndex << startingInReady);
4153 while (!secretKey.empty())
4155 if(!startingInReady)
4157 uint32_t currentChunkSize = ( (it->second).buffer.rbegin()->second ).key.size();
4159 uint32_t diff = keyChunkSize - currentChunkSize;
4162 std::string incompleteChunkKey = (it->second).buffer.rbegin()->second.key;
4163 if(secretKey.size() >= diff){
4164 std::string diffKey = secretKey.substr(0, diff);
4165 std::string temp = secretKey.substr(diff);
4167 std::string completeKey = incompleteChunkKey+diffKey;
4168 NS_LOG_FUNCTION(
this << incompleteChunkKey << diffKey << completeKey);
4170 (it->second).buffer.rbegin()->second.key = completeKey;
4171 (it->second).buffer.rbegin()->second.ready =
true;
4173 NS_LOG_FUNCTION(
this << startingIndex << (it->second).buffer.rbegin()->second.key );
4176 startingInReady =
true;
4178 std::string completeKey = incompleteChunkKey+secretKey;
4180 (it->second).buffer.rbegin()->second.key = completeKey;
4186 if (secretKey.size() >= keyChunkSize)
4189 len = secretKey.size();
4193 key = secretKey.substr(0, len);
4194 temp = secretKey.substr(len);
4201 keyC.
index = startingIndex;
4203 if (len == keyChunkSize)
4208 (it->second).buffer.insert(std::make_pair(startingIndex, keyC));
4213 (it->second).lastIndex = startingIndex - 1;
4214 NS_LOG_FUNCTION(
this <<
"Last index stored is " << (it->second).lastIndex );
4217 NS_LOG_FUNCTION(
this <<
"Is association empty:" << (it->second).buffer.empty() );
4218 NS_LOG_FUNCTION(
this <<
"Is association first key ready:" << (it->second).buffer.begin()->second.ready );
4219 NS_LOG_FUNCTION(
this <<
"How many keys do we have in association:" << (it->second).buffer.size() );
4227 CryptoPP::StringSource(input,
true,
4228 new CryptoPP::Base64Encoder(
4229 new CryptoPP::StringSink(output)
4239 CryptoPP::StringSource(input,
true,
4240 new CryptoPP::Base64Decoder(
4241 new CryptoPP::StringSink(output)
4261 if (jOpenConnectRequest.contains(
"QoS")) {
4262 if (jOpenConnectRequest[
"QoS"].contains(
"key_chunk_size")) inQos.
chunkSize = jOpenConnectRequest[
"QoS"][
"key_chunk_size"];
4263 if (jOpenConnectRequest[
"QoS"].contains(
"max_bps")) inQos.
maxRate = jOpenConnectRequest[
"QoS"][
"max_bps"];
4264 if (jOpenConnectRequest[
"QoS"].contains(
"min_bps")) inQos.
minRate = jOpenConnectRequest[
"QoS"][
"min_bps"];
4265 if (jOpenConnectRequest[
"QoS"].contains(
"jitter")) inQos.
jitter = jOpenConnectRequest[
"QoS"][
"jitter"];
4266 if (jOpenConnectRequest[
"QoS"].contains(
"priority")) inQos.
priority = jOpenConnectRequest[
"QoS"][
"priority"];
4267 if (jOpenConnectRequest[
"QoS"].contains(
"timeout")) inQos.
timeout = jOpenConnectRequest[
"QoS"][
"timeout"];
4268 if (jOpenConnectRequest[
"QoS"].contains(
"TTL")) inQos.
TTL = jOpenConnectRequest[
"QoS"][
"TTL"];
4289 std::string srcSaeId,
4290 std::string dstSaeId,
4294 std::string appConnectionId
4300 association004.
srcSaeId = srcSaeId;
4301 association004.
dstSaeId = dstSaeId;
4302 association004.
qos = inQos;
4306 ksid = appConnectionId;
4313 association004.
ksid = ksid;
4332 <<
"minRate:" << inQos.
minRate
4333 <<
"maxRate:" << inQos.
maxRate
4336 <<
"jitter:" << inQos.
jitter
4337 <<
"timeout:" << inQos.
timeout
4338 <<
"TTL:" << inQos.
TTL
4351 <<
"keyAssociationId:" << keyAssociation.
GetId()
4352 <<
"SKR:" << keyAssociation.
GetSKR()
4354 <<
"ratioSKR:" << ratioSKR
4358 uint32_t processWithQos = 1;
4403 std::map<std::string, uint32_t>::iterator it2 =
m_sessionList.find(ksid);
4405 NS_LOG_FUNCTION(
this <<
"SESSION with KSID " << ksid <<
" was located in the m_session_list!");
4407 NS_LOG_FUNCTION(
this <<
"SESSION with KSID " << ksid <<
" was *NOT* located in m_session_list!");
4408 NS_LOG_FUNCTION(
this <<
"WE HAVE NO ENOUGH RESOURCES TO SERVE UNTRUSTED APPS AT THE MOMENT!");
4428 uint32_t chunkSizeDoubled = (inQos.
chunkSize*1);
4429 uint32_t requestedNumberOfChunkKeys = 0;
4431 requestedNumberOfChunkKeys = 1;
4433 requestedNumberOfChunkKeys = ceil(inQos.
maxRate/chunkSizeDoubled);
4435 uint32_t supportedNumberOfChunkKeys = round (keyAssociation.
GetEffectiveSKR()/chunkSizeDoubled);
4436 uint32_t priorityThreshold = round(supportedNumberOfChunkKeys/2);
4437 uint32_t providedNumberOfChunkKeys;
4440 providedNumberOfChunkKeys =
m_random->
GetValue (priorityThreshold, supportedNumberOfChunkKeys);
4445 if(providedNumberOfChunkKeys > requestedNumberOfChunkKeys)
4446 providedNumberOfChunkKeys = requestedNumberOfChunkKeys;
4448 NS_LOG_FUNCTION(
this <<
"requestedNumberOfChunkKeys:" << requestedNumberOfChunkKeys);
4449 NS_LOG_FUNCTION(
this <<
"supportedNumberOfChunkKeys:" << supportedNumberOfChunkKeys);
4451 NS_LOG_FUNCTION(
this <<
"providedNumberOfChunkKeys:" << providedNumberOfChunkKeys);
4459 std::map<std::string, uint32_t>::iterator it2 =
m_sessionList.find(ksid);
4461 providedTTL *= it2->second;
4462 NS_LOG_FUNCTION(
this <<
"SESSION with KSID " << ksid <<
" was located in the m_session_list!");
4464 NS_LOG_FUNCTION(
this <<
"SESSION with KSID " << ksid <<
" was *NOT* located in m_session_list!");
4467 if(providedTTL > inQos.
TTL) providedTTL = inQos.
TTL;
4468 outQos.
TTL = providedTTL;
4482 requestedNumberOfChunkKeys,
4483 supportedNumberOfChunkKeys,
4484 providedNumberOfChunkKeys,
4495 uint32_t chunkSizeDoubled = (inQos.
chunkSize);
4496 uint32_t supportedNumberOfChunkKeys = round (keyAssociation.
GetEffectiveSKR()/chunkSizeDoubled);
4497 uint32_t requestedNumberOfChunkKeys = ceil (inQos.
maxRate/chunkSizeDoubled);
4498 uint32_t providedNumberOfChunkKeys = requestedNumberOfChunkKeys;
4499 uint32_t priorityThreshold = 0;
4501 if(requestedNumberOfChunkKeys > supportedNumberOfChunkKeys)
4504 providedNumberOfChunkKeys = 0;
4507 NS_LOG_FUNCTION(
this <<
"requestedNumberOfChunkKeys:" << requestedNumberOfChunkKeys);
4508 NS_LOG_FUNCTION(
this <<
"supportedNumberOfChunkKeys:" << supportedNumberOfChunkKeys);
4510 NS_LOG_FUNCTION(
this <<
"providedNumberOfChunkKeys:" << providedNumberOfChunkKeys);
4516 requestedNumberOfChunkKeys,
4517 supportedNumberOfChunkKeys,
4518 providedNumberOfChunkKeys,
4536 keyId = keyIdRaw.
string();
a polymophic address class
bool IsInvalid(void) const
The base class for all ns3 applications.
virtual void DoDispose(void)
Destructor implementation.
Class for representing data rates.
uint64_t GetBitRate() const
Get the underlying bitrate.
AttributeValue implementation for DataRate.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
An identifier for simulation events.
The basic class to represent both HTTP requests and responses.
uint16_t GetStatusCode() const
Get the status code for this message.
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()
void CreateResponse(const HttpStatus status)
HTTPMessage::HttpMethod GetMethod() const
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)
AttributeValue implementation for Ipv4Address.
uint32_t GetId(void) const
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current 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.
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).
Introspection did not find any typical Config paths.
void PrintRegistryInfo()
Print the registry information.
ConnectionType
The connection types.
@ ETSI_QKD_004_AUTHENTICATION
@ ETSI_QKD_014_AUTHENTICATION
@ ETSI_QKD_004_ENCRYPTION
@ ETSI_QKD_014_ENCRYPTION
UUID GetSrcSaeId()
Get the source (sender) application identifier.
void SetId(UUID value)
Set the application identifier.
bool IsValid()
Check if entry is valid.
UUID GetId()
Get the application identifier.
Ipv4Address GetDestinationKmsAddress() const
Get the destination KMS IP address.
QKDConnectionRegister is a class used to keep details about distant QKD links and applications.
Introspection did not find any typical Config paths.
Ipv4Address GetDestinationKmsAddress() const
Get destination KMS Address.
void SetExpectedConsumption(double value)
void PrintRegistryInfo()
Print registry info.
Ptr< QKDBuffer > GetSourceBuffer()
double GetExpectedConsumption()
Ipv4Address GetSourceKmsAddress() const
Get source KMS Address.
void SetUpdateStatusInterval(double statusInterval)
double GetUpdateStatusInterval()
void SetSKR(double value)
void SetEffectiveSKR(double value)
Address m_sdnControllerAddress
The SDN controller address.
void ProcessRegisterResponse(HTTPMessage header, Ptr< Socket > socket)
Process the REGISTER response.
uint32_t GetMaxKeyPerRequest()
Get maximum number of keys that can be supplied via a single response (ETSI QKD 014).
uint32_t m_port
Local port to bind to.
QKDApplicationEntry GetApplicationConnectionDetails(std::string saeId)
Get the application connection details.
TracedCallback< const std::string &, Ptr< QKDKey > > m_keyServedETSI014Trace
A trace for the consumed keys by the ETSI 014 clients.
void HandlePeerCloseKMSs(Ptr< Socket > socket)
Handle a connection close from the KMS.
void DataSend(Ptr< Socket >, uint32_t)
Callback function for the data sent.
Ptr< QKDKMSQueueLogic > m_queueLogic
The KMS Queue Logic for the ETSI 004 QoS handling.
void SendToSocketPairKMS(Ptr< Socket > socket, Ptr< Packet > packet)
Send the packet to the pair socket.
RequestType
Request methods.
@ ETSI_QKD_014_GET_KEY
Integer equivalent = 1.
@ ETSI_QKD_014_GET_KEY_WITH_KEY_IDS
Integer equivalent = 2.
@ ETSI_QKD_004_OPEN_CONNECT
@ ETSI_QKD_014_GET_STATUS
Integer equivalent = 0.
void HandleAccept(Ptr< Socket > s, const Address &from)
Handle an incoming connection from the application.
std::map< std::string, Association004 > m_associations004
The list of active key stream sessions.
Ptr< Socket > GetSendSocketKMS(Ipv4Address kmsDstAddress)
Obtain the send socket.
uint32_t m_default_ttl
The default value of TTL.
void DataToSDNSend(Ptr< Socket >, uint32_t)
Callback function for the data sent to the SDN controller.
uint32_t GetTotalRx() const
Get the total amount of received bytes.
void HttpKMSAddQuery(Ipv4Address dstKms, HttpQuery request)
Remember the HTTP request made to the peer KMS.
uint32_t ScheduleCheckAssociation(Time t, std::string action, std::string ksid)
Schedule the next event in the attempt to fill the key stream session buffer.
void ProcessRegisterRequest(HTTPMessage header, std::string ksid, Ptr< Socket > socket)
Process the REGISTER request.
QKDKeyAssociationLinkEntry GetKeyAssociationByNodeIds(uint32_t srcNodeId, uint32_t dstNodeId)
Get the key association link details.
std::multimap< UUID, Ptr< Socket > > m_http004App
The list of HTTP requests (without response) set to the application.
Ipv4Address GetDestinationKmsAddress(Ptr< Socket > socket)
Get the destiantion KMS IP address based on the connected socket.
void Http004AppQuery(UUID saeId, Ptr< Socket > socket)
Remember the HTTP request received from the application.
nlohmann::json Check014GetKeyRequest(nlohmann::json request, QKDKeyAssociationLinkEntry conn)
Validate the request and probe if the KMS can meet the request requirements.
void HandleAcceptKMSs(Ptr< Socket > s, const Address &from)
Handle an incoming connection from the KMS.
void CreateNew004Association(std::string srcSaeId, std::string dstSaeId, QKDKeyManagerSystemApplication::QoS &inQos, Ipv4Address dstKms, std::string &ksid, std::string appConnectionId)
Create a new key stream session.
std::map< Ipv4Address, std::pair< Ptr< Socket >, Ptr< Socket > > > m_socketPairsKMS
The accepted sockets for the communication between KMSs.
void HandleAcceptSDN(Ptr< Socket > s, const Address &from)
Handle an incoming connection from the SDN.
uint32_t m_totalRx
Total bytes received.
void PurgeExpiredAssociations()
Purge (delete) the expired ETSI 004 key stream sessions based on the QoS - TTL value.
void ProcessPacketKMSs(HTTPMessage header, Ptr< Packet > packet, Ptr< Socket > socket)
Process incoming request at the KM link.
std::string Base64Encode(std::string input)
Base64 encoder.
void ConnectionSucceeded(Ptr< Socket > socket)
Callback function after the connection to the APP is complete.
std::string GenerateKeyId()
Generate unique key identifier.
void ProcessRequestKMS(HTTPMessage header, Ptr< Socket > socket)
Process request from the peer KMS.
std::map< Ptr< Socket >, Ptr< Packet > > m_packetQueues
Buffering unsend messages due to the connection problems.
void TransformKeys(uint32_t keySize, uint32_t keyNumber, UUID slave_SAE_ID)
Transform a number of keys to a given size.
void NewAppRequest(std::string ksid)
Make a NEW_APP request to the peer KMS.
void HttpKMSCompleteQuery(Ipv4Address dstKms)
Remove the HTTP request from the list.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTrace
A trace for the received packets from the applications.
void ProcessResponseKMS(HTTPMessage header, Ptr< Packet > packet, Ptr< Socket > socket)
Process response from the peer KMS.
void SetSocket(std::string type, Ptr< Socket > socket)
Set the sink socket.
void SendQKDLinkStatusToSDN(UUID linkId, double updatePeriod)
Send the QKD link statistics to the SDN controller.
std::string AddNewLink(uint32_t srcSaeId, uint32_t dstSaeId, Ipv4Address kmsDstAddress, Ptr< QKDBuffer > srcBuffer)
Register a new QKD link, or a pair of post-processing applications.
TracedCallback< const std::string &, const uint32_t &, const uint32_t & > m_keyServedETSI004Trace
A trace for the consumed keys by the ETSI 004 clients.
static uint32_t nKMS
The number of created KMSs.
void RegisterRequest(std::string ksid)
Send the REGISTER request.
QKDKeyManagerSystemApplication::RequestType FetchRequestType(std::string s)
Read the request method from the request URI.
void ProcessAddKeysRequest(HTTPMessage h, Ptr< Socket > socket, std::string ksid)
Process the FILL request.
uint32_t m_sdnSupportEnabled
The support for the SDN.
uint32_t m_kms_id
The KMS identifier.
TypeId m_tid
The object type identifier.
void ProcessCloseRequest(std::string ksid, HTTPMessage header, Ptr< Socket > socket)
static TypeId GetTypeId(void)
Get the type ID.
void NegotiateKeysForAssociation(std::string ksid, uint32_t keyAmount=1024, uint32_t priority=0)
Add new keys to the key stream session buffer.
void DataSendKMSs(Ptr< Socket >, uint32_t)
Callback function for the data sent to the peer KMS.
void CheckSessionList(std::string ksid)
Check whether a new OPEN_CONNECT was received before the previously established session expired.
Ipv4Address GetAddress()
Get the local IP address.
void HandleReadKMSs(Ptr< Socket > socket)
Handle a packet received from the KMS.
void HandlePeerError(Ptr< Socket > socket)
Handle a connection error from the application.
void HandlePeerErrorSDN(Ptr< Socket > socket)
Handle a connection error from the SDN.
void SetNode(Ptr< Node > n)
Set the node.
double m_qos_maxrate_threshold
The maximal rate threshold.
void ProcessResponseSDN(HTTPMessage header, Ptr< Packet > packet, Ptr< Socket > socket)
Process response from the SDN controller.
TracedCallback< const Ipv4Address &, Ptr< const Packet > > m_dropTrace
A trace for the dropped packets.
void HandlePeerClose(Ptr< Socket > socket)
Handle an connection close from the application.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTraceKMSs
A trace for the received packets from the peer KMS.
nlohmann::json CreateKeyContainer(std::vector< Ptr< QKDKey >> keys)
Create the key container data structure.
QKDApplicationEntry GetApplicationConnectionDetailsBySaeIDsAndType(std::string srcSaeId, std::string dstSaeId, QKDApplicationEntry::ConnectionType type)
Get the application connection details.
void PrepareSinkSocket()
Prepare the sink socket.
uint32_t m_maliciousBlocking
Should KMS detect and block malicious requests?
std::map< Ptr< Socket >, Ptr< Socket > > m_socketPairs
The accepted sockets.
void PacketReceivedKMSs(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Assemble a byte stream from the peer KMS to extract the HTTP message.
void ProcessTransformRequest(HTTPMessage header, Ptr< Socket > socket)
Process the transform request.
TracedCallback< const uint32_t & > m_newKeyGeneratedTraceEmir
A trace for the generated keys.
void ProcessGetKey004Request(std::string ksid, HTTPMessage header, Ptr< Socket > socket)
Ptr< Socket > GetSocketFromHttp004AppQuery(UUID saeId)
Lookup the HTTP request and obtain connected socket.
void ProcessOpenConnectRequest(HTTPMessage header, Ptr< Socket > socket)
std::map< Ptr< Socket >, Ptr< Socket > > GetAcceptedSockets(void) const
Get the list of all the accepted sockets.
void ProcessNewAppResponse(HTTPMessage header, Ptr< Socket > socket)
Process the NEW_APP response.
Ptr< Node > GetNode()
Get the node.
bool CheckDoSAttack(HTTPMessage headerIn, Ptr< Socket > socket)
Check for the DoS attack.
void CheckAssociation(std::string ksid)
Check the state of a single key stream session.
Ptr< Socket > m_sinkSocketFromSDN
The sink socket from the SND controller.
void ProcessKMSCloseRequest(HTTPMessage header, Ptr< Socket > socket, std::string ksid)
Process the close request from the peer KMS.
RequestType HttpQueryMethod(Ipv4Address dstKms)
Map the HTTP response and obtain the request method.
std::map< Ipv4Address, uint32_t > m_flagedIPAdr
A list of flaged IP addresses.
uint32_t m_maxKeyPerRequest
The maximal number of keys per request application can ask for.
QKDKeyAssociationLinkEntry GetKeyAssociationById(UUID keyAssociationId)
Get the key association link details.
void ProcessKMSCloseResponse(HTTPMessage header, Ptr< Socket > socket)
Process close response from the peer KMS.
void SaveKeyAssociation(QKDKeyAssociationLinkEntry &rt)
Add the key association.
void ConnectionToSDNSucceeded(Ptr< Socket > socket)
Callback function after the connection to the SDN controller is complete.
void AddKeyToAssociationDedicatedStore(std::string ksid, Ptr< QKDKey > key)
Add the key to the key stream session buffer.
bool connectedToSDN
Is conncted to the SDN controller?
void HandlePeerErrorKMSs(Ptr< Socket > socket)
Handle a connection error from the KMS.
DataRate m_minKeyRate
The minimal key rate.
std::map< Ptr< Socket >, Ptr< Packet > > m_packetQueuesToSDN
Buffering unsend messages due to the connection problems.
uint32_t m_defaultKeySize
The default key size KMS will deliver if the size was not defined in the request.
std::vector< std::string > ProcessUriParams(std::string s)
Read the URI parameters in a vector.
void ConnectionToSDNFailed(Ptr< Socket > socket)
Callback function after the connection to the SDN controller has failed.
void ProcessRequestSDN(HTTPMessage header, Ptr< Packet > packet, Ptr< Socket > socket)
Process request from the SDN controller.
void SendToSocketPair(Ptr< Socket > socket, Ptr< Packet > packet)
Send the packet to the pair socket.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTraceSDN
A trace for the received packets from the SDN controller.
uint32_t m_maxKeySize
The maximal size of the key application can request.
Ptr< Socket > m_sinkSocket
The sink socket.
uint32_t m_totalRxKMSs
Total bytes sent between KMSs.
void PacketReceivedSDN(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Assemble a byte stream from the SDN to extract the HTTP message.
void ProcessTransformResponse(HTTPMessage header, Ptr< Socket > socket)
Process the transform response.
void HandleReadSDN(Ptr< Socket > socket)
Handle a packet received from the SDN.
void HandleRead(Ptr< Socket > socket)
Handle a packet received from the application.
DataRate m_maxKeyRate
The maximal key rate.
QKDKeyAssociationLinkEntry GetKeyAssociationLinkDetailsByApplicationId(std::string appId)
Get the key association link details.
void ReadJsonQos(QKDKeyManagerSystemApplication::QoS &inQos, nlohmann::json jOpenConnectRequest)
Read the QoS parameters from the JSON OPEN_CONNECT structure.
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_bufferKMS
The buffer for the received packets from the peer KMS (TCP segmentation).
QKDApplicationEntry RegisterApplicationEntry(UUID keyAssociationId, UUID applicationEntryId, UUID srcSaeId, UUID dstSaeId, std::string type, Ipv4Address dstKmsAddress, uint32_t priority, double expirationTime)
Register a new pair of QKD applications.
void StartApplication(void)
Start the KMS Application.
bool ProcessQoSRequest(QKDApplicationEntry &appConnection, QKDKeyAssociationLinkEntry &keyAssociation, QKDKeyManagerSystemApplication::QoS &inQos, QKDKeyManagerSystemApplication::QoS &outQos, std::string ksid)
Process the QoS requirements.
TracedCallback< const std::string &, const std::string &, const uint32_t &, const uint32_t &, const uint32_t &, const uint32_t &, const uint32_t & > m_providedQoS
A trace for the admitted QoS.
void ProcessNewAppRequest(HTTPMessage header, Ptr< Socket > socket)
virtual ~QKDKeyManagerSystemApplication()
Destructor.
bool AddNewKey(Ptr< QKDKey > key, uint32_t srcNodeId, uint32_t dstNodeId)
Add new keys to the QKD buffer.
std::string GenerateKsid()
Generate a new key stream session identifier (ksid).
std::map< std::string, uint32_t > m_sessionList
A list of sessions.
std::map< Ipv4Address, std::vector< HttpQuery > > m_httpRequestsQueryKMS
The list of HTTP request (without response) sent to the peer KMS.
uint32_t m_minKeySize
The minimal size of the key application can request.
void PacketReceived(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Assemble a byte stream from the application to extract the HTTP message.
void StopApplication(void)
Stop the KMS Application.
TracedCallback< Ptr< const Packet > > m_txTraceKMSs
A trace for the sent packets to the peer KMS.
virtual void DoDispose(void)
Destructor implementation.
void ReleaseAssociation(std::string ksid, std::string surplusKeyId, uint32_t syncIndex)
Release the key stream session.
void HandlePeerCloseSDN(Ptr< Socket > socket)
Handle a connection close from the SDN.
void ConnectionFailedKMSs(Ptr< Socket > socket)
Callback function after the connection to the peer KMS has failed.
void ConnectionFailed(Ptr< Socket > socket)
Callback function after the connection to the APP has failed.
void ProcessRequest(HTTPMessage header, Ptr< Packet > packet, Ptr< Socket > socket)
Process incoming requests from the service layer, i.e., QKD applications.
TracedCallback< const uint32_t & > m_keyServedTraceEmir
A trace for the consumed keys.
TracedCallback< Ptr< const Packet > > m_txTrace
A trace for the sent packets to the applications.
void ConnectToSDNController()
Connect to the SDN controller.
Ptr< Socket > GetSocket(void) const
Get the sink socket.
Ptr< Socket > m_sendSocketToSDN
The send socket to the SDN controller.
Ptr< UniformRandomVariable > m_random
The uniform random variable.
void ConnectionSucceededKMSs(Ptr< Socket > socket)
Callback function after the connection to the peer KMS is complete.
uint32_t GetId()
Get the KMS identifier.
void ProcessAddKeysResponse(HTTPMessage header, Ptr< Socket > socket)
Process the FILL response.
void CheckSocketsKMS(Ipv4Address dstSaeId)
Prepare the send socket to communicate with the peer KMS.
uint32_t m_kms_key_id
The counter value to assure generation of the unique key identifiers.
QKDKeyManagerSystemApplication()
Constructor.
std::string Base64Decode(std::string input)
Base64 decoder.
uint32_t GetPort()
Get the local port.
TracedCallback< const uint32_t &, const uint32_t & > m_newKeyGeneratedTrace
A trace for the generated keys.
Ipv4Address m_local
Local address to bind to.
void Http004AppQueryComplete(UUID saeId)
Remove the HTTP request from the list.
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 ShutdownRecv(void)=0
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.
virtual enum Socket::SocketType GetSocketType(void) const =0
static TypeId GetTypeId(void)
Get the type ID.
Simulation virtual time values and global simulation resolution.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
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 Nil()
Generate nil UUID0 (all bits set to zero)
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.
make Callback use a separate empty 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 > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeIpv4AddressChecker(void)
Ptr< const AttributeAccessor > MakeIpv4AddressAccessor(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_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.
std::string GetQKDApplicationEntryText(const uint16_t statusCode)
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...
The key stream session details.
uint32_t associationDirection
The key within the key stream session buffer.
The HTTP request details.
std::vector< std::string > transform_key_IDs
uint32_t transform_key_number
uint32_t transform_key_size
std::string surplus_key_ID
std::vector< std::string > to_transform_key_IDs
The Quality of service indicators.