10#include "ns3/qcen-control.h"
11#include "ns3/address.h"
13#include "ns3/nstime.h"
14#include "ns3/socket.h"
15#include "ns3/simulator.h"
16#include "ns3/tcp-socket-factory.h"
17#include "ns3/packet.h"
18#include "ns3/uinteger.h"
19#include "ns3/trace-source-accessor.h"
37 static TypeId tid =
TypeId(
"ns3::QKDKeyManagerSystemApplication")
39 .SetGroupName(
"Applications")
41 .AddAttribute(
"Protocol",
"The type of protocol to use.",
45 .AddAttribute(
"LocalAddress",
"The ipv4 address of the application",
49 .AddAttribute(
"MaximalKeysPerRequest",
50 "The maximal number of keys per request(ESTI QKD 014)",
54 .AddAttribute(
"MinimalKeySize",
55 "The minimal size of key QKDApp can request",
59 .AddAttribute(
"MaximalKeySize",
60 "The maximal size of key QKDApp can request",
64 .AddAttribute(
"BufferList",
"The list of Qbuffers needed for plotting QKDGraphs.",
68 .AddTraceSource(
"Tx",
"A new packet is created and is sent to the APP",
70 "ns3::QKDKeyManagerSystemApplication::Tx")
71 .AddTraceSource(
"Rx",
"A packet from the APP has been received",
73 "ns3::QKDKeyManagerSystemApplication::Rx")
74 .AddTraceSource(
"TxKMSs",
"A new packet is created and is sent to the APP",
76 "ns3::QKDKeyManagerSystemApplication::TxKMSs")
77 .AddTraceSource(
"RxKMSs",
"A packet from the APP has been received",
79 "ns3::QKDKeyManagerSystemApplication::RxKMSs")
80 .AddTraceSource(
"QKDKeyGenerated",
"The trace to monitor key material received from QL",
82 "ns3::QKDKeyManagerSystemApplication::QKDKeyGenerated")
83 .AddTraceSource(
"KeyServed",
"The trece to monitor key usage",
85 "ns3::QKDKeyManagerSystemApplication::KeyServed")
86 .AddTraceSource(
"KeyConsumedLink",
"The trece to monitor p2p key usage",
88 "ns3::QKDKeyManagerSystemApplication::KeyConsumedLink")
89 .AddTraceSource(
"RelayConsumption",
"The trace to monitor key material consumed for key relay",
91 "ns3::QKDKeyManagerSystemApplication::RelayConsumption")
92 .AddTraceSource(
"WasteRelay",
"The trace to monitor failed relays",
94 "ns3::QKDKeyManagerSystemApplication::WasteRelay")
160 NS_LOG_FUNCTION(
this <<
"Do nothing since centralized controller is not set!");
172 if(
it->second != 3 &&
qBuffer->GetState() == 3){
177 }
else if(
it->second == 3 &&
qBuffer->GetBitCount() >
qBuffer->GetMthr() && sBuffer->GetSBitCount() > sBuffer->GetMthr()){
207 address =
it->second;
273 it->second->Initialize();
275 it->second->SetKeySize(
285 it1->second->Initialize();
287 it1->second->SetKeySize(
333 <<
"BitCount: " <<
ie->second->GetSBitCount()
334 <<
"\n SBitCount: " <<
ie->second->GetBitCount()
335 <<
"\n Max: " <<
ie->second->GetMmax()
339 ie->second->GetBitCount() >=
ie->second->GetMmax() &&
340 id->second->GetBitCount() >= id->second->GetMmax()
389 NS_LOG_FUNCTION(
this <<
"How many keys in S-Buffer" << sBuffer->GetSKeyCount()
416 NS_LOG_FUNCTION(
this <<
"Source cannot perform relay due to the lack of key material!");
441 std::vector<std::string> keyIds {};
448 relayPayload[
"keys"].push_back({ {
"key_ID", key->GetId()} });
449 keyIds.push_back(key->GetId());
464 amount -= key->GetSizeInBits();
501 query.keyIds = keyIds;
506 << packet->GetUid() << packet->GetSize());
513 std::string direction,
520 if(direction ==
"enc" || direction ==
"dec"){
526 NS_FATAL_ERROR(
this <<
"Unknown key stream session" << direction);
528 sBuffer =
it->second.stre_buffer;
535 std::vector<std::string> keyIds;
537 if(direction ==
"enc")
539 else if(direction ==
"dec")
550 sBuffer->GetBitCount() + sBuffer->GetKeySize() > sBuffer->GetMmax() &&
554 NS_LOG_FUNCTION(
this <<
"To be sure that we not exceed capacity of S-Buffer!");
566 NS_LOG_FUNCTION(
this <<
"We obtained random key from qBUFFER: " << key->GetId());
568 fillPayload[
"keys"].push_back({ {
"key_ID", key->GetId()} });
569 keyIds.push_back(key->GetId());
570 sBuffer->StoreKey(key,
true);
573 if(key->GetSizeInBits() >
amount)
575 NS_LOG_DEBUG(
this <<
"Trying to FILL beyond buffer capacity! " << key->GetSizeInBits() <<
" / " << sBuffer->GetKeySize());
580 amount -= key->GetSizeInBits();
614 query.sBuffer = direction;
615 query.keyIds = keyIds;
620 << packet->GetUid() << packet->GetSize());
632 }
else if(type ==
"dec"){
699 std::map<Ipv4Address, std::pair<Ptr<Socket>,
Ptr<Socket> > >::iterator
it;
701 if(
it->second.first) {
703 it->second.first =
nullptr;
705 if(
it->second.second) {
707 it->second.second =
nullptr;
736 it->second.first = s;
755 NS_LOG_FUNCTION(
this <<
"QKDKeyManagerSystemApplication Connection succeeded");
759 if(
j->first == socket){
773 NS_LOG_FUNCTION(
this <<
"QKDKeyManagerSystemApplication KMSs Connection succeeded");
780 NS_LOG_FUNCTION(
this <<
"QKDKeyManagerSystemApplication, Connection Failed");
787 NS_LOG_FUNCTION(
this <<
"QKDKeyManagerSystemApplication, Connection Failed");
837 socket->Send(packet);
839 NS_LOG_FUNCTION(
this << packet->GetUid() <<
"sent via socket " << socket);
843 NS_LOG_FUNCTION(
this << packet->GetUid() <<
"enqued for socket " << socket);
852 std::map<Ipv4Address, std::pair<Ptr<Socket>,
Ptr<Socket> > >::iterator
it;
855 if(
it->second.first == socket )
881 NS_LOG_FUNCTION(
this <<
"Let's create a new send socket to reach KMS!");
919 NS_LOG_FUNCTION(
this <<
"Socket to peer KMS exist. No action required");
959 while((packet = socket->RecvFrom(from)))
961 if(packet->GetSize() == 0)
967 NS_LOG_FUNCTION(
this << packet <<
"PACKETID: " << packet->GetUid() <<
" of size: " << packet->GetSize() );
972 <<
"s KMS received packet ID: "
973 << packet->GetUid() <<
" of "
974 << packet->GetSize() <<
" bytes from "
977 <<
" total Rx " <<
m_totalRx <<
" bytes");
992 while((packet = socket->RecvFrom(from)))
994 if(packet->GetSize() == 0)
1000 NS_LOG_FUNCTION(
this << packet <<
"PACKETID: " << packet->GetUid() <<
" of size: " << packet->GetSize() );
1005 <<
"s KMS received packet ID: "
1006 << packet->GetUid() <<
" of "
1007 << packet->GetSize() <<
" bytes from KMS "
1010 <<
" total Rx " <<
m_totalRx <<
" bytes");
1028 buffer->AddAtEnd(p);
1029 NS_LOG_DEBUG(
"[DEBUG] Buffer after appending packet UID " << p->GetUid() <<
": " << buffer->GetSize() <<
" bytes");
1034 while (buffer->GetSize() > 0) {
1036 std::string
bufferStr(buffer->GetSize(),
'\0');
1043 NS_LOG_DEBUG(
"[DEBUG] HTTP message is incomplete or fragmented, waiting for more data...");
1059 NS_LOG_DEBUG(
"[DEBUG] Remaining buffer size: " << buffer->GetSize());
1074 buffer->AddAtEnd(p);
1075 NS_LOG_DEBUG(
"[DEBUG] Buffer after adding packet UID " << p->GetUid() <<
": " << buffer->GetSize() <<
" bytes");
1078 while (buffer->GetSize() > 0) {
1080 std::string
bufferStr(buffer->GetSize(),
'\0');
1087 NS_LOG_DEBUG(
"[DEBUG] HTTP message is incomplete or fragmented, waiting for more data...");
1104 NS_LOG_DEBUG(
"[DEBUG] Remaining buffer size: " << buffer->GetSize());
1172 NS_LOG_FUNCTION(
this <<
"Scheduling new event in an attempt to fill association buffer " << ksid <<
" ...");
1173 if(action ==
"CheckEtsi004Association")
1180 NS_LOG_FUNCTION(
this <<
"NEW event successfully scheduled!" << action << ksid <<
t);
1182 NS_LOG_FUNCTION(
this <<
"Event already scheduled!" << action << ksid);
1185 NS_FATAL_ERROR(
this <<
"Invalid action as the function input recived " << action);
1192 if(action ==
"ReleaseAssociation")
1200 NS_LOG_FUNCTION(
this <<
"NEW event successfully scheduled!" << action << ksid);
1202 NS_LOG_FUNCTION(
this <<
"Event already scheduled!" << action << ksid);
1205 NS_FATAL_ERROR(
this <<
"Invalid action as the function input recived " << action);
1254 NS_LOG_FUNCTION(
this <<
"The S-Buffer does not exists! This is new virtual connection!");
1259 m_keys_enc.insert(std::make_pair(dstNodeId, sBuffer));
1260 m_keys_dec.insert(std::make_pair(dstNodeId, sBuffer));
1265 nlohmann::json
j = {
1270 {
"key_size", sBuffer->GetKeySize()},
1271 {
"stored_key_count", sBuffer->GetSKeyCount()},
1272 {
"max_key_count",
uint32_t(sBuffer->GetMmax() / sBuffer->GetKeySize())},
1276 {
"max_SAE_ID_count", 0}
1284 {
"Content-Type",
"application/json; charset=utf-8"},
1285 {
"Request URI", headerIn.GetUri() }
1287 std::string
hMessage = httpMessage.ToString();
1329 NS_LOG_FUNCTION(
this <<
"Validate request and probe ability to serve!");
1335 NS_LOG_DEBUG(
this <<
"We have an error. Request is not valid, or KM is unable to serve!");
1346 NS_LOG_FUNCTION(
this <<
"Form a transform set, and a large merged key!");
1371 std::string
skeyId = GenerateUUID();
1389 conn.GetDestinationKmNodeId(),
1411 jtransform[
"source_node_id"] = GetNode()->GetId();
1422 Ipv4Address
dstKms =
conn.GetDestinationKmsAddress();
1429 headerUri +=
"/api/v1/sbuffers/skey_create";
1431 HTTPMessage httpMessage;
1433 std::string
hMessage = httpMessage.ToString();
1441 httpRequest.method_type = RequestType::TRANSFORM_KEYS;
1447 NS_LOG_FUNCTION(
this <<
"SKEY_CREATE request sent to peer KM" << packet->GetUid() << packet->GetSize());
1452 SBufferClientCheck(
conn.GetDestinationKmNodeId());
1456 HTTPMessage httpMessage;
1458 {
"Content-Type",
"application/json; charset=utf-8"},
1459 {
"Request URI",
headerIn.GetUri() }
1461 std::string
hMessage = httpMessage.ToString();
1468 NS_LOG_FUNCTION(
this <<
"\nSending PacketID: " << packet->GetUid() <<
" of size: " << packet->GetSize() <<
hMessage);
1473 }
else if(
requestType == ETSI_QKD_014_GET_KEY_WITH_KEY_IDS){
1474 QKDLocationRegisterEntry
conn = GetController()->GetRoute(
remoteAppId);
1485 std::vector<std::string>
keyIDs;
1487 keyIDs.push_back((
it.value())[
"key_ID"]);
1490 std::vector<Ptr<QKDKey>> keys {};
1506 conn.GetDestinationKmNodeId(),
1519 nlohmann::json
jkeys = CreateKeyContainer(keys);
1524 msg = nlohmann::json{ {
"message",
"key not found"} }.dump();
1529 HTTPMessage httpMessage;
1531 {
"Content-Type",
"application/json; charset=utf-8"},
1532 {
"Request URI",
headerIn.GetUri() }
1535 std::string
hMessage = httpMessage.ToString();
1542 NS_LOG_FUNCTION(
this <<
"Sending Response to ETSI_QKD_014_GET_KEY\n PacketID: " << packet->GetUid() <<
" of size: " << packet->GetSize() <<
hMessage );
1543 SendToSocketPair(socket, packet);
1545 }
else if(
requestType == ETSI_QKD_004_OPEN_CONNECT) {
1550 ProcessOpenConnectRequest(
headerIn, socket);
1554 ProcessGetKey004Request(ksid,
headerIn, socket);
1556 ProcessCloseRequest(ksid,
headerIn, socket);
1588 <<
"\nKeyID:\t" <<
keyId
1590 <<
"\nKeySize(bits):\t" <<
keyValue.size()*8
1591 <<
"\nQKD Module ID:\t" <<
moduleId
1609 if(
it!=m_qkdmodules.end())
1610 dstNodeId =
it->second;
1616 if(GetNode()->GetId() > dstNodeId)
1664 buffer->StoreKey(
newKey);
1669 UpdateLinkState(dstNodeId);
1672 SBufferClientCheck(dstNodeId);
1681 if(headerIn.
GetUri() !=
"")
1682 ProcessRequestKMS(headerIn, socket);
1684 ProcessResponseKMS(headerIn, packet, socket);
1693 std::string s = headerIn.
GetUri();
1694 std::string delimiter =
"/";
1698 std::vector<std::string> uriParams;
1699 while((pos = s.find(delimiter)) != std::string::npos){
1700 token = s.substr(0, pos);
1702 uriParams.push_back(token);
1704 s.erase(0, pos + delimiter.length());
1707 uriParams.push_back(s);
1709 requestType = FetchRequestType(uriParams[4]);
1711 if(requestType == NEW_APP)
1712 ProcessNewAppRequest(headerIn, socket);
1713 else if(requestType == REGISTER){
1714 std::string ksid = uriParams[5];
1716 ProcessRegisterRequest(headerIn, ksid, socket);
1717 }
else if(requestType == FILL){
1718 std::string resource = uriParams[3];
1719 ProcessFillRequest(headerIn, resource, socket);
1720 }
else if(requestType == TRANSFORM_KEYS){
1721 ProcessSKeyCreateRequest(headerIn, socket);
1722 }
else if(requestType == ETSI_QKD_004_KMS_CLOSE){
1723 std::string ksid = uriParams[5];
1725 ProcessKMSCloseRequest(headerIn, socket, ksid);
1726 }
else if(requestType == RELAY_KEYS){
1727 ProcessRelayRequest(headerIn, socket);
1738 std::vector<std::string> uriParams = ReadUri(headerIn.
GetRequestUri());
1740 RequestType methodType = FetchRequestType(uriParams[4]);
1742 if(methodType == NEW_APP)
1743 ProcessNewAppResponse(headerIn, socket);
1744 else if(methodType == REGISTER)
1745 ProcessRegisterResponse(headerIn, socket);
1746 else if(methodType == FILL)
1747 ProcessFillResponse(headerIn,
Ipv4Address(uriParams[0].c_str()));
1748 else if(methodType == TRANSFORM_KEYS)
1749 ProcessSKeyCreateResponse(headerIn, socket);
1750 else if(methodType == ETSI_QKD_004_KMS_CLOSE)
1751 ProcessKMSCloseResponse(headerIn, socket);
1752 else if(methodType == RELAY_KEYS)
1753 ProcessRelayResponse(headerIn);
1774 nlohmann::json jOpenConnectRequest;
1776 jOpenConnectRequest = nlohmann::json::parse(payload);
1782 std::string srcSaeId;
1783 std::string dstSaeId;
1785 if(jOpenConnectRequest.contains(
"Destination"))
1786 dstSaeId = jOpenConnectRequest[
"Destination"];
1787 if(jOpenConnectRequest.contains(
"Source"))
1788 srcSaeId = jOpenConnectRequest[
"Source"];
1789 if(jOpenConnectRequest.contains(
"Key_stream_ID"))
1790 ksid = jOpenConnectRequest[
"Key_stream_ID"];
1791 ReadJsonQos(inQos, jOpenConnectRequest);
1792 NS_ASSERT(!srcSaeId.empty() || !dstSaeId.empty());
1806 bool callByMaster {ksid.empty()};
1808 ksid = CreateKeyStreamSession(srcSaeId, dstSaeId, inQos, ksid);
1810 nlohmann::json jOpenConnectResponse {{
"Key_stream_ID", ksid}};
1812 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::Ok, jOpenConnectResponse.dump(), {
1813 {
"Content-Type",
"application/json; charset=utf-8"},
1814 {
"Request URI", headerIn.GetUri() }
1816 std::string hMessage = httpMessage.ToString();
1818 (uint8_t*)(hMessage).c_str(),
1822 SendToSocketPair(socket, packet);
1825 NS_FATAL_ERROR(
this <<
"ETSI QKD 004 is supported only for point-to-point connections");
1829 NewAppRequest(ksid);
1832 auto it = m_associations004.find(ksid);
1833 if(it == m_associations004.end()){
1834 NS_LOG_ERROR(
this <<
"Key stream association identified with " << ksid <<
"does not exists!");
1838 }
else if((it->second).srcSaeId != srcSaeId){
1839 NS_LOG_ERROR(
this <<
"KSID is not registered for this application" <<(it->second).dstSaeId << srcSaeId);
1844 (it->second).peerRegistered =
true;
1845 RegisterRequest(ksid);
1846 HTTPMessage httpMessage;
1847 httpMessage.CreateResponse(HTTPMessage::HttpStatus::Ok,
"", {
1848 {
"Content-Type",
"application/json; charset=utf-8"},
1849 {
"Request URI", headerIn.GetUri() }
1851 std::string hMessage = httpMessage.ToString();
1852 Ptr<Packet> packet = Create<Packet>(
1853 (uint8_t*)(hMessage).c_str(),
1857 SendToSocketPair(socket, packet);
1867 NS_LOG_FUNCTION(
this <<
"Processing get_key request(ETSI 004)" << ksid );
1868 auto it = m_associations004.find(ksid);
1869 if(it == m_associations004.end()){
1870 NS_LOG_DEBUG(
this <<
"Key stream association identified with " << ksid <<
"does not exists!" );
1874 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::BadRequest,
"", {
1875 {
"Request URI", headerIn.
GetUri() }
1877 std::string hMessage = httpMessage.
ToString();
1879 (uint8_t*)(hMessage).c_str(),
1884 SendToSocketPair(socket, packet);
1889 NS_LOG_FUNCTION(
this <<
"EMIRS" << it->second.stre_buffer->GetStreamKeyCount() << it->second.peerRegistered);
1891 if( it->second.peerRegistered && it->second.stre_buffer->GetStreamKeyCount())
1893 Ptr<QKDKey> keyChunk = it->second.stre_buffer->GetStreamKey();
1894 if(GetNode()->GetId() > it->second.dstNodeId)
1895 CheckEtsi004Association(ksid);
1897 nlohmann::json jresponse {
1898 {
"index", std::stoi(keyChunk->GetId())},
1899 {
"Key_buffer", keyChunk->GetKeyString()}
1902 std::string msg = jresponse.dump();
1907 {
"Content-Type",
"application/json; charset=utf-8"},
1908 {
"Request URI", headerIn.
GetUri() }
1910 std::string hMessage = httpMessage.
ToString();
1912 (uint8_t*)(hMessage).c_str(),
1916 SendToSocketPair(socket, packet);
1918 m_keyServedTrace(it->second.srcSaeId, keyChunk->GetId(), keyChunk->GetSizeInBits());
1920 it->second.srcNodeId,
1921 it->second.dstNodeId,
1923 keyChunk->GetSizeInBits()
1928 NS_LOG_FUNCTION(
this <<
"No keys available in the association buffer. Responding on the request ...");
1930 auto itSchedule = m_scheduledChecks.find(ksid);
1931 if(itSchedule!=m_scheduledChecks.end())
1933 NS_LOG_FUNCTION(
this <<
"The CheckEtsi004Association for ksid ("<< ksid <<
") is already scheduled!");
1935 CheckEtsi004Association(ksid);
1940 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::BadRequest,
"", {
1941 {
"Request URI", headerIn.
GetUri() }
1943 std::string hMessage = httpMessage.
ToString();
1945 (uint8_t*)(hMessage).c_str(),
1950 SendToSocketPair(socket, packet);
1959 auto it = m_associations004.find(ksid);
1960 if(it == m_associations004.end()){
1961 NS_LOG_DEBUG(
this <<
"Key stream association identified with " << ksid <<
"does not exists!" );
1968 if(it->second.stre_buffer->GetStreamKeyCount()){
1970 query.
sync_index = it->second.stre_buffer->GetNextIndex();
1973 NS_LOG_FUNCTION(
this <<
"Releasing key stream association buffer. Synchronizing with peer KMS ..." );
1974 CheckSocketsKMS((it->second).dstKmsAddr );
1975 Ptr<Socket> sendSocket = GetSendSocketKMS((it->second).dstKmsAddr );
1978 nlohmann::json msgBody;
1983 std::string msg = msgBody.dump();
1985 std::string headerUri =
"http://" + GetAddressString((it->second).dstKmsAddr);
1986 headerUri +=
"/api/v1/associations/close_kms/" + ksid;
1991 std::string hMessage = httpMessage.
ToString();
1993 (uint8_t*)(hMessage).c_str(),
1998 HttpKMSAddQuery((it->second).dstKmsAddr, query);
2000 sendSocket->Send(packet);
2001 NS_LOG_FUNCTION(
this <<
"Synchronization information for releasing key stream association sent to peer KMS"
2002 << packet->GetUid() << packet->GetSize() );
2008QKDKeyManagerSystemApplication::CreateRelaySBuffer(
uint32_t srcNodeId,
uint32_t dstNodeId, std::string description)
2012 Ptr<SBuffer> sBuffer = GetController()->CreateRSBuffer(dstNodeId);
2013 sBuffer->SetType(SBuffer::Type::RELAY_SBUFFER);
2014 sBuffer->Initialize();
2015 sBuffer->SetDescription (description);
2016 sBuffer->SetIndex( m_qbuffersVector.size() );
2018 m_qbuffersVector.push_back(sBuffer);
2019 m_qbuffers.insert(std::make_pair(dstNodeId, sBuffer) );
2023 for(
uint32_t i = 0; i < GetNode()->GetNApplications(); ++i)
2026 applicationIndex = i;
2029 sBuffer->SetSrcKMSApplicationIndex(applicationIndex);
2033 std::string graphTitle =
"SBUFFER (RELAY): " + std::to_string(srcNodeId) +
" - " + std::to_string(dstNodeId);
2034 Ptr<Node> dstNode = NodeList::GetNode(dstNodeId);
2038 sBuffer->GetIndex(),
2039 sBuffer->GetSrcKMSApplicationIndex(),
2061 std::vector<std::string> uriParams {ReadUri(headerIn.
GetUri())};
2062 std::string reqId = uriParams[6];
2066 nlohmann::json jRelayPayload;
2068 jRelayPayload = nlohmann::json::parse(payload);
2073 uint32_t srcNodeId {0}, dstNodeId {0};
2074 if(jRelayPayload.contains(
"source_node_id"))
2075 srcNodeId = jRelayPayload[
"source_node_id"];
2076 if(jRelayPayload.contains(
"destination_node_id"))
2077 dstNodeId = jRelayPayload[
"destination_node_id"];
2079 NS_LOG_FUNCTION(
this << srcNodeId << GetNode()->GetId() << dstNodeId);
2081 bool terminateRelay {
false};
2082 std::vector<std::string> keyIds {}, keys {};
2083 if(!jRelayPayload.contains(
"repeater_node_id"))
2092 keyId = (it.value())[
"key_ID"];
2096 NS_LOG_FUNCTION(
this <<
"Relay key with ID" <<(it.value())[
"key_ID"] <<
"not found! Relay is terminated!");
2097 terminateRelay =
true;
2102 NS_LOG_FUNCTION(
this <<
"\nFirstNode -> Relay key -> ID: " << key->GetId()
2103 <<
"\nFirstNode -> Relay key -> key: " << key->GetKeyString());
2104 keyIds.push_back(key->GetId());
2105 keys.push_back(key->GetKeyString());
2108 if(GetNode()->GetId() > srcNodeId)
2109 SBufferClientCheck(srcNodeId);
2115 uint32_t previousNodeId = jRelayPayload[
"repeater_node_id"];
2116 std::vector<std::string> ekeys {}, ekeyIds {};
2117 Ptr<SBuffer> decBuffer = GetSBuffer(previousNodeId,
"dec");
2123 ekeys.push_back((it.value())[
"ekey"] );
2124 ekeyIds.push_back((it.value())[
"ekey_ID"] );
2125 keyIds.push_back((it.value())[
"key_ID"] );
2128 keyId = (it.value())[
"ekey_ID"];
2132 NS_LOG_FUNCTION(
this <<
"Decryption key with ID" <<(it.value())[
"ekey_ID"] <<
"is not found! Relay is terminated!");
2133 terminateRelay =
true;
2135 keys.push_back( decryptor->COTP(key->GetKeyString(),(it.value())[
"ekey"]) );
2138 if(GetNode()->GetId() > previousNodeId)
2139 SBufferClientCheck(previousNodeId);
2143 if(GetNode()->GetId() != dstNodeId && !terminateRelay)
2150 uint32_t availableKeysCount = encBuffer->GetDefaultKeyCount(keyIds.size());
2153 NS_LOG_FUNCTION(
this <<
"zzz:" << availableKeysCount << keyIds.size() );
2154 if(encBuffer->GetDefaultKeyCount(keyIds.size()) != keyIds.size())
2156 terminateRelay =
true;
2158 if(jRelayPayload.contains(
"repeater_node_id")){
2159 previousNodeId = jRelayPayload[
"repeater_node_id"];
2161 if(jRelayPayload.contains(
"source_node_id"))
2162 previousNodeId = jRelayPayload[
"source_node_id"];
2170 nlohmann::json jrelayResponse{ {
"node-id", GetNode()->GetId()} };
2171 std::string msg = jrelayResponse.dump();
2174 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::BadRequest, msg, {
2175 {
"Request URI", headerIn.
GetUri() }
2177 std::string hMessage = httpMessage.
ToString();
2179 (uint8_t*)(hMessage).c_str(),
2184 NS_LOG_FUNCTION(
this <<
"Sending response" << packet->GetUid() << packet->GetSize() );
2185 Ipv4Address peerAddress = GetPeerKmAddress(previousNodeId);
2187 Ptr<Socket> sendSocket = GetSendSocketKMS(peerAddress);
2188 sendSocket->Send(packet);
2197 nlohmann::json jRelay;
2199 uint32_t encDefaultKeySize = encBuffer->GetKeySize();
2200 for(
uint32_t i = 0; i < keyIds.size(); i++)
2203 Ptr<QKDKey> encKey = encBuffer->GetKey(encDefaultKeySize);
2205 NS_LOG_FUNCTION(
this <<
"\nMiddleNode -> Relay key -> eKeyId" << encKey->GetId()
2206 <<
"\nMiddleNode -> Relay key -> keyId" << keyIds[i]);
2207 std::string encryptedKey = encryptor->COTP(encKey->GetKeyString(), keys[i]);
2208 NS_LOG_FUNCTION(
this <<
"\nMiddleNode -> Relay key -> ekey" << encryptedKey);
2209 jRelay[
"keys"].push_back({ {
"key_ID", keyIds[i]}, {
"ekey_ID", encKey->GetId()}, {
"ekey", encryptedKey} });
2214 encKey->GetSizeInBits()
2220 jRelay[
"source_node_id"] = srcNodeId;
2221 jRelay[
"destination_node_id"] = dstNodeId;
2222 jRelay[
"repeater_node_id"] = GetNode()->GetId();
2227 std::string headerUri =
"http://" + GetAddressString(nextHopAddress);
2228 headerUri +=
"/api/v1/keys/relay/?req_id=/" + reqId;
2229 std::string msg = jRelay.dump();
2234 std::string hMessage = httpMessage.
ToString();
2236 (uint8_t*)(hMessage).c_str(),
2241 CheckSocketsKMS( nextHopAddress );
2242 Ptr<Socket> sendSocket = GetSendSocketKMS( nextHopAddress );
2248 if(jRelayPayload.contains(
"repeater_node_id"))
2249 query.
prev_hop_id = jRelayPayload[
"repeater_node_id"];
2253 HttpProxyRequestAdd(query);
2255 sendSocket->Send(packet);
2257 << packet->GetUid() << packet->GetSize());
2259 }
else if(!terminateRelay)
2267 NS_LOG_FUNCTION(
this <<
"The S-Buffer does not exists! This is new virtual connection!");
2268 uint32_t dstNodeId = GetNode()->GetId();
2269 sBuffer = CreateRelaySBuffer(dstNodeId, srcNodeId,
"(RELAY)");
2270 m_keys_enc.insert(std::make_pair(srcNodeId, sBuffer));
2271 m_keys_dec.insert(std::make_pair(srcNodeId, sBuffer));
2275 for(
uint32_t i = 0; i < keyIds.size(); i++){
2276 Ptr<QKDKey> key = CreateObject<QKDKey>(keyIds[i], keys[i]);
2278 sBuffer->StoreKey(key,
true);
2285 {
"Content-Type",
"application/json; charset=utf-8"},
2286 {
"Request URI", headerIn.
GetUri() }
2288 std::string hMessage = httpMessage.
ToString();
2290 (uint8_t*)(hMessage).c_str(),
2295 uint32_t previousNodeId = jRelayPayload[
"repeater_node_id"];
2296 Ipv4Address peerAddress = GetPeerKmAddress(previousNodeId);
2299 <<
"Sending response"
2302 << packet->GetSize()
2303 <<
"previousNodeId:"
2311 Ptr<Socket> sendSocket = GetSendSocketKMS(peerAddress);
2313 uint32_t outcome = sendSocket->Send(packet);
2314 NS_LOG_INFO(
this <<
"outcome of sending packet:" << outcome);
2321QKDKeyManagerSystemApplication::ProcessRelayResponse(
HTTPMessage headerIn)
2324 std::vector<std::string> uriParams = ReadUri(headerIn.
GetRequestUri());
2326 std::string reqId = uriParams[6];
2330 HttpQuery sQuery = GetProxyQuery(reqId);
2333 if(prevHop != GetNode()->GetId()){
2337 {
"Content-Type",
"application/json; charset=utf-8"},
2338 {
"Request URI", sQuery.request_uri }
2340 std::string hMessage = httpMessage.ToString();
2342 (uint8_t*)(hMessage).c_str(),
2349 Ipv4Address peerAddress = GetPeerKmAddress(prevHop);
2351 CheckSocketsKMS(peerAddress);
2352 Ptr<Socket> sendSocket = GetSendSocketKMS(peerAddress);
2355 NS_LOG_FUNCTION(
this <<
"Forwarding response" << packet->GetUid() << packet->GetSize() );
2356 sendSocket->Send(packet);
2361 NS_LOG_FUNCTION(
this <<
"Response have reached the source!" << headerIn.GetStatus());
2362 Ptr<SBuffer> relayBuffer = GetSBuffer(sQuery.peerNodeId,
"enc");
2364 std::vector<std::string> keyIds = sQuery.keyIds;
2365 bool fail {headerIn.GetStatus() != HTTPMessage::HttpStatus::Ok};
2366 for(
const auto& keyId : keyIds){
2367 if(headerIn.GetStatus() == HTTPMessage::HttpStatus::Ok)
2368 relayBuffer->MarkKey(keyId, QKDKey::READY);
2382 relayBuffer->MarkKey(keyId, QKDKey::OBSOLETE);
2385 relayBuffer->SetRelayState(
false);
2386 NS_LOG_FUNCTION(
this <<
"\nAmount of key material in RELAY s-buffer (READY): " << relayBuffer->GetSBitCount());
2394 RemoveProxyQuery(reqId);
2398QKDKeyManagerSystemApplication::NewAppRequest(std::string ksid)
2401 auto it = m_associations004.find(ksid);
2402 if(it == m_associations004.end()){
2403 NS_LOG_DEBUG(
this <<
"Key stream association identified with " << ksid <<
"does not exists!" );
2407 CheckSocketsKMS((it->second).dstKmsAddr );
2408 Ptr<Socket> sendSocket = GetSendSocketKMS((it->second).dstKmsAddr );
2411 nlohmann::json msgBody = {
2412 {
"Source",(it->second).srcSaeId},
2413 {
"Destination",(it->second).dstSaeId},
2415 {
"Key_chunk_size",(it->second).qos.chunkSize}
2417 {
"Key_stream_ID", ksid}
2419 std::string msg = msgBody.dump();
2421 std::ostringstream peerkmsAddressTemp;
2422 (it->second).dstKmsAddr.Print(peerkmsAddressTemp);
2423 std::string headerUri =
"http://" + peerkmsAddressTemp.str();
2424 headerUri +=
"/api/v1/associations/new_app";
2429 std::string hMessage = httpMessage.
ToString();
2431 (uint8_t*)(hMessage).c_str(),
2441 HttpKMSAddQuery((it->second).dstKmsAddr, query);
2443 sendSocket->Send(packet);
2444 NS_LOG_FUNCTION(
this <<
"NEW_APP: KMS informs peer KMS on new association established!" );
2452 nlohmann::json jNewAppRequest;
2454 jNewAppRequest = nlohmann::json::parse(payload);
2460 std::string srcSaeId, dstSaeId;
2463 if(jNewAppRequest.contains(
"Destination"))
2464 dstSaeId = jNewAppRequest[
"Destination"];
2465 if(jNewAppRequest.contains(
"Source"))
2466 srcSaeId = jNewAppRequest[
"Source"];
2467 if(jNewAppRequest.contains(
"Key_stream_ID"))
2468 ksid = jNewAppRequest[
"Key_stream_ID"];
2469 ReadJsonQos(inQoS, jNewAppRequest);
2470 NS_ASSERT(!srcSaeId.empty() || !dstSaeId.empty() || !ksid.empty());
2472 bool qosAgreed {
true};
2474 CreateKeyStreamSession(dstSaeId, srcSaeId, inQoS, ksid);
2482 {
"Content-Type",
"application/json; charset=utf-8"},
2483 {
"Request URI", headerIn.
GetUri() }
2485 std::string hMessage = httpMessage.
ToString();
2487 (uint8_t*)(hMessage).c_str(),
2492 NS_LOG_FUNCTION(
this <<
"NEW_APP request accepted. Association created." );
2494 auto it = m_associations004.find(ksid);
2495 if(it == m_associations004.end())
2499 CheckSocketsKMS( dstKms );
2500 Ptr<Socket> sendSocket = GetSendSocketKMS( dstKms );
2502 sendSocket->Send(packet);
2505 NS_LOG_ERROR(
this <<
"QoS requirements can not be satisfied");
2515 std::vector<std::string> uriParams = ReadUri(headerIn.
GetRequestUri());
2518 auto it = m_httpRequestsQueryKMS.find(dstKms);
2519 if(it == m_httpRequestsQueryKMS.end() ||(it->second).empty())
2520 NS_FATAL_ERROR(
this <<
"Response cannot be mapped! HttpQuery empty!" );
2522 std::string dstSaeId = it->second[0].destination_sae;
2524 if(GetController()->GetRoute(dstSaeId).GetHop() == 1)
2525 HttpKMSCompleteQuery(dstKms);
2529 nlohmann::json jOpenConnectResponse;
2530 jOpenConnectResponse[
"Key_stream_ID"] = it->second[0].ksid;
2531 std::string msg = jOpenConnectResponse.dump();
2536 {
"Content-Type",
"application/json; charset=utf-8"},
2537 {
"Request URI", headerIn.
GetUri() }
2539 std::string hMessage = httpMessage.
ToString();
2541 (uint8_t*)(hMessage).c_str(),
2546 Ptr<Socket> responseSocket = GetSocketFromHttp004AppQuery(it->second[0].source_sae);
2547 Http004AppQueryComplete(it->second[0].source_sae);
2548 HttpKMSCompleteQuery(dstKms);
2549 CheckSocketsKMS( dstKms );
2550 Ptr<Socket> sendSocket = GetSendSocketKMS( dstKms );
2552 sendSocket->Send(packet);
2559 std::string ksid = it->second[0].ksid;
2560 if(GetController()->GetRoute(dstSaeId).GetHop() == 1)
2561 HttpKMSCompleteQuery(dstKms);
2564 HttpKMSCompleteQuery(dstKms);
2566 auto it = m_associations004.find(ksid);
2567 if(it != m_associations004.end()){
2568 m_associations004.erase(it);
2577QKDKeyManagerSystemApplication::RegisterRequest(std::string ksid)
2580 auto it = m_associations004.find(ksid);
2581 if(it == m_associations004.end()){
2582 NS_LOG_DEBUG(
this <<
"Key stream association identified with " << ksid <<
"does not exists!" );
2587 CheckSocketsKMS( dstKms );
2588 Ptr<Socket> sendSocket = GetSendSocketKMS( dstKms );
2591 std::string headerUri =
"http://" + GetAddressString(dstKms);
2592 headerUri +=
"/api/v1/associations/register/" + ksid;
2597 std::string hMessage = httpMessage.
ToString();
2599 (uint8_t*)(hMessage).c_str(),
2607 HttpKMSAddQuery(dstKms, query);
2609 sendSocket->Send(packet);
2617 auto it = m_associations004.find(ksid);
2618 if(it != m_associations004.end() && ! ((it->second).peerRegistered))
2620 else if(it != m_associations004.end() && (it->second).peerRegistered )
2621 NS_LOG_FUNCTION(
this <<
"Key stream session has already been registered!");
2623 NS_LOG_FUNCTION(
this <<
"Key stream association identified with " << ksid <<
"does not exists!");
2627 (it->second).peerRegistered =
true;
2632 {
"Content-Type",
"application/json; charset=utf-8"},
2633 {
"Request URI", headerIn.
GetUri() }
2635 std::string hMessage = httpMessage.
ToString();
2637 (uint8_t*)(hMessage).c_str(),
2642 CheckSocketsKMS( it->second.dstKmsAddr );
2643 Ptr<Socket> sendSocket = GetSendSocketKMS( it->second.dstKmsAddr );
2645 sendSocket->Send(packet);
2648 if(it->second.srcNodeId > it->second.dstNodeId){
2650 CheckEtsi004Association(ksid);
2658 std::vector<std::string> uriParams = ReadUri(headerIn.
GetRequestUri());
2661 if(uriParams[4] !=
"register"){
2662 NS_LOG_ERROR(
this <<
"Not a register response! Invalid HTTP mapping!");
2664 }
else if(!uriParams[5].empty())
2665 ksid = uriParams[5];
2667 auto it1 = m_associations004.find(ksid);
2668 if(it1 == m_associations004.end()){
2669 NS_LOG_ERROR(
this <<
"Association with given KSID" << ksid <<
"cannot be found!");
2674 auto it = m_httpRequestsQueryKMS.find(dstKms);
2675 if(it == m_httpRequestsQueryKMS.end() ||(it->second).empty())
2676 NS_FATAL_ERROR(
this <<
"Response cannot be mapped! HttpQuery empty!" );
2678 if(headerIn.
GetStatus() == HTTPMessage::HttpStatus::Ok){
2680 if(it1->second.srcNodeId > it1->second.dstNodeId){
2682 CheckEtsi004Association(ksid);
2685 NS_LOG_FUNCTION(
this <<
"/register error! Releasing established association" << ksid );
2686 if(it1 != m_associations004.end()){
2687 m_associations004.erase(it1);
2692 HttpKMSCompleteQuery(dstKms);
2702 nlohmann::json jFillPayload;
2704 jFillPayload = nlohmann::json::parse(payload);
2711 std::string sBufferType, ksid;
2712 if(jFillPayload.contains(
"source_node_id"))
2713 peerNodeId = jFillPayload[
"source_node_id"];
2714 if(jFillPayload.contains(
"s_buffer_type"))
2715 sBufferType = jFillPayload[
"s_buffer_type"];
2717 if(sBufferType ==
"stream"){
2718 if(jFillPayload.contains(
"ksid"))
2719 ksid = jFillPayload[
"ksid"];
2721 NS_FATAL_ERROR(
this <<
"Mandatory parametar -- ksid -- not received");
2729 if(sBufferType !=
"stream")
2731 sBuffer = GetSBuffer(peerNodeId, sBufferType);
2735 uint32_t srcNodeId = GetNode()->GetId();
2737 sBuffer = CreateRelaySBuffer(srcNodeId, dstNodeId,
"(RELAY)");
2738 m_keys_enc.insert(std::make_pair(peerNodeId, sBuffer));
2739 m_keys_dec.insert(std::make_pair(peerNodeId, sBuffer));
2741 }
else if(sBufferType ==
"stream"){
2742 auto it = m_associations004.find(ksid);
2743 if(it == m_associations004.end()){
2747 sBuffer = it->second.stre_buffer;
2752 bool storeSuccesfull =
true;
2753 nlohmann::json resultKeyIds;
2755 Ptr<QKDKey> key = qBuffer->GetKey((it.value())[
"key_ID"] );
2759 NS_LOG_FUNCTION(
this <<
"Let's try to save key " << key->GetId() <<
" in sBuffer: " << sBuffer->GetDescription() );
2760 storeSuccesfull =
true;
2761 if(sBufferType !=
"stream")
2763 storeSuccesfull = sBuffer->StoreKey(key,
true);
2764 if(!storeSuccesfull)
2766 NS_LOG_FUNCTION(
this <<
"Unable to store key " << key->GetId() <<
" in SBUFFER! Return it back to QBuffer!");
2767 qBuffer->StoreKey(key,
true);
2769 sBuffer->MarkKey( key->GetId(), QKDKey::READY );
2772 sBuffer->InsertKeyToStreamSession(key);
2775 resultKeyIds[
"keys_accepted"].push_back( { {
"key_ID", key->GetId()} } );
2777 resultKeyIds[
"keys_rejected"].push_back( { {
"key_ID", key->GetId()} } );
2781 NS_LOG_FUNCTION(
this <<
"FILL complete, check the state of S-Buffer" << sBuffer->GetSKeyCount());
2782 NS_LOG_FUNCTION(
this <<
"FILL complete, but how many in default size: " << sBuffer->GetDefaultKeyCount() << sBuffer->GetKeySize());
2784 UpdateLinkState(peerNodeId);
2790 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::Ok, resultKeyIds.dump(), {
2791 {
"Content-Type",
"application/json; charset=utf-8"},
2792 {
"Request URI", headerIn.GetUri() }
2795 httpMessage.CreateResponse(HTTPMessage::HttpStatus::NotAcceptable, resultKeyIds.dump(), {
2796 {
"Content-Type",
"application/json; charset=utf-8"},
2797 {
"Request URI", headerIn.GetUri() }
2800 std::string hMessage = httpMessage.ToString();
2801 Ptr<Packet> packet = Create<Packet>(
2802 (uint8_t*)(hMessage).c_str(),
2807 NS_LOG_FUNCTION(
this <<
"Sending response" << packet->GetUid() << packet->GetSize() << hMessage );
2809 Ipv4Address peerKMAddress = GetPeerKmAddress(peerNodeId);
2810 CheckSocketsKMS(peerKMAddress);
2811 Ptr<Socket> sendSocket = GetSendSocketKMS(peerKMAddress);
2813 sendSocket->Send(packet);
2823 auto it = m_httpRequestsQueryKMS.find(dstKms);
2825 if(it == m_httpRequestsQueryKMS.end() ||(it->second).empty())
2826 NS_FATAL_ERROR(
this <<
"Response cannot be mapped! HttpQuery empty!" );
2827 if(it->second[0].method_type != FILL){
2829 HttpKMSCompleteQuery(dstKms);
2832 NS_LOG_FUNCTION(
this << it->second[0].method_type << it->second[0].sBuffer);
2835 if(headerIn.
GetStatus() == HTTPMessage::HttpStatus::Ok)
2839 NS_LOG_ERROR(
this <<
" *** Unexpected error received! *** ");
2843 nlohmann::json resultKeyIds;
2845 resultKeyIds = nlohmann::json::parse(payload);
2850 uint32_t peerNodeId =(it->second)[0].peerNodeId;
2852 std::string sBufferType =(it->second)[0].sBuffer;
2854 if(sBufferType ==
"enc" || sBufferType ==
"dec"){
2855 sBuffer = GetSBuffer(peerNodeId, sBufferType);
2858 auto it {m_associations004.find(sBufferType)};
2859 if(it == m_associations004.end())
2862 sBuffer = it->second.stre_buffer;
2864 std::vector<std::string> keyIds =(it->second)[0].keyIds;
2866 NS_LOG_FUNCTION(
this <<
"First take all ACCEPTED keys from response. Mark them ready. Remove them from local keyIds!");
2867 for(
nlohmann::json::iterator it = resultKeyIds[
"keys_accepted"].begin(); it != resultKeyIds[
"keys_accepted"].end(); ++it)
2869 std::string keyId {(it.value())[
"key_ID"]};
2870 auto a { std::find( keyIds.begin(), keyIds.end(), keyId ) };
2871 if(a != keyIds.end())
2876 if(sBufferType ==
"enc" || sBufferType ==
"dec"){
2877 sBuffer->MarkKey( keyId, QKDKey::READY );
2881 Ptr<QKDKey> key { sBuffer->GetKey(keyId,
false) };
2884 key->SwitchToState( QKDKey::READY );
2885 sBuffer->InsertKeyToStreamSession(key);
2893 NS_LOG_FUNCTION(
this <<
"Now check REJECTED keys from response. Return them to QBuffer!");
2894 for(
nlohmann::json::iterator it = resultKeyIds[
"keys_rejected"].begin(); it != resultKeyIds[
"keys_rejected"].end(); ++it)
2896 std::string keyId {(it.value())[
"key_ID"]};
2897 auto a { std::find( keyIds.begin(), keyIds.end(), keyId ) };
2898 if(a != keyIds.end())
2905 key->SwitchToState( QKDKey::READY );
2906 qBuffer->StoreKey(key,
false);
2909 NS_LOG_FUNCTION(
this <<
"FILL complete, check the state of S-Buffer: " << sBuffer->GetSKeyCount());
2911 UpdateLinkState(peerNodeId);
2914 for(
const auto& el: keyIds)
2915 sBuffer->MarkKey(el, QKDKey::OBSOLETE);
2919 HttpKMSCompleteQuery(dstKms);
2927 nlohmann::json jPayload;
2929 jPayload = nlohmann::json::parse(payload);
2934 uint32_t keySize {0}, keyNumber {0};
2935 std::vector<std::string> candidateSetIds {}, supplyKeyIds {};
2936 std::string surplusKeyId, targetSaeId;
2939 if(jPayload.contains(
"source_node_id"))
2940 peerNodeId = jPayload[
"source_node_id"];
2941 if(jPayload.contains(
"target_SAE_ID"))
2942 targetSaeId = jPayload[
"target_SAE_ID"];
2943 if(jPayload.contains(
"key_size"))
2944 keySize = jPayload[
"key_size"];
2945 if(jPayload.contains(
"key_number"))
2946 keyNumber = jPayload[
"key_number"];
2947 if(jPayload.contains(
"supply_key_ID")){
2950 it != jPayload[
"supply_key_ID"].end();
2953 supplyKeyIds.push_back((it.value())[
"key_ID"]);
2956 if(jPayload.contains(
"candidate_set_ID")){
2959 it != jPayload[
"candidate_set_ID"].end();
2962 candidateSetIds.push_back((it.value())[
"key_ID"]);
2965 NS_ASSERT(!supplyKeyIds.empty() || !candidateSetIds.empty() || !targetSaeId.empty());
2969 <<
"\nTarget SAE ID:" << targetSaeId <<
"\nKey size:\t" << keySize
2970 <<
"\nKey number:\t" << keyNumber <<
"\nSupply key IDs:\t"<< supplyKeyIds
2971 <<
"\nCandidateSetIDs:" << candidateSetIds);
2978 uint32_t targetSize = keySize*keyNumber;
2979 std::string mergedKey {};
2981 for(
size_t i = 0; i < candidateSetIds.size(); i++)
2983 if(i != candidateSetIds.size()-1)
2985 tempKey = sBuffer->GetKey(candidateSetIds[i],
true);
2986 mergedKey += tempKey->GetKeyString();
2989 uint32_t size = targetSize - mergedKey.size()*8;
2990 NS_LOG_FUNCTION(
this <<
"em95" << targetSize << mergedKey.size()*8 << size <<
"\n" << mergedKey);
2991 mergedKey +=(sBuffer->GetHalfKey(candidateSetIds[i], size))->GetKeyString();
2995 for(
size_t i = 0; i < supplyKeyIds.size(); i++)
2997 std::string keyString = mergedKey.substr(0, keySize/8);
2998 mergedKey.erase(0, keySize/8);
2999 Ptr<QKDKey> skey = CreateObject<QKDKey>(supplyKeyIds[i], keyString);
3000 sBuffer->StoreSupplyKey(skey);
3006 {
"Content-Type",
"application/json; charset=utf-8"},
3007 {
"Request URI", headerIn.
GetUri() }
3009 std::string hMessage = httpMessage.
ToString();
3011 (uint8_t*)(hMessage).c_str(),
3018 CheckSocketsKMS( dstKms );
3019 Ptr<Socket> sendSocket = GetSendSocketKMS( dstKms );
3021 sendSocket->Send(packet);
3023 NS_LOG_FUNCTION(
this <<
"Sending packed id " << packet->GetUid() <<
" of size " << packet->GetSize());
3028 NS_FATAL_ERROR(
this <<
"No s-buffer found for this connection!" );
3038 std::vector<std::string> uriParams {ReadUri(headerIn.
GetRequestUri())};
3041 auto it = m_httpRequestsQueryKMS.find(peerAddress);
3042 if(it == m_httpRequestsQueryKMS.end()){
3047 if(headerIn.
GetStatus() == HTTPMessage::HttpStatus::Ok)
3052 if(it->second[0].surplus_key_ID.empty())
3055 HttpKMSCompleteQuery(peerAddress);
3059 Ptr<SBuffer> sBuffer = GetSBuffer(it->second[0].peerNodeId,
"enc");
3061 std::string surplusKeyId {(it->second[0]).surplus_key_ID};
3062 sBuffer->MarkKey(surplusKeyId, QKDKey::READY);
3069 HttpKMSCompleteQuery(peerAddress);
3077 nlohmann::json jcloseRequest;
3079 jcloseRequest = nlohmann::json::parse(payload);
3084 std::string surplusKeyId {};
3086 if(jcloseRequest.contains(
"surplus_key_ID"))
3087 surplusKeyId = jcloseRequest[
"surplus_key_ID"];
3088 if(jcloseRequest.contains(
"sync_index"))
3089 syncIndex = jcloseRequest[
"sync_index"];
3091 auto it = m_associations004.find(ksid);
3092 if(it == m_associations004.end()){
3097 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::NotAcceptable,
"", {
3098 {
"Content-Type",
"application/json; charset=utf-8"},
3099 {
"Request URI", headerIn.
GetUri() }
3101 std::string hMessage = httpMessage.
ToString();
3103 (uint8_t*)(hMessage).c_str(),
3108 NS_LOG_FUNCTION(
this <<
"packet sent " << packet->GetUid() << packet->GetSize());
3109 CheckSocketsKMS( it->second.dstKmsAddr );
3110 Ptr<Socket> sendSocket = GetSendSocketKMS( it->second.dstKmsAddr );
3112 sendSocket->Send(packet);
3115 it->second.peerRegistered =
false;
3118 if(it->second.stre_buffer->GetStreamKeyCount())
3119 localSyncIndex = it->second.stre_buffer->GetNextIndex();
3123 if(!surplusKeyId.empty() && syncIndex < localSyncIndex)
3124 syncIndex = localSyncIndex;
3127 if(empty && !surplusKeyId.empty())
3130 if(GetNode()->GetId() < it->second.dstNodeId)
3131 ReleaseAssociation(ksid, surplusKeyId, syncIndex);
3133 ScheduleReleaseAssociation(
Time(
"20ms"),
"ReleaseAssociation", ksid, surplusKeyId, syncIndex);
3135 nlohmann::json jresponse;
3137 if(!surplusKeyId.empty())
3138 jresponse[
"sync_index"] = syncIndex;
3140 jresponse[
"flag_empty"] =
true;
3144 httpMessage.
CreateResponse(HTTPMessage::HttpStatus::Ok, jresponse.dump(), {
3145 {
"Content-Type",
"application/json; charset=utf-8"},
3146 {
"Request URI", headerIn.GetUri()}
3148 std::string hMessage = httpMessage.ToString();
3150 (uint8_t*)(hMessage).c_str(),
3155 NS_LOG_FUNCTION(
this <<
"packet sent" << packet->GetUid() << packet->GetSize());
3156 CheckSocketsKMS( it->second.dstKmsAddr );
3157 Ptr<Socket> sendSocket = GetSendSocketKMS( it->second.dstKmsAddr );
3159 sendSocket->Send(packet);
3165QKDKeyManagerSystemApplication::ReleaseAssociation(std::string ksid, std::string surplusKeyId,
uint32_t syncIndex)
3169 std::string temp = ksid +
"-" + surplusKeyId +
"-" + std::to_string(syncIndex);
3170 auto itSchedule = m_scheduledChecks.find(temp);
3171 if(itSchedule!=m_scheduledChecks.end())
3172 m_scheduledChecks.erase(itSchedule);
3174 auto it = m_associations004.find(ksid);
3175 if(it == m_associations004.end()){
3180 if(surplusKeyId.empty())
3182 m_associations004.erase(it);
3184 std::string preservedKeyString;
3187 while(it->second.stre_buffer->GetNextIndex() && it->second.stre_buffer->GetNextIndex() < syncIndex){
3188 NS_LOG_FUNCTION(
this <<
"emir1" << it->second.stre_buffer->GetNextIndex());
3189 Ptr<QKDKey> key = it->second.stre_buffer->GetStreamKey();
3190 presentKeyMaterial += key->GetSizeInBits();
3191 m_keyServedTrace(it->second.srcSaeId, key->GetId(), key->GetSizeInBits());
3193 it->second.srcNodeId,
3194 it->second.dstNodeId,
3196 key->GetSizeInBits()
3202 Ptr<QKDKey> key = it->second.stre_buffer->GetStreamKey();
3204 preservedKeyString += key->GetKeyString();
3209 if(!preservedKeyString.empty()){
3210 Ptr<QBuffer> qBuffer = GetQBuffer(GetController()->GetRoute(it->second.dstSaeId).GetDestinationKmNodeId());
3212 NS_LOG_FUNCTION(
this <<
"preserved key material" << preservedKeyString.size());
3214 std::string hashInput {surplusKeyId + ksid};
3217 uint32_t blockSize {qBuffer->GetKeySize()/8}, blockNum {0};
3218 while(!preservedKeyString.empty()){
3219 std::string keyValueTemp {preservedKeyString};
3220 if(preservedKeyString.size() >= blockSize)
3221 keyValueTemp = preservedKeyString.substr(0, blockSize);
3222 std::string completeHashInput = hashInput + std::to_string(blockNum++);
3223 std::string blockKeyId {encryptor->SHA1(completeHashInput)};
3225 Ptr<QKDKey> tempKey = Create<QKDKey>(blockKeyId, keyValueTemp);
3226 qBuffer->StoreKey(tempKey);
3227 preservedKeyString.erase(0, blockSize);
3234 m_associations004.erase(it);
3245 nlohmann::json jcloseResponse;
3247 jcloseResponse = nlohmann::json::parse(payload);
3253 auto it = m_httpRequestsQueryKMS.find(dstKms);
3254 if(it == m_httpRequestsQueryKMS.end()){
3255 NS_LOG_ERROR(
this <<
"unable to map response; query empty");
3259 std::string ksid { ReadUri(headerIn.
GetRequestUri())[5].c_str() };
3260 auto a = m_associations004.find(ksid);
3261 if(a == m_associations004.end()){
3266 if(headerIn.
GetStatus() == HTTPMessage::NotAcceptable){
3270 Ptr<QKDKey> key {a->second.stre_buffer->GetStreamKey()};
3272 presentKeyMaterial += key->GetSizeInBits();
3273 m_keyServedTrace(a->second.srcSaeId, key->GetId(), key->GetSizeInBits());
3274 m_keyConsumedLink(a->second.srcNodeId, a->second.dstNodeId, key->GetSizeInBits());
3279 m_associations004.erase(a);
3281 }
else if(headerIn.
GetStatus() == HTTPMessage::Ok){
3282 uint32_t peerSyncIndex {0}, localSyncIndex {it->second[0].sync_index};
3283 if(jcloseResponse.contains(
"sync_index")){
3284 peerSyncIndex = jcloseResponse[
"sync_index"];
3285 if(peerSyncIndex > localSyncIndex)
3286 localSyncIndex = peerSyncIndex;
3288 ReleaseAssociation(it->second[0].ksid, it->second[0].surplus_key_ID, localSyncIndex);
3295 Ptr<QKDKey> key {a->second.stre_buffer->GetStreamKey()};
3298 presentKeyMaterial += key->GetSizeInBits();
3299 m_keyServedTrace(a->second.srcSaeId, key->GetId(), key->GetSizeInBits());
3300 m_keyConsumedLink(a->second.srcNodeId, a->second.dstNodeId, key->GetSizeInBits());
3305 m_associations004.erase(a);
3312 HttpKMSCompleteQuery(dstKms);
3328 auto it = m_httpRequestsQueryKMS.find(dstKms);
3329 if(it != m_httpRequestsQueryKMS.end())
3330 it->second.push_back(request);
3332 m_httpRequestsQueryKMS.insert(std::make_pair(dstKms, std::vector<HttpQuery> {request}));
3336QKDKeyManagerSystemApplication::HttpKMSCompleteQuery(
Ipv4Address dstKms)
3339 auto it = m_httpRequestsQueryKMS.find(dstKms);
3340 if(it != m_httpRequestsQueryKMS.end())
3342 if(!it->second.empty())
3344 it->second.erase(it->second.begin());
3349 NS_FATAL_ERROR(
this <<
"HTTP query to destination KMS does not exist!" );
3358 auto it = m_httpRequestsQueryKMS.find(dstKms);
3359 if(it!=m_httpRequestsQueryKMS.end())
3360 methodType = it->second.begin()->method_type;
3362 NS_FATAL_ERROR(
this <<
"HTTP response cannot be mapped: HTTP query is empty!" );
3367QKDKeyManagerSystemApplication::Http004AppQuery( std::string saeId,
Ptr<Socket> socket )
3370 m_http004App.insert(std::make_pair(saeId, socket));
3374QKDKeyManagerSystemApplication::Http004AppQueryComplete(std::string saeId)
3378 std::pair<std::multimap<std::string, Ptr<Socket> >::iterator, std::multimap<std::string, Ptr<Socket> >::iterator > ret;
3379 ret = m_http004App.equal_range(saeId);
3381 if(ret.first == ret.second)
3384 std::multimap<std::string, Ptr<Socket> >::iterator it = ret.first;
3385 m_http004App.erase(it);
3390QKDKeyManagerSystemApplication::GetSocketFromHttp004AppQuery(std::string saeId)
3394 std::pair<std::multimap<std::string, Ptr<Socket> >::iterator, std::multimap<std::string, Ptr<Socket> >::iterator > ret;
3395 ret = m_http004App.equal_range(saeId);
3396 if(ret.first == ret.second)
3398 auto it = ret.first;
3407QKDKeyManagerSystemApplication::HttpProxyRequestAdd(
HttpQuery query)
3410 m_httpProxyRequests.insert( std::make_pair(query.
req_id, query) );
3414QKDKeyManagerSystemApplication::GetProxyQuery(std::string reqId)
3418 auto it = m_httpProxyRequests.find(reqId);
3419 if(it == m_httpProxyRequests.end()){
3420 NS_FATAL_ERROR(
this <<
"Unknown proxy request ID:" << reqId <<
"\tMapping of response failed!");
3429QKDKeyManagerSystemApplication::RemoveProxyQuery(std::string reqId)
3432 auto it = m_httpProxyRequests.find(reqId);
3433 if(it == m_httpProxyRequests.end()){
3434 NS_FATAL_ERROR(
this <<
"Unknown proxy request ID:" << reqId <<
"\tRemove failed!");
3438 m_httpProxyRequests.erase(it);
3444QKDKeyManagerSystemApplication::GetDestinationKmsAddress(
Ptr<Socket> socket)
3449 std::map<Ipv4Address, std::pair<Ptr<Socket>,
Ptr<Socket> > >::iterator it;
3450 for(it = m_socketPairsKMS.begin(); it != m_socketPairsKMS.end(); ++it)
3452 if((it->second).first == socket) {
3453 dstKMSAddress = it->first;
3458 return dstKMSAddress;
3462QKDKeyManagerSystemApplication::GetMaxKeyPerRequest(){
3463 return m_maxKeyPerRequest;
3467QKDKeyManagerSystemApplication::FetchRequestType(std::string s)
3476 return ETSI_QKD_014_GET_STATUS;
3478 }
else if(s ==
"enc_keys") {
3480 return ETSI_QKD_014_GET_KEY;
3482 }
else if(s ==
"dec_keys"){
3484 return ETSI_QKD_014_GET_KEY_WITH_KEY_IDS;
3486 }
else if(s ==
"open_connect"){
3488 return ETSI_QKD_004_OPEN_CONNECT;
3490 }
else if(s ==
"get_key") {
3492 return ETSI_QKD_004_GET_KEY;
3494 }
else if(s ==
"close") {
3496 return ETSI_QKD_004_CLOSE;
3498 }
else if(s ==
"new_app") {
3502 }
else if(s ==
"register") {
3506 }
else if(s ==
"fill") {
3510 }
else if(s ==
"store_key") {
3514 }
else if(s ==
"skey_create") {
3516 return TRANSFORM_KEYS;
3518 }
else if(s ==
"close_kms") {
3520 return ETSI_QKD_004_KMS_CLOSE;
3522 }
else if(s ==
"relay") {
3536QKDKeyManagerSystemApplication::EstablishKMLinkSockets(
Ipv4Address remoteKmAddress)
3538 NS_LOG_FUNCTION(
this <<
"Create sink socket to listen requests exchanged between KMSs!");
3541 Ptr<Socket> sinkSocket = Socket::CreateSocket(GetNode(), m_tid);
3542 sinkSocket->Bind(sinkAddress);
3543 sinkSocket->Listen();
3545 sinkSocket->SetRecvCallback(
MakeCallback(&QKDKeyManagerSystemApplication::HandleReadKMSs,
this));
3546 sinkSocket->SetAcceptCallback(
3548 MakeCallback(&QKDKeyManagerSystemApplication::HandleAcceptKMSs,
this)
3550 sinkSocket->SetCloseCallbacks(
3551 MakeCallback(&QKDKeyManagerSystemApplication::HandlePeerCloseKMSs,
this),
3552 MakeCallback(&QKDKeyManagerSystemApplication::HandlePeerErrorKMSs,
this)
3557 m_socketPairsKMS.insert(
3560 std::make_pair(sinkSocket, sendSocket)
3568QKDKeyManagerSystemApplication::Check014GetKeyRequest(
3574 NS_LOG_FUNCTION(
this << number << size << GetMaxKeyPerRequest() << m_maxKeySize << m_minKeySize << size % 8);
3582 nlohmann::json jError;
3584 number > GetMaxKeyPerRequest() ||
3586 size > m_maxKeySize ||
3587 size < m_minKeySize ||
3590 jError[
"message"] = std::string {
"requested parameters do not adhere to KM rules"};
3591 if(number > GetMaxKeyPerRequest()){
3592 std::string msgDetail =
"requested number of keys(" + std::to_string(number) +
") is higher then a maximum number of keys(" + std::to_string(GetMaxKeyPerRequest()) +
") per request allowed by KMS";
3593 jError[
"details"].push_back({{
"number_unsupported", msgDetail}});
3595 }
else if(number <= 0){
3596 std::string msgDetail =
"requested number of keys can not be lower or equal to zero";
3597 jError[
"details"].push_back({{
"number_unsupported", msgDetail}});
3600 if(size > m_maxKeySize){
3601 std::string msgDetail =
"requested size of keys(" + std::to_string(size) +
") is higher then a maximum size of key(" + std::to_string(m_maxKeySize) +
") that KMS can deliver";
3602 jError[
"details"].push_back({{
"size_unsupported", msgDetail}});
3604 }
else if(size < m_minKeySize){
3605 std::string msgDetail =
"requested size of keys(" + std::to_string(size) +
") is lower then a minimum size of key(" + std::to_string(m_minKeySize) +
") that KMS can deliver";
3606 jError[
"details"].push_back({{
"size_unsupported", msgDetail}});
3609 std::string msgDetail =
"size shall be a multiple of 8";
3610 jError[
"details"].push_back({{
"size_unsupported", msgDetail}});
3615 uint32_t availableKeyBits = buffer->GetSBitCount();
3616 NS_LOG_FUNCTION(
this <<
"\nTarget key size: " << size <<
"\nTarget number: " << number
3617 <<
"\nRequired amount of key material: " << size*number
3618 <<
"\nAmount of key material in s-buffer(READY): " << availableKeyBits);
3619 if(size*number > availableKeyBits)
3620 jError = {{
"message",
"insufficient amount of key material"}};
3628QKDKeyManagerSystemApplication::CreateKeyContainer(std::vector<
Ptr<QKDKey>> keys)
3631 nlohmann::json jkeys;
3632 for(
uint32_t i = 0; i < keys.size(); i++){
3636 std::string byteKey = keys[i]->ConsumeKeyString();
3638 std::string encodedKey = m_encryptor->Base64Encode(byteKey);
3639 NS_LOG_FUNCTION(
this <<
"KEY" << i+1 << keys[i]->GetId() << encodedKey <<
"\n");
3640 jkeys[
"keys"].push_back({ {
"key_ID", keys[i]->GetId()}, {
"key", encodedKey} });
3657 QKDKeyManagerSystemApplication::GenerateUUID()
3661 UUID ksidRaw = UUID::Sequential();
3662 output = ksidRaw.
string();
3668QKDKeyManagerSystemApplication::CheckEtsi004Association(std::string ksid)
3672 auto itSchedule = m_scheduledChecks.find(ksid);
3673 if(itSchedule!=m_scheduledChecks.end())
3674 m_scheduledChecks.erase(itSchedule);
3676 auto it = m_associations004.find(ksid);
3677 if(it == m_associations004.end()){
3682 if(it->second.peerRegistered &&(it->second).stre_buffer->GetStreamKeyCount() < 2)
3689 Ptr<QBuffer> qBuffer = GetQBuffer(it->second.dstNodeId);
3690 uint32_t availableKeys = qBuffer->GetBitCount();
3691 uint32_t availableKeyChunks = std::floor(availableKeys / it->second.qos.chunkSize);
3693 NS_LOG_FUNCTION(
this << availableKeys << it->second.qos.chunkSize << availableKeyChunks);
3695 if(availableKeyChunks >= 6){
3697 availableKeyChunks = 6;
3698 }
else if(availableKeyChunks >= 2){
3700 availableKeyChunks--;
3701 }
else if(availableKeyChunks == 0){
3703 ScheduleCheckEtsi004Association(
Time(
"2s"),
"CheckEtsi004Association", ksid);
3706 Fill(it->second.dstNodeId, ksid, availableKeyChunks*it->second.qos.chunkSize);
3708 }
else if(!it->second.peerRegistered)
3714QKDKeyManagerSystemApplication::ReadJsonQos(
3716 nlohmann::json jOpenConnectRequest)
3719 if(jOpenConnectRequest.contains(
"QoS")) {
3721 if(jOpenConnectRequest[
"QoS"].contains(
"Key_chunk_size"))
3722 inQos.
chunkSize = jOpenConnectRequest[
"QoS"][
"Key_chunk_size"];
3728std::vector<std::string>
3729QKDKeyManagerSystemApplication::ReadUri(std::string s)
3733 std::string delimiter {
"/"}, token;
3735 std::vector<std::string> uriParams;
3736 while((pos = s.find(delimiter)) != std::string::npos){
3737 token = s.substr(0, pos);
3739 uriParams.push_back(token);
3741 s.erase(0, pos + delimiter.length());
3745 uriParams.push_back(s);
3751QKDKeyManagerSystemApplication::CreateKeyStreamSession(
3752 std::string srcSaeId,
3753 std::string dstSaeId,
3760 SBufferStream->Initialize();
3761 SBufferStream->SetDescription (
"(STREAM)");
3762 SBufferStream->SetIndex( m_qbuffersVector.size() );
3763 uint32_t dstNodeId = GetController()->GetRoute(dstSaeId).GetDestinationKmNodeId();
3764 m_qbuffersVector.push_back(SBufferStream);
3765 m_qbuffers.insert(std::make_pair(dstNodeId, SBufferStream) );
3769 for(
uint32_t i = 0; i < GetNode()->GetNApplications(); ++i)
3772 applicationIndex = i;
3775 SBufferStream->SetSrcKMSApplicationIndex(applicationIndex);
3779 uint32_t srcNodeId = GetNode()->GetId();
3780 std::string graphTitle =
"SBUFFER (STREAM): " + std::to_string(srcNodeId) +
"-SAE(" + srcSaeId +
") - " + std::to_string(dstNodeId) +
"-SAE(" + dstSaeId +
")" ;
3782 Ptr<Node> dstNode = NodeList::GetNode(dstNodeId);
3787 SBufferStream->GetIndex(),
3788 SBufferStream->GetSrcKMSApplicationIndex(),
3799 GetController()->GetRoute(dstSaeId).GetDestinationKmsAddress(),
3805 ksid = GenerateUUID();
3806 newKeyStreamSession.peerRegistered =
false;
3809 m_associations004.insert(std::make_pair(ksid, newKeyStreamSession));
3815QKDKeyManagerSystemApplication::GenerateRandomString(
const int len,
const uint32_t seed){
3817 static const char alphanum[] =
3819 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
3820 "abcdefghijklmnopqrstuvwxyz";
3825 for(
int i = 0; i < len; ++i){
3826 tmp_s += alphanum[rand() %(
sizeof(alphanum) - 1)];
iter_impl< basic_json > iterator
an iterator for a basic_json container
a polymophic address class
The base class for all ns3 applications.
void DoDispose() override
Destructor implementation.
AttributeValue implementation for Boolean.
An identifier for simulation events.
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()
void CreateResponse(const HttpStatus status)
size_t GetContentLength() const
Return the size of the binary body vector.
HTTPMessage::HttpStatus GetStatus() const
To be returned with a status code in a response is a status text describing the status code by text r...
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.
static Ipv4Address GetAny()
AttributeValue implementation for Ipv4Address.
Smart pointer class similar to boost::intrusive_ptr.
void CreateGraphForBuffer(Ptr< Node > srcKMSNode, Ptr< Node > dstKMSNode, uint32_t bufferID, uint32_t srcKMSApplicationIndex, std::string graphName, std::string graphType, Ptr< QBuffer > buff)
Connect new QBuffer/Sbuffer to QKDTotalGraph.
QKDNetSim implements Key Management System(KMS) as an application that listens on TCP port 80.
uint32_t GetMaxKeyPerRequest()
Get maximum number of keys per request(ETSI QKD 014)
uint32_t m_port
Local port to bind to.
void HandlePeerCloseKMSs(Ptr< Socket > socket)
Handle an connection close.
static TypeId GetTypeId()
Get the type ID.
void DataSend(Ptr< Socket >, uint32_t)
Ptr< QKDKMSQueueLogic > m_queueLogic
KMS Queue Logic for ETSI 004 QoS handling.
void SendToSocketPairKMS(Ptr< Socket > socket, Ptr< Packet > packet)
Send packet to the pair socket.
RequestType
Request types.
@ ETSI_QKD_014_GET_STATUS
Integer equivalent = 0.
void HandleAccept(Ptr< Socket > s, const Address &from)
Handle an incoming connection.
void StopApplication() override
Stop KMS Application.
std::map< std::string, Association004 > m_associations004
Ptr< Socket > GetSendSocketKMS(Ipv4Address kmsDstAddress)
Obtain send socket.
Ptr< QCenController > m_cen_controller
Asigned Q centralized controler for routing!
std::map< uint32_t, Ipv4Address > m_peerAddressTable
IP address of peer KM nodes.
uint32_t GetTotalRx() const
Get the total amount of bytes received.
void ScheduleReleaseAssociation(Time t, std::string action, std::string ksid, std::string surplusKeyId, uint32_t syncIndex)
void HttpKMSAddQuery(Ipv4Address dstKms, HttpQuery request)
remember HTTP request made to peer KMS
void HandleAcceptKMSs(Ptr< Socket > s, const Address &from)
Handle an incoming connection.
std::vector< Ptr< QBuffer > > m_qbuffersVector
The list of QBuffers is necessary for plotting.
std::map< Ipv4Address, std::pair< Ptr< Socket >, Ptr< Socket > > > m_socketPairsKMS
we do not know which KMS is going to initialize new TCP connection to peer KMS.
uint32_t m_totalRx
Total bytes received.
void ProcessPacketKMSs(HTTPMessage header, Ptr< Packet > packet, Ptr< Socket > socket)
QKD key manager system application process the request peer KMS, and complete certain actions to resp...
void ConnectionSucceeded(Ptr< Socket > socket)
@toDo:following functions
std::map< Ptr< Socket >, Ptr< Packet > > m_packetQueues
Buffering unsend messages due to connection problems.
void StartSBufferClients(uint32_t dstKmNodeId)
Start s-buffers control – monitoring.
std::map< uint32_t, uint32_t > m_link_states
Notified link states!
std::string GetAddressString(Ipv4Address address)
Get address as string.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTrace
Traced Callback: received packets, source address.
void Fill(uint32_t dstKmNodeId, std::string direction, uint32_t amount)
Fill s-buffer.
void SetSocket(std::string type, Ptr< Socket > socket)
Set sink socket.
Ptr< Socket > GetSocket() const
Get sink socket.
void SetPeerKmAddress(uint32_t dstKmNodeId, Ipv4Address dstKmAddress)
Set peer KM node address.
Ptr< QBuffer > GetQBuffer(uint32_t remoteKmNodeId, std::string type="ns3::QBuffer")
Get q-buffer established with remote key manager.
void HttpProxyRequestAdd(HttpQuery query)
Save query.
QKDKeyManagerSystemApplication::RequestType FetchRequestType(std::string s)
Get request type.
void SBufferClientCheck(uint32_t dstKmNodeId)
check s-buffer levels
void DataSendKMSs(Ptr< Socket >, uint32_t)
void SetCenController(Ptr< QCenController > controller)
Ipv4Address GetAddress()
Get local address.
void HandleReadKMSs(Ptr< Socket > socket)
Handle a packet received by the KMS from KMS.
void HandlePeerError(Ptr< Socket > socket)
Handle an connection error.
std::string GenerateUUID()
Generate UUID.
Ptr< QCenController > GetCenController()
void HandlePeerClose(Ptr< Socket > socket)
Handle an connection close.
Ipv4Address GetPeerKmAddress(uint32_t dstKmNodeId)
TracedCallback< Ptr< const Packet >, const Address & > m_rxTraceKMSs
Ptr< QKDEncryptor > m_encryptor
std::string GetId()
Get key menager ID.
std::map< std::string, uint32_t > m_qkdmodules
QKD modules and KM node ID they connect to.
Ptr< QKDControl > GetController()
Get QKDN controller object.
void PacketReceivedKMSs(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Assemble byte stream to extract HTTPMessage.
std::map< uint32_t, Ptr< QBuffer > > m_qbuffers
Q-buffers for every QKD connection.
Ptr< SBuffer > GetSBuffer(uint32_t dstKmNodeId, std::string type)
TracedCallback< const uint32_t &, const uint32_t &, const uint32_t &, const uint32_t & > m_keyConsumedRelay
Ptr< Node > GetNode()
Get node.
void CreateQBuffer(uint32_t dstId, Ptr< QBuffer > bufferConf)
Create Q buffer shared with remote key manager node.
void Relay(uint32_t dstKmNodeId, uint32_t amount)
Start key relay function.
uint32_t m_maxKeyPerRequest
TracedCallback< const std::string &, const std::string &, const uint32_t & > m_keyServedTrace
void DoDispose() override
Destructor implementation.
uint32_t GetPort() const
Get local port.
void HandlePeerErrorKMSs(Ptr< Socket > socket)
Handle an connection error.
void UpdateLinkState(uint32_t dstKmNodeId)
Check the QKD link state to given destination.
std::map< uint32_t, Ptr< SBuffer > > m_keys_dec
LOCAL S-buffers for the inbound point-to-poit usage.
void SetController(Ptr< QKDControl > controller)
Assign QKDN controller.
~QKDKeyManagerSystemApplication() override
QKDKeyManagerSystemApplication destructor.
void SendToSocketPair(Ptr< Socket > socket, Ptr< Packet > packet)
Send packet to the pair socket.
std::vector< std::string > ReadUri(std::string s)
Read parameters from URI.
Ptr< SBuffer > CreateRelaySBuffer(uint32_t srcNodeId, uint32_t dstNodeId, std::string description)
Help function to create relay SBuffers.
Ptr< Socket > m_sinkSocket
uint32_t m_totalRxKMSs
Total bytes received between KMSs.
void StartApplication() override
Start KMS Application.
void HandleRead(Ptr< Socket > socket)
Handle a packet received by the KMS application.
TracedCallback< const uint32_t &, const uint32_t &, const uint32_t & > m_keyWasteRelay
std::map< std::string, EventId > m_scheduledChecks
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_bufferKMS
Buffer for received packets(TCP segmentation)
Ptr< QKDControl > m_controller
Asigned QKDN controller.
std::map< uint32_t, Ptr< SBuffer > > m_keys_enc
LOCAL S-buffers for the outbound point-to-point usage.
TracedCallback< const std::string &, const std::string &, const uint32_t & > m_qkdKeyGeneratedTrace
TracedCallback< const uint32_t &, const uint32_t &, const uint32_t & > m_keyConsumedLink
void EstablishKMLinkSockets(Ipv4Address remoteKmAddress)
Create sink socket to listen requests exchanged between KMSs.
void RegisterQKDModule(uint32_t dstId, std::string moduleId)
Registers a QKD module in key manager.
void PacketReceived(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Assemble byte stream to extract HTTPMessage.
TracedCallback< Ptr< const Packet > > m_txTraceKMSs
void ReleaseAssociation(std::string ksid, std::string surplusKeyId, uint32_t syncIndex)
release key stream association
void ConnectionFailedKMSs(Ptr< Socket > socket)
void ConnectionFailed(Ptr< Socket > socket)
void ProcessRequest(HTTPMessage header, Ptr< Packet > packet, Ptr< Socket > socket)
QKD key manager system application process the request from QKDApp, and complete certain actions to r...
void ScheduleCheckEtsi004Association(Time t, std::string action, std::string ksid)
schedule next event in an attempt to fill association buffer
TracedCallback< Ptr< const Packet > > m_txTrace
void ConnectionSucceededKMSs(Ptr< Socket > socket)
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer
Buffer for received packets(TCP segmentation)
void CheckEtsi004Association(std::string ksid)
Check the state of a single assocation.
void CheckSocketsKMS(Ipv4Address dstSaeId)
Prepare send socket to communicate with peer KMS Application.
QKDKeyManagerSystemApplication()
QKDKeyManagerSystemApplication constructor.
Ipv4Address m_local
Local address to bind to.
Introspection did not find any typical Config paths.
Ipv4Address GetDestinationKmsAddress() const
Get destination KMS Address.
uint32_t GetNextHop() const
Get next hop.
uint32_t GetHop() const
Get hop.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now()
Return the current simulation virtual time.
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
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 Close()=0
Close a socket.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int Listen()=0
Listen for incoming connections.
static TypeId GetTypeId()
Get the type ID.
Simulation virtual time values and global simulation resolution.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
AttributeValue implementation for TypeId.
Universally unique identifier(UUID)
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,...
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Callback< R, Args... > MakeNullCallback()
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
#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_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
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.
@ error
throw a parse_error exception in case of a tag
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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 AttributeAccessor > MakeUintegerAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeIpv4AddressAccessor(T1 a1)
Ptr< const AttributeChecker > MakeTypeIdChecker()
Ptr< const AttributeChecker > MakeIpv4AddressChecker()
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
std::string destination_sae
std::string surplus_key_ID