12#include "ns3/address.h"
13#include "ns3/address-utils.h"
15#include "ns3/inet-socket-address.h"
16#include "ns3/inet6-socket-address.h"
18#include "ns3/socket.h"
19#include "ns3/udp-socket-factory.h"
20#include "ns3/tcp-socket-factory.h"
21#include "ns3/simulator.h"
22#include "ns3/socket-factory.h"
23#include "ns3/packet.h"
24#include "ns3/trace-source-accessor.h"
38 .SetGroupName(
"Applications")
40 .AddAttribute(
"Protocol",
"The type of protocol to use.",
44 .AddAttribute(
"NumberOfKeyToFetchFromKMS",
45 "The total number of keys per request to LKMS(ESTI QKD 014)",
49 .AddAttribute(
"LengthOfAuthenticationTag",
50 "The default length of the authentication tag",
54 .AddAttribute(
"EncryptionType",
55 "The type of encryption to be used(0-unencrypted, 1-OTP, 2-AES)",
59 .AddAttribute(
"AuthenticationType",
60 "The type of authentication to be used(0-unauthenticated, 1-VMAC, 2-MD5, 3-SHA1)",
64 .AddAttribute(
"AESLifetime",
65 "Lifetime of AES key expressed in number of packets",
69 .AddAttribute(
"UseCrypto",
70 "Should crypto functions be performed(0-No, 1-Yes)",
74 .AddAttribute(
"WaitInsufficient",
"Penalty time(in seconds) when there is insufficient amount of key",
79 .AddTraceSource(
"Tx",
"A new packet is created and is sent",
81 "ns3::Packet::TracedCallback")
82 .AddTraceSource(
"TxSig",
"A new signaling packet is created and is sent",
84 "ns3::Packet::TracedCallback")
85 .AddTraceSource(
"TxKMS",
"A new packet is created and is sent to local KMS",
87 "ns3::Packet::TracedCallback")
88 .AddTraceSource(
"Rx",
"A new packet is received",
90 "ns3::Packet::TracedCallback")
91 .AddTraceSource(
"RxSig",
"A new signaling packet is received",
93 "ns3::Packet::TracedCallback")
94 .AddTraceSource(
"RxKMS",
"A new packet is received from local KMS",
96 "ns3::Packet::TracedCallback")
97 .AddTraceSource(
"StateTransition",
98 "Trace fired upon every QKDApp014 state transition.",
100 "ns3::Application::StateTransitionCallback")
101 .AddTraceSource(
"PacketEncrypted",
102 "The change trance for currenly ecrypted packet",
104 "ns3::QKDCrypto::PacketEncrypted")
105 .AddTraceSource(
"PacketDecrypted",
106 "The change trance for currenly decrypted packet",
108 "ns3::QKDCrypto::PacketDecrypted")
109 .AddTraceSource(
"PacketAuthenticated",
110 "The change trance for currenly authenticated packet",
112 "ns3::QKDCrypto::PacketAuthenticated")
113 .AddTraceSource(
"PacketDeAuthenticated",
114 "The change trance for currenly deauthenticated packet",
116 "ns3::QKDCrypto::PacketDeAuthenticated")
117 .AddTraceSource(
"Mx",
"Missed send packet call",
119 "ns3::Packet::TracedCallback")
137 : m_signalingSocketApp(nullptr),
138 m_dataSocketApp(nullptr),
139 m_socketToKMS(nullptr),
140 m_state(NOT_STARTED),
144 m_encryptor(nullptr),
150 {
"NOT_STARTED",
"INITIALIZED"},
151 {
"INITIALIZED",
"WAIT"},
152 {
"INITIALIZED",
"READY"},
155 {
"READY",
"SEND_DATA"},
156 {
"SEND_DATA",
"READY"},
157 {
"READY",
"DECRYPT_DATA"},
158 {
"DECRYPT_DATA",
"READY"},
159 {
"DECRYPT_DATA",
"STOPPED"},
160 {
"SEND_DATA",
"STOPPED"},
161 {
"READY",
"STOPPED"},
279 if(action ==
"ManageStores"){
627 while((packet = socket->RecvFrom(from))){
628 if(packet->GetSize() == 0)
632 << packet <<
"PACKETID: " << packet->GetUid()
633 <<
" of size: " << packet->GetSize()
637 <<
"s packet from KMS received "
638 << packet->GetSize() <<
" bytes from "
655 while((packet = socket->RecvFrom(from))){
656 if(packet->GetSize() == 0)
660 <<
"PACKETID: " << packet->GetUid()
661 <<
" of size: " << packet->GetSize()
665 <<
"s packet from APP pair received "
666 << packet->GetSize() <<
" bytes from "
683 while((packet = socket->RecvFrom(from))){
684 if(packet->GetSize() == 0)
688 <<
"PACKETID: " << packet->GetUid()
689 <<
" of size: " << packet->GetSize()
693 <<
"s signaling packet from APP pair received "
694 << packet->GetSize() <<
" bytes from "
724 buffer->PeekHeader(header);
727 while(buffer->GetSize() >= header.
GetLength()){
728 NS_LOG_DEBUG(
"Removing packet of size " << header.
GetLength() <<
" from buffer of size " << buffer->GetSize());
738 buffer->PeekHeader(header);
760 while (buffer->GetSize() > 0) {
762 std::string
bufferStr(buffer->GetSize(),
'\0');
769 NS_LOG_DEBUG(
"[DEBUG] Fragmented or incomplete HTTP message. Awaiting more data.");
778 NS_LOG_DEBUG(
"[DEBUG] Detected fragmented or malformed HTTP message. Waiting...");
800 NS_LOG_DEBUG(
"[DEBUG] Remaining buffer size: " << buffer->GetSize());
852 if(type ==
"encryption"){
907 <<
"authentication key count" <<
m_authStore.size()
970std::vector<std::string>
974 std::vector<std::string> keyIds {};
1081 <<
"\n\tauthentication tag" <<
authTag);
1100 else qHeader.SetEncryptionKeyId(std::string(32,
'0'));
1103 else qHeader.SetAuthenticationKeyId(std::string(32,
'0'));
1105 qHeader.SetLength(packet->GetSize() +
qHeader.GetSerializedSize());
1108 NS_LOG_FUNCTION(
this <<
"sending data packet id" << packet->GetUid() << packet->GetSize());
1134 uint8_t *buffer =
new uint8_t[packet->GetSize()];
1135 packet->CopyData(buffer, packet->GetSize());
1136 std::string
payload = std::string((
char*)buffer, packet->GetSize());
1214 <<
" of size: " << packet->GetSize()
1233 else if(
keyType ==
"authentication")
1239 if(number <= 0)
NS_FATAL_ERROR(
this <<
"invalid m_numberOfKeysKMS" << number);
1240 if(size <= 0)
NS_FATAL_ERROR(
this <<
"invalid key_size" << size);
1250 headerUri +=
"/number/" + std::to_string(number) +
"/size/" + std::to_string(size);
1265 <<
" of size: " << packet->GetSize()
1293 <<
" of size: " << packet->GetSize()
1326 std::vector<std::string> keyIds;
1331 else if(
keyType ==
"authentication")
1335 keyIds.push_back(key->GetId());
1343 if(
responseBody[
"message"] == std::string {
"insufficient amount of key material"})
1357 std::make_pair((
it.value())[
"key_ID"],
1385 for(
auto const&
el: keyIds){
1391 m_encStore.insert( std::make_pair(
it->second->GetId(),
it->second) );
1392 NS_LOG_DEBUG(
this <<
"moved to encryption store\t" <<
it->second->GetId());
1394 m_authStore.insert( std::make_pair(
it->second->GetId(),
it->second) );
1395 NS_LOG_DEBUG(
this <<
"moved to authentication store\t" <<
it->second->GetId());
1399 NS_LOG_DEBUG(
this <<
"key removed from common\t" <<
it->second->GetId());
1411 for(
auto const&
el : keyIds){
1414 type =
it->second->GetType();
1443 for(
uint i = 0;
i < keyIds.size();
i++)
1444 jKeyIds[
"key_IDs"].push_back({ {
"key_ID", keyIds[
i]} });
1474 NS_LOG_FUNCTION(
this <<
"PEER Sending SIGNALING PACKETID: " << packet->GetUid()
1475 <<
" of size: " << packet->GetSize()
1524 "for AppTransitionTree()!");
1533 "for AppTransitionTree()!");
1546 return "NOT_STARTED";
1549 return "INITIALIZED";
1561 return "DECRYPT_DATA";
1568 return "FATAL_ERROR";
1678 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1679 "abcdefghijklmnopqrstuvwxyz";
1699 keyId.insert(8,
"-");
1700 keyId.insert(13,
"-");
1701 keyId.insert(18,
"-");
1702 keyId.insert(23,
"-");
1722 return CryptoPP::AES::MAX_KEYLENGTH * 8;
1739 return CryptoPP::AES::BLOCKSIZE * 8;
1753std::vector<std::string>
1762 while((pos = s.find(
delimiter)) != std::string::npos){
1763 token = s.substr(0, pos);
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.
Ptr< Node > GetNode() const
Class for representing data rates.
uint64_t GetBitRate() const
Get the underlying bitrate.
bool IsPending() const
This method is syntactic sugar for !IsExpired().
The basic class to represent both HTTP requests and responses.
std::string GetRequestUri() const
std::string ToString()
Takes the headers added to the message along with the body and outputs it to a std::string for use in...
void CreateRequest(const std::string &url, const std::string &method)
std::string GetMessageBodyString()
HTTPMessage & SetHeader(const std::string &name, const std::string &value)
Set a header in the map to the value provided.
void CreateResponse(const HttpStatus status)
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.
Smart pointer class similar to boost::intrusive_ptr.
Establish secure communication on application lavel to use the key and test LKSM.
void SetState(State state)
set application state
void AppTransitionTree()
Transition tree of the application.
uint32_t m_master
is master App014
void HandleAcceptFromKMS(Ptr< Socket > s, const Address &from)
Handle an incoming connection from KMS.
std::string PopHttpKmsRequest()
Pop HTTP request from kms queue.
TracedCallback< const std::string &, Ptr< const Packet > > m_rxKmsTrace
Traced Callback: received packets from KMS.
Ptr< Socket > m_dataSocketApp
void HandleReadFromKMS(Ptr< Socket > socket)
Handle a packet received by the QKD application from KMS application.
std::map< std::string, Ptr< AppKey > > m_authStore
void QAppPacketReceived(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Check for tcp segmentation of signaling packets received from KMS.
Ptr< QKDEncryptor > m_encryptor
encryptor
std::vector< std::string > m_kmsHttpReqQueue
void ConnectionSignalingToAppSucceeded(Ptr< Socket > socket)
Callback function after the signaling connection to the APP is complete.
void SwitchAppState(State state)
Change the state of the application.
TracedCallback< const std::string &, Ptr< const Packet > > m_txTrace
Traced Callback: transmitted data packets.
std::string CreateKeyIdField(std::string keyId)
Create encryption key id field for the QKDApp header.
void ProcessDataPacket(QKDAppHeader header, Ptr< Packet > packet, Ptr< Socket > socket)
Process data packets from peer QKD application.
void HandlePeerCloseSignalingFromApp(Ptr< Socket > socket)
Handle a signaling connection close from peer QKD application.
void ConnectionSignalingToAppFailed(Ptr< Socket > socket)
Callback function after the signaling connection to the APP has.
bool ConnectionRequestedFromApp(Ptr< Socket > socket, const Address &address)
Callback function after the connection for response from KMS has been received.
TracedCallback< const std::string &, Ptr< const Packet > > m_rxSigTrace
Traced Callback: received signaling packets.
State GetState() const
returns application state
TracedCallback< const std::string &, Ptr< const Packet > > m_txKmsTrace
Traced Callback: transmitted packets to KMS.
std::string GetPacketContent(uint32_t msgLength=0)
Get the packet payload content.
Ipv4Address GetPeerIp()
Get ipv4 address of destination.
void HandlePeerErrorFromKMS(Ptr< Socket > socket)
Handle a connection error from KMS.
Ptr< Socket > m_signalingSocketApp
TracedCallback< const std::string &, Ptr< const Packet > > m_mxTrace
Traced Callback: missed send packet call.
void InitKeyStores()
Initialize key stores at application layer.
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer_kms
Buffer for received packets(fragmentation)
void StartApplication() override
Start application.
void Setup(std::string socketType, std::string appId, std::string remoteAppId, const Address &appAddress, const Address &remoteAppAddress, const Address &kmAddress, uint32_t packetSize, DataRate dataRate, std::string type)
uint32_t m_aesLifetime
key lifetime in bytes
Time m_waitInsufficient
time wait before submitting new get_key after error
void ConnectionToKMSSucceeded(Ptr< Socket > socket)
Callback function after the connection to the KMS is complete.
State
QKD App states(App) States that refer to QKDApp014 data transmision!
Ptr< Socket > m_socketToKMS
void PrintStoreStats()
Print status information on key stores.
static TypeId GetTypeId()
Get the type ID.
Ipv4Address GetIp()
Get ipv4 address of source.
void SendDataPacket()
Send protected data.
std::vector< std::string > PopHttpAppRequest()
Pop HTTP request from app queue.
Ptr< AppKey > GetLocalKey(std::string keyType, std::string keyId="")
Get key from key store.
void HandleAcceptSignalingFromApp(Ptr< Socket > s, const Address &from)
Handle a signaling incoming connection from peer QKD application.
EventId m_scheduleManageStores
uint32_t GetAuthenticationKeySize()
Get key size for defined authentication algorithm.
std::string m_id
source application id
void ManageStores()
Checks the state of the key stores.
void HandlePeerCloseFromKMS(Ptr< Socket > socket)
Handle a connection close from KMS.
uint32_t GetEncryptionKeySize()
Get key size for defined encryption algorithm.
uint32_t m_encryption
encryption type
std::string IpToString(Ipv4Address address)
Convert ipv4 address in string.
void PushHttpAppRequest(std::vector< std::string > keyIds)
Adds HTTP request to app queue to properly map response later.
void ProcessResponseFromKMS(HTTPMessage &header, Ptr< Packet > packet, Ptr< Socket > socket)
Process response from KMS application.
void PrepareSocketToApp()
Prepare send socket to communicate with QKD Application.
void HandleAcceptFromApp(Ptr< Socket > s, const Address &from)
Handle an incoming connection from peer QKD application.
void ConnectionToAppFailed(Ptr< Socket > socket)
Callback function after the connection to the APP has failed.
std::string GetAppStateString() const
Returns the current state of the application in string format.
Address m_kms
local kms address
std::vector< std::vector< std::string > > m_appHttpReqQueue
void GetKeyWithKeyIDs(std::string keyIds)
Get keys identified with given IDs from local KMS.
TracedCallback< Ptr< Packet >, std::string > m_authenticationTrace
trace callback for authentication
uint32_t m_numberOfKeysKMS
number of keys to fetch per request
std::string ReadKeyIdField(std::string keyId)
Read key ID from the encryption key ID field of the QKDApp header.
bool ConnectionRequestedFromKMS(Ptr< Socket > socket, const Address &address)
Callback function after the connection for response from KMS has been received.
TracedCallback< Ptr< Packet > > m_encryptionTrace
trace callback for encryption
uint32_t m_authentication
authentication type
std::string GetId()
Get the application ID.
void ScheduleAction(Time t, std::string action)
Schedule action to performe.
uint32_t m_authTagSize
length of the authentication tag in bits
void StopApplication() override
Stop application.
void HandleReadFromApp(Ptr< Socket > socket)
Handle a packet received by the QKD application from peer QKD application.
void ScheduleTx()
Schedule event to send data.
TracedCallback< const std::string &, Ptr< const Packet > > m_rxTrace
Traced Callback: received data packets.
void HandlePeerErrorFromApp(Ptr< Socket > socket)
Handle a connection error from peer QKD application.
void ConnectionToAppSucceeded(Ptr< Socket > socket)
Callback function after the connection to the APP is complete.
TracedCallback< const std::string &, Ptr< const Packet > > m_txSigTrace
Traced Callback: transmitted signaling packets.
void ProcessSignalingPacketFromApp(HTTPMessage &header, Ptr< Packet > packet, Ptr< Socket > socket)
Process signaling packets from peer QKD application.
void DoDispose() override
Destructor implementation.
void GetKeysFromKMS(std::string keyType)
Get keys from local KMS.
bool m_isDataConnectedToApp
std::map< std::string, Ptr< AppKey > > m_commonStore
std::string m_dstId
destination application id
void DataToKMSSend(Ptr< Socket >, uint32_t)
Callback function to notify that data to KMS has been sent.
void ConnectionToKMSFailed(Ptr< Socket > socket)
Callback function after the connection to the KMS has failed.
ns3::TracedCallback< const std::string &, const std::string & > m_stateTransitionTrace
The StateTransition trace source.
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer_QKDApp014
Buffer for received packets(fragmentation)
void SendKeyIds(std::vector< std::string > keyIds, HTTPMessage::HttpStatus statusCode=HTTPMessage::Ok)
Implementation of send KEY_IDS notification.
void GetStatusFromKMS()
Get status from local KMS.
Address m_local
local address
void HandlePeerErrorSignalingFromApp(Ptr< Socket > socket)
Handle a signaling connection error from peer QKD application.
static uint32_t m_applicationCounts
application count
void SetCryptoSettings(uint32_t encryptionType, uint32_t authenticationType, uint32_t authenticationTagLengthInBits)
Set encryption and authentication type.
void HttpPacketReceived(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Check for tcp segmentation of packets received.
void CheckAppState()
Checks the conditions to change the application state.
uint32_t m_useCrypto
execute crypo algorithms
void PrepareSocketToKMS()
Prepare send socket to communicate with KMS Application.
std::multimap< std::string, std::string > m_transitionMatrix
transition map of protocol states
Ipv4Address GetKmsIp()
Get ipv4 address of local KMS.
TracedCallback< Ptr< Packet >, std::string > m_deauthenticationTrace
trace callback for authentication check
std::map< std::string, Ptr< AppKey > > m_encStore
void HandleReadSignalingFromApp(Ptr< Socket > socket)
Handle a signaling packet received by the QKD application from peer QKD application.
bool ConnectionRequestedSignalingFromApp(Ptr< Socket > socket, const Address &address)
Callback function after the connection for response from KMS has been received.
TracedCallback< Ptr< Packet > > m_decryptionTrace
trace callback for decryption
std::vector< std::string > ReadUri(std::string s)
Read http uri in vector.
Address m_peer
peer address
uint32_t m_size
data packet size
QKDEncryptor::AuthenticationType m_authenticationType
authentication type
void HandlePeerCloseFromApp(Ptr< Socket > socket)
Handle a connection close from peer QKD application.
bool m_isSignalingConnectedToApp
QKDEncryptor::EncryptionType m_encryptionType
encryption type
void PushHttpKmsRequest(std::string input)
Adds HTTP request to kms queue to properly map response later.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
static Time Now()
Return the current simulation virtual time.
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
void 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 Socket::SocketErrno GetErrno() const =0
Get last error number.
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
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 Connect(const Address &address)=0
Initiate a connection to a remote host.
void SetCloseCallbacks(Callback< void, Ptr< Socket > > normalClose, Callback< void, Ptr< Socket > > errorClose)
Detect socket recv() events such as graceful shutdown or error.
void 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.
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
AttributeValue implementation for TypeId.
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,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
#define NS_LOG_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_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
#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.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Ptr< const AttributeChecker > MakeTypeIdChecker()
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
static const uint32_t packetSize
Packet size generated at the AP.