A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
qkd-link-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright(c) 2020 DOTFEESA www.tk.etf.unsa.ba
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 *
7 *
8 * Author: Miralem Mehic <miralem.mehic@ieee.org>
9 */
10
11#include "ns3/abort.h"
12#include "ns3/log.h"
13#include "ns3/simulator.h"
14#include "ns3/queue.h"
15#include "ns3/config.h"
16#include "ns3/packet.h"
17#include "ns3/object.h"
18#include "ns3/names.h"
19#include "ns3/internet-module.h"
20#include "ns3/random-variable-stream.h"
21#include "ns3/trace-helper.h"
22#include "ns3/traffic-control-module.h"
23
24#include "qkd-link-helper.h"
25
26namespace ns3 {
27
28NS_LOG_COMPONENT_DEFINE("QKDLinkHelper");
29
31{
32 m_useRealStorages = false;
33 m_controllers.clear();
34 m_adjList.clear();
35}
36
37/**
38* @brief ADD QKDGraph
39* @param Ptr<Node> src
40* @param Ptr<Node> dst
41*/
42void
44{
45 std::cout << "ADD GRAPHS! " << std::endl;
47 for(int32_t i = 0; i < nNodes; ++i)
48 {
52 for(uint32_t i = 0; i < node->GetNApplications(); ++i)
53 {
54 kms = node->GetApplication(i)->GetObject <QKDKeyManagerSystemApplication>();
56 if(kms) break;
57 }
58
59 if(kms)
60 {
62
63 std::vector<Ptr<QBuffer> > Qbuffers = kms->GetQBuffersVector();
64 for(const auto& buffer : Qbuffers)
65 {
66 buffer->SetSrcKMSApplicationIndex(applicationIndex);
67 NS_LOG_FUNCTION(this << buffer << buffer->GetState() << buffer->GetIndex() );
68
69 uint32_t dstNodeId = buffer->GetRemoteNodeId();
71
72 std::string graphTitle = "";
73 if(
74 buffer->GetInstanceTypeId().GetName() == "ns3::SBuffer"
75 ){
76
78 std::string bufferDescription = sbuffer->GetDescription();
79 if(sbuffer->GetType() == SBuffer::LOCAL_SBUFFER)
80 {
81 std::ostringstream temp1;
82 temp1 << "SBUFFER (LOCAL) between " << node->GetId() << " and " << dstKmsNode->GetId();
83 graphTitle = temp1.str();
84
85 }else if(sbuffer->GetType() == SBuffer::RELAY_SBUFFER)
86 {
87 std::ostringstream temp1;
88 temp1 << "SBUFFER (RELAY) between " << node->GetId() << " and " << dstKmsNode->GetId();
89 graphTitle = temp1.str();
90 }else if(sbuffer->GetType() == SBuffer::STREAM_SBUFFER)
91 {
92 std::ostringstream temp1;
93 temp1 << "SBUFFER (STREAM) between " << node->GetId() << " and " << dstKmsNode->GetId();
94 graphTitle = temp1.str();
95 }
96
97 if(!bufferDescription.empty())
99 }
100
101 NS_LOG_FUNCTION(this << "BufferTitle: " << graphTitle);
102
104 node,
106 buffer->GetIndex(),
107 buffer->GetSrcKMSApplicationIndex(),
108 graphTitle,
109 "png",
110 buffer
111 );
112 }
113 }
114 }
115}
116
117/**
118* @brief ADD QKDGraph
119* @param Ptr<Node> src
120* @param Ptr<Node> dst
121*/
122void
124 Ptr<Node> src,
125 Ptr<Node> dst
126) {
127 AddGraph(src, dst, "", "png");
128}
129
130/**
131* @brief ADD QKDGraph
132* @param Ptr<Node> src
133* @param Ptr<Node> dst
134* @param std::string graphName
135*/
136void
138 Ptr<Node> src,
139 Ptr<Node> dst,
140 std::string graphName
141){
142 AddGraph(src, dst, graphName, "png");
143}
144
145/**
146* @brief ADD QKDGraph
147* @param Ptr<QKDControl> QKDControl
148* @param Ptr<Node> src
149* @param Ptr<Node> dst
150* @param std::string graphName
151* @param std::string graphType
152*/
153void
157 std::string graphName,
158 std::string graphType
159) {
160
161 NS_LOG_FUNCTION(this);
162
165 for(uint32_t i = 0; i < srcKMSNode->GetNApplications(); ++i){
166 kms = srcKMSNode->GetApplication(i)->GetObject <QKDKeyManagerSystemApplication>();
168 if(kms) break;
169 }
170 NS_ASSERT(kms);
171
172 Ptr<QBuffer> buffer = kms->GetQBuffer( dstKmsNode->GetId(), "ns3::QBuffer" );
173 NS_ASSERT(buffer);
174
175 buffer->SetSrcKMSApplicationIndex(applicationIndex);
176 NS_LOG_FUNCTION(this << buffer << buffer->GetState() << buffer->GetIndex() );
177
179 QKDGraphManager->CreateGraphForBuffer(srcKMSNode, dstKmsNode, buffer->GetIndex(), buffer->GetSrcKMSApplicationIndex(), graphName, graphType, buffer);
180}
181
182/**
183* @brief Print QKDGraphs
184*/
185void
193
196{
197 NS_LOG_FUNCTION(this);
198
199 Ptr<QKDControl> controller = n->GetObject<QKDControl>();
200 if(!controller){
202 factory.SetTypeId("ns3::QKDControl");
203 controller = factory.Create <QKDControl>();
204 controller->SetNode(n);
205 n->AggregateObject(controller);
206 }
207 return controller;
208}
209
212{
213 NS_LOG_FUNCTION(this);
214
215 Ptr<QCenController> controller = node->GetObject<QCenController>();
216 if(!controller){
218 factory.SetTypeId("ns3::QCenController");
219 controller = factory.Create <QCenController>();
220 controller->SetNode(node);
221 node->AggregateObject(controller);
222 }
223
224 m_cen_controller = controller;
225 return controller;
226}
227
228void
240
241void
243 std::vector<Ptr<QKDControl> > controllers,
249)
250{
251 NS_LOG_FUNCTION(this);
252
253 for(auto controller : controllers)
254 controller->ConfigureQBuffers(Mmin, Mthr, Mmax, Mcurr, defaultKeySize);
255}
256
257void
259 std::vector<Ptr<QKDControl> > controllers,
265)
266{
267 for(auto controller : controllers)
268 controller->ConfigureRSBuffers(Mmin, Mthr, Mmax, Mcurr, defaultKeySize);
269}
270
271void
282
283void
285{
288 Ptr<Object> protocol = factory.Create <Object>();
289 node->AggregateObject(protocol);
290}
291
294{
295 uint32_t output = 0;
296 for(auto el : m_controllers)
297 {
298 if(el.first == nodeId)
299 break;
300 output++;
301 }
302
303 return output;
304}
305
308{
309 auto it = std::next(std::begin(m_controllers), position);
310 if(it == m_controllers.end())
311 NS_LOG_ERROR(this);
312
313 return it->first;
314}
315
316void
318{
319 NS_LOG_FUNCTION(this);
320 //Code adjusted from: https://www.srcmake.com/home/cpp-shortest-path-dijkstra
321 if(reroute == 0){ //Use old code
322 for(size_t i = 0; i < controllers.size(); i++)
323 {
324 // Create a vector to represent a row, and add it to the adjList.
325 std::vector<std::pair<uint32_t, uint32_t> > row;
326 m_adjList.push_back(row);
327 }
328
329 //Read inputs into sorted map entries where key is KMNodeId and value is QKDControl
330 for(auto el : controllers)
331 m_controllers.insert(std::make_pair(el->GetLocalKMNodeId(), el));
332 //Algorithm uses nodes from 0 to size. Our nodes have other numbers!
333 //We use this map to transit from position(0 to size) to actual node Id
334
337
338 //We use are automated procedure to fill adjList!
339 uint32_t row = 0;
340 for(auto const& el : m_controllers) //For each controller
341 {
342 NS_LOG_FUNCTION(this << "KMNodeId: " << el.first << "Row: " << row);
343 //Get connecting remote KM node IDs
344 std::vector<uint32_t> remoteKmNodeIds = el.second->GetRemoteKmNodeIds();
345 //Go through all remote KM node IDs and fill the graph
346 for(auto const& kmNodeId : remoteKmNodeIds)
347 {
348 NS_LOG_FUNCTION(this << "Connected to: " << kmNodeId << "Column: " << GetColumn(kmNodeId));
349 m_adjList[row].push_back(std::make_pair(GetColumn(kmNodeId), uint32_t(1))); //weight is always 1 in our simple case
350 }
351
352 ++row;
353 }
354
355 }else{ //Use centralized controller. qcen-control
356 m_cen_controller->RegisterDControllers(controllers); //Just initialize centralized controller!
357
358 }
359
360}
361
362// Given an Adjacency List, find all shortest paths from "start" to all other vertices.
363std::vector< std::pair<uint32_t, uint32_t> >
365 std::vector< std::vector<std::pair<uint32_t, uint32_t> > > adjList,
366 uint32_t start)
367{
368 std::vector<std::pair<uint32_t, uint32_t> > dist; // First int is dist, second is the previous node.
369
370 // Initialize all source->vertex as infinite.
371 int n = adjList.size();
372 for(int i = 0; i < n; i++)
373 {
374 dist.push_back(std::make_pair(uint32_t(1000000007), uint32_t(i))); // Define "infinity" as necessary by constraints.
375 }
376
377 // Create a PQ.
378 std::priority_queue<std::pair<int, int>, std::vector< std::pair<int, int> >, std::greater<std::pair<int, int> > > pq;
379
380 // Add source to pq, where distance is 0.
381 pq.push(std::make_pair(int(start), 0));
382 dist[start] = std::make_pair(uint32_t(0), start);
383
384 // While pq isn't empty...
385 while(pq.empty() == false)
386 {
387 // Get min distance vertex from pq.(Call it u.)
388 int u = pq.top().first;
389 pq.pop();
390
391 // Visit all of u's friends. For each one(called v)....
392 int listSize = adjList[u].size();
393 for(int i = 0; i < listSize; i++)
394 {
395 uint32_t v = adjList[u][i].first;
396 uint32_t weight = adjList[u][i].second;
397
398 // If the distance to v is shorter by going through u...
399 if(dist[v].first > dist[u].first + weight)
400 {
401 // Update the distance of v.
402 dist[v].first = dist[u].first + weight;
403 // Update the previous node of v.
404 dist[v].second = u;
405 // Insert v into the pq.
406 pq.push(std::make_pair(v, dist[v].first));
407 }
408 }
409 }
410
411 return dist;
412}
413
414
415void
417{
418 NS_LOG_FUNCTION(this << m_controllers.size() );
419
420 if(!m_controllers.empty())
421 { //old code
422
423 std::vector<std::pair<uint32_t, uint32_t> > dist; // First int is dist, second is the previous node.
424 for(auto el : m_controllers)
425 {
427 int distSize = dist.size();
428 for(int i = 0; i < distSize; i++)
429 {
430 int currnode = i;
431 std::vector<uint32_t> path;
432 while(currnode != int(GetColumn(el.first)))
433 {
434 path.push_back(currnode);
435 currnode = dist[currnode].second;
436 }
437 /*
438 path is empty if the node is the node!
439 the first element in path is destination node!
440 the last element in path is the next hop!
441 GetColumn(el.fist) is the source node!
442 dist[i].first is number of hops
443 i is source node as well
444 */
445 uint32_t hops = dist[i].first;
446 if(hops >= 1){ //Populate routing table
447 uint32_t nextHop = ReverseColumn(path[path.size()-1]);
448 Ipv4Address nextHopAddress = m_controllers.find(nextHop)->second->GetLocalKMAddress();
449 uint32_t dstNodeId = ReverseColumn(uint32_t(i));
450 Ipv4Address dstNodeAddress = m_controllers.find(dstNodeId)->second->GetLocalKMAddress();
451 std::string dstKmId = m_controllers.find(dstNodeId)->second->GetLocalKMId();
453 nextHop,//nextHop KM node ID
454 nextHopAddress, //nextHop KM address
455 hops, // Dirrect p2p connection(number of hops)
456 dstNodeId, //Destination KM node ID
457 dstNodeAddress, //Destination KM address
458 dstKmId
459 );
460 el.second->AddRouteEntry(newEntry);
461 }
462
463 }
464
465 }
466 }
467}
468
469} // namespace ns3
Ipv4 addresses are stored in host order in this class.
static uint32_t GetNNodes()
Definition node-list.cc:247
static Ptr< Node > GetNode(uint32_t n)
Definition node-list.cc:240
Instantiate subclasses of ns3::Object.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
A base class which provides memory management and object aggregation.
Definition object.h:78
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
QCenController is a centralized controller used for re-routing.
As described in OPENQKD deliverable D6.1(section 5), the QKD control is a network component with the ...
Definition qkd-control.h:64
static QKDGraphManager * getInstance()
Signelton getInstance function.
void PrintGraphs()
Print graphs.
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.
Introspection did not find any typical Config paths.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Definition first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.