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"
53 .SetGroupName(
"Applications")
56 .AddAttribute (
"Protocol",
"The type of protocol to use.",
60 .AddAttribute (
"LocalAddress",
"The ipv4 address of the application",
63 MakeIpv4AddressChecker ())
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 SDN detects and blocks malicious get_key_004 request?",
88 MakeUintegerChecker<uint32_t> ())
89 .AddAttribute (
"QKDLinkUpdateInterval",
90 "Default value of QKD link status update interval (in seconds)",
93 MakeDoubleChecker<double> ())
96 .AddTraceSource (
"Tx",
"A new packet is created and is sent to the APP",
98 "ns3::QKDSDNController::Tx")
99 .AddTraceSource (
"Rx",
"A packet from the APP has been received",
101 "ns3::QKDSDNController::Rx")
102 .AddTraceSource (
"TxSDNs",
"A new packet is created and is sent to the SDN",
104 "ns3::QKDSDNController::TxSDNs")
105 .AddTraceSource (
"RxSDNs",
"A packet from the APP has been received",
107 "ns3::QKDSDNController::RxSDNs")
109 .AddTraceSource (
"NewKeyGeneratedEmir",
"The trace to monitor key material received from QL",
111 "ns3::QKDSDNController::NewKeyGeneratedEmir")
112 .AddTraceSource (
"KeyServedEmir",
"The trace to monitor key material served to QKD Apps",
114 "ns3:QKDSDNController::KeyServedEmir")
116 .AddTraceSource (
"NewKeyGenerated",
"The trace to monitor key material received from QL",
118 "ns3::QKDSDNController::NewKeyGenerated")
120 .AddTraceSource (
"KeyServedEtsi014",
"The threce to monitor key usage by etsi 014",
122 "ns3::QKDSDNController::KeyServedEtsi014")
124 .AddTraceSource (
"KeyServedEtsi004",
"The threce to monitor key usage by etsi 004",
126 "ns3::QKDSDNController::KeyServedEtsi004")
128 .AddTraceSource (
"DropKMSRequest",
"Drop a request from the queue disc",
130 "ns3::QKDSDNController::TracedCallback")
230 sendSocket->
Connect ( receiveAddress );
235 <<
"Create the response socket " << sendSocket
250 if(j->first == socket){
251 uint32_t response = j->first->Send(j->second);
252 response = j->first->Send(j->second);
255 NS_LOG_FUNCTION(
this << j->first <<
"Sending packet from the queue!" << response );
299 if(sendingSocket->
GetPeerName(connectedAddress) == 0){
300 sendingSocket->
Send(packet);
320 while ((packet = socket->
RecvFrom (from)))
333 <<
"s SDN received packet ID: "
334 << packet->
GetUid () <<
" of "
335 << packet->
GetSize () <<
" bytes from "
338 <<
" total Rx " <<
m_totalRx <<
" bytes");
350 std::string receivedStatus = p->
ToString();
354 if (receivedStatus.find(
"Fragment") != std::string::npos) {
355 auto itBuffer =
m_buffer.find (from);
358 std::make_pair (from, Create<Packet> (0))
361 buffer = itBuffer->second;
372 uint8_t *b1 =
new uint8_t[buffer->
GetSize ()];
374 std::string requestString = std::string((
char*)b1);
378 parser.Parse(&request, requestString);
391 uint8_t *b2 =
new uint8_t[completePacket->
GetSize ()];
393 std::string s2 = std::string((
char*)b2);
396 parser.Parse(&request2, s2);
471 if(j->second) j->second->Close();
493 uint32_t slave_SAE_ID = 0;
497 std::string s = headerIn.
GetUri();
498 std::string delimiter =
"/";
502 std::vector<std::string> uriParams;
503 while ((pos = s.find(delimiter)) != std::string::npos) {
504 token = s.substr(0, pos);
505 if(token.length() > 0){
506 uriParams.push_back(token);
508 s.erase(0, pos + delimiter.length());
511 uriParams.push_back(s);
515 uriParams.size() > 3 &&
516 uriParams[1] ==
"api" &&
517 uriParams[2] ==
"v1" &&
518 uriParams[3] ==
"keys"
520 std::string receivedAddressStr (uriParams[0]);
522 NS_LOG_FUNCTION(
this <<
"received address" << receivedAddressStr << receivedAddress);
531 std::stringstream tempString (uriParams[4]);
532 tempString >> slave_SAE_ID;
538 NS_LOG_FUNCTION (
this <<
"slave_SAE_ID: " << slave_SAE_ID <<
"requestType: " << requestType );
543 uint32_t srcSaeId = 0;
544 uint32_t dstSaeId = 0;
547 std::string keyAssociationIdString;
549 if(headerIn.
GetMethod() == HTTPMessage::HttpMethod::POST){
555 jrequest = nlohmann::json::parse(payload);
556 if (jrequest.contains(
"master_SAE_ID")) srcSaeId = jrequest[
"master_SAE_ID"];
557 if (jrequest.contains(
"slave_SAE_ID")) dstSaeId = jrequest[
"slave_SAE_ID"];
558 if (jrequest.contains(
"key_association_id")) keyAssociationIdString = jrequest[
"key_association_id"];
560 std::string kmsSrcAddressStr;
561 if (jrequest.contains(
"master_kms_address")) kmsSrcAddressStr = jrequest[
"master_kms_address"];
562 kmsSrcAddress =
Ipv4Address(kmsSrcAddressStr.c_str());
564 std::string kmsDstAddressStr;
565 if (jrequest.contains(
"slave_kms_address")) kmsDstAddressStr = jrequest[
"slave_kms_address"];
566 kmsDstAddress =
Ipv4Address(kmsDstAddressStr.c_str());
569 NS_FATAL_ERROR(
this <<
"JSON parse error of the received payload: " << payload <<
"\t" << payload.length() );
588 newEntry.
SetId(
UUID{keyAssociationIdString} );
590 lr->AddKeyAssociationEntry(newEntry);
592 NS_LOG_FUNCTION (
this <<
"NEW QKD LINK REGISTERED AT SDN CONTROLLER!");
598 j[
"key_association_id"] = keyAssociationIdString;
601 std::string msg = j.dump();
606 {
"Content-Type",
"application/json; charset=utf-8"},
607 {
"Request URI", headerIn.
GetUri() }
609 std::string hMessage = httpMessage.
ToString();
611 (uint8_t*) (hMessage).c_str(),
618 <<
"Sending Response to REGISTER_QKD_LINK\n PacketID: "
630 double expectedConsumption = 0;
631 double effectiveSkr = 0;
632 std::string keyAssociationIdString;
634 if(headerIn.
GetMethod() == HTTPMessage::HttpMethod::POST){
640 jrequest = nlohmann::json::parse(payload);
641 if (jrequest.contains(
"key_association_id")) keyAssociationIdString = jrequest[
"key_association_id"];
642 if (jrequest.contains(
"qkdl_performance_skr")) skr = jrequest[
"qkdl_performance_skr"];
643 if (jrequest.contains(
"qkdl_performance_expected_consumption")) expectedConsumption = jrequest[
"qkdl_performance_expected_consumption"];
644 if (jrequest.contains(
"qkdl_performance_eskr")) effectiveSkr = jrequest[
"qkdl_performance_eskr"];
647 NS_FATAL_ERROR(
this <<
"JSON parse error of the received payload: " << payload <<
"\t" << payload.length() );
657 lr->LookupKeyAssociationById(
UUID{keyAssociationIdString}, conn);
666 lr->SaveKeyAssociation(conn);
668 NS_LOG_FUNCTION (
this <<
"NEW QKD LINK STATS (id: " << keyAssociationIdString <<
"; eskr:" << effectiveSkr <<
") UPDATE RECEIVED AT SDN CONTROLLER!");
672 std::string srcSaeId;
673 std::string dstSaeId;
674 std::string nextHopId;
676 uint32_t linkType = 0;
680 if(headerIn.
GetMethod() == HTTPMessage::HttpMethod::POST){
686 jrequest = nlohmann::json::parse(payload);
687 if (jrequest.contains(
"master_SAE_ID")) srcSaeId = jrequest[
"master_SAE_ID"];
688 if (jrequest.contains(
"slave_SAE_ID")) dstSaeId = jrequest[
"slave_SAE_ID"];
689 if (jrequest.contains(
"hops")) hops = jrequest[
"hops"];
690 if (jrequest.contains(
"linkType")) linkType = jrequest[
"linkType"];
691 if (jrequest.contains(
"next_hop_id")) nextHopId = jrequest[
"next_hop_id"];
693 std::string kmsSrcAddressStr;
694 if (jrequest.contains(
"master_kms_address")) kmsSrcAddressStr = jrequest[
"master_kms_address"];
695 kmsSrcAddress =
Ipv4Address(kmsSrcAddressStr.c_str());
697 std::string kmsDstAddressStr;
698 if (jrequest.contains(
"slave_kms_address")) kmsDstAddressStr = jrequest[
"slave_kms_address"];
699 kmsDstAddress =
Ipv4Address(kmsDstAddressStr.c_str());
702 NS_FATAL_ERROR(
this <<
"JSON parse error of the received payload: " << payload <<
"\t" << payload.length() );
711 NS_LOG_FUNCTION(
this << srcSaeId << dstSaeId << nextHopId << hops << linkType);
727 NS_LOG_FUNCTION (
this <<
"NEW SAE LINK REGISTERED AT SDN CONTROLLER!");
749 }
else if(s ==
"enc_keys") {
753 }
else if(s ==
"dec_keys"){
757 }
else if (s ==
"open_connect"){
761 }
else if (s ==
"get_key") {
765 }
else if (s ==
"close") {
769 }
else if (s ==
"new_app") {
773 }
else if (s ==
"register") {
777 }
else if (s ==
"fill") {
781 }
else if (s ==
"store_pp_key") {
785 }
else if (s ==
"transform_keys") {
789 }
else if (s ==
"close_kms") {
793 }
else if (s ==
"register_sae_link") {
797 }
else if (s ==
"register_qkd_link") {
801 }
else if (s ==
"key_association_status") {
838 lr->AddKeyAssociationEntry(newEntry);
840 NS_LOG_FUNCTION (
this <<
"Create sink socket to listen requests exchanged between KMSs!" );
910 CryptoPP::StringSource(input,
true,
911 new CryptoPP::Base64Encoder(
912 new CryptoPP::StringSink(output)
922 CryptoPP::StringSource(input,
true,
923 new CryptoPP::Base64Decoder(
924 new CryptoPP::StringSink(output)
a polymophic address class
The base class for all ns3 applications.
void DoDispose() override
Destructor implementation.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
The basic class to represent both HTTP requests and responses.
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.
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.
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()
Ptr< T > GetObject() 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 GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
uint64_t GetUid() const
Returns the packet's Uid.
std::string ToString() const
Return a string representation of the packet.
QKDConnectionRegister is a class used to keep details about distant QKD links and applications.
void SetExpectedConsumption(double value)
void SetUpdateStatusInterval(double statusInterval)
void SetSKR(double value)
void SetEffectiveSKR(double value)
TracedCallback< Ptr< const Packet > > m_txTraceSDNs
static TypeId GetTypeId(void)
Get the type ID.
std::map< Ptr< Socket >, Ptr< Packet > > m_packetQueues
Buffering unsend messages due to connection problems.
uint32_t GetMaxKeyPerRequest()
Get maximum number of keys per request (ETSI QKD 014)
uint32_t GetId()
Get key menager system ID.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTrace
Traced Callback: received packets, source address.
uint32_t m_defaultKeySize
uint32_t GetTotalRx() const
Get the total amount of bytes received.
std::map< Ptr< Socket >, Ptr< Socket > > m_socketPairs
the accepted sockets
void HandleRead(Ptr< Socket > socket)
Handle a packet received by the KMS application.
void StopApplication(void)
Stop KMS Application.
TracedCallback< const std::string &, const uint32_t &, const uint32_t &, const uint32_t & > m_keyServedETSI004Trace
TracedCallback< Ptr< const Packet >, const Address & > m_rxTraceSDNs
void StartApplication(void)
Start KMS Application.
std::string Base64Decode(std::string input)
Base64 decoder.
void HandlePeerClose(Ptr< Socket > socket)
Handle an connection close.
void HandlePeerError(Ptr< Socket > socket)
Handle an connection error.
uint32_t m_port
Local port to bind to.
Ipv4Address m_local
Local address to bind to.
TracedCallback< const uint32_t & > m_newKeyGeneratedTraceEmir
uint32_t m_totalRx
Total bytes received
void ConnectionFailed(Ptr< Socket > socket)
TracedCallback< const std::string &, const uint32_t &, Ptr< QKDKey > > m_keyServedETSI014Trace
double m_qkdLinkDefaultUpdateInterval
Default update interval of QKD link status (seconds)
void SetSocket(std::string type, Ptr< Socket > socket)
Set sink socket.
RequestType
Request types.
@ ETSI_QKD_014_GET_KEY
Integer equivalent = 1.
@ ETSI_QKD_004_OPEN_CONNECT
@ ETSI_QKD_014_GET_KEY_WITH_KEY_IDS
Integer equivalent = 2.
@ ETSI_QKD_014_GET_STATUS
Integer equivalent = 0.
QKDSDNController::RequestType FetchRequestType(std::string s)
Get request type.
uint32_t m_maliciousBlocking
TracedCallback< const uint32_t & > m_keyServedTraceEmir
Ptr< Socket > m_sinkSocket
void PacketReceived(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Assemble byte stream to extract HTTPMessage.
Ptr< Node > GetNode()
Get node.
void SendToSocketPair(Ptr< Socket > socket, Ptr< Packet > packet)
Send packet to the pair socket.
uint32_t m_maxKeyPerRequest
virtual void DoDispose(void)
@toDo
std::string Base64Encode(std::string input)
Base64 encoder.
virtual ~QKDSDNController()
QKDSDNController destructor.
void ConnectionSucceeded(Ptr< Socket > socket)
@toDo:following functions
std::map< Ptr< Socket >, Ptr< Socket > > GetAcceptedSockets(void) const
Get list of all accepted sockets.
void AddNewLink(uint32_t srcSaeId, uint32_t dstSaeId, Ipv4Address kmsDstAddress, Ptr< QKDBuffer > srcBuffer)
Inform KMS about the new QKD connection/link.
TracedCallback< const Ipv4Address &, Ptr< const Packet > > m_dropTrace
Traced callback: fired when a packet is dropped.
void RegisterSaePair(Ptr< Node > srcNode, Ptr< Node > dstNode, uint32_t srcSaeId, uint32_t dstSaeId, std::string type)
Inform KMS about the SAE connection.
void HandleAccept(Ptr< Socket > s, const Address &from)
Handle an incoming connection.
TracedCallback< const uint32_t &, const uint32_t & > m_newKeyGeneratedTrace
void DataSend(Ptr< Socket >, uint32_t)
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer
Buffer for received packets (TCP segmentation)
Ptr< Socket > GetSocket(void) const
Get sink socket.
QKDSDNController()
QKDSDNController constructor.
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...
TracedCallback< Ptr< const Packet > > m_txTrace
void SetNode(Ptr< Node > n)
Set node.
static Time Now()
Return the current simulation virtual time.
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual Socket::SocketType GetSocketType() const =0
void SetCloseCallbacks(Callback< void, Ptr< Socket >> normalClose, Callback< void, Ptr< Socket >> errorClose)
Detect socket recv() events such as graceful shutdown or error.
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
virtual int ShutdownRecv()=0
void SetDataSentCallback(Callback< void, Ptr< Socket >, uint32_t > dataSent)
Notify application when a packet has been sent from transport protocol (non-standard socket call)
virtual int GetPeerName(Address &address) const =0
Get the peer address of a connected socket.
virtual int ShutdownSend()=0
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
virtual int Close()=0
Close a socket.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int Listen()=0
Listen for incoming connections.
void SetConnectCallback(Callback< void, Ptr< Socket >> connectionSucceeded, Callback< void, Ptr< Socket >> connectionFailed)
Specify callbacks to allow the caller to determine if the connection succeeds of fails.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
static TypeId GetTypeId()
Get the type ID.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Universally unique identifier (UUID)
static TypeId GetTypeId()
Get the type ID.
Hold an unsigned integer type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Callback< R, Args... > MakeNullCallback()
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_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.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
basic_json<> json
default JSON class
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 AttributeChecker > MakeTypeIdChecker()
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)