Directory Structuring
diff --git a/nlsr.conf b/nlsr.conf
new file mode 100644
index 0000000..2f2287b
--- /dev/null
+++ b/nlsr.conf
@@ -0,0 +1,14 @@
+network ndn
+site-name memphis.edu
+router-name cs/macbook
+
+ndnneighbor /ndn/memphis.edu/cs/maia 7
+link-cost /ndn/memphis.edu/cs/maia 30
+ndnneighbor /ndn/memphis.edu/cs/pollux 10
+link-cost /ndn/memphis.edu/cs/pollux 25
+
+ndnname /ndn/memphis.edu/cs/macbook/name1
+ndnname /ndn/memphis.edu/cs/macbook/name2
+
+
+!logdir /Users/akmhoque/NLSR-CPP/log
diff --git a/src/communication/nlsr_dm.cpp b/src/communication/nlsr_dm.cpp
new file mode 100644
index 0000000..92a911d
--- /dev/null
+++ b/src/communication/nlsr_dm.cpp
@@ -0,0 +1,202 @@
+#include<iostream>
+#include<cstdlib>
+
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/util/io.hpp>
+
+#include "nlsr.hpp"
+#include "nlsr_dm.hpp"
+#include "utility/nlsr_tokenizer.hpp"
+#include "nlsr_lsdb.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+ using namespace ndn;
+
+ void
+ DataManager::processContent(Nlsr& pnlsr, const ndn::Interest &interest,
+ const ndn::Data & data, interestManager& im)
+ {
+ cout << "I: " << interest.toUri() << endl;
+ string dataName(data.getName().toUri());
+ //cout << "D: " << dataName << endl;
+ //cout << "Data Content: " << dataContent << endl;
+ nlsrTokenizer nt(dataName,"/");
+ //SignatureSha256WithRsa sig(data.getSignature());
+ //ndn::Name keyName=sig.getKeyLocator().getName();
+ //cout<<"Key Locator Name: "<<keyName.toUri()<<endl;
+ string chkString("info");
+ if( nt.doesTokenExist(chkString) )
+ {
+ string dataContent((char *)data.getContent().value());
+ processContentInfo(pnlsr,dataName,dataContent);
+ }
+ chkString="LSA";
+ if( nt.doesTokenExist(chkString) )
+ {
+ string dataContent((char *)data.getContent().value());
+ processContentLsa(pnlsr, dataName, dataContent);
+ }
+ chkString="keys";
+ if( nt.doesTokenExist(chkString) )
+ {
+ processContentKeys(pnlsr, data);
+ }
+ }
+
+ void
+ DataManager::processContentInfo(Nlsr& pnlsr, string& dataName,
+ string& dataContent)
+ {
+ nlsrTokenizer nt(dataName,"/");
+ string chkString("info");
+ string neighbor=nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
+ int oldStatus=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+ int infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
+ //debugging purpose start
+ cout <<"Before Updates: " <<endl;
+ cout <<"Neighbor : "<<neighbor<<endl;
+ cout<<"Status: "<< oldStatus << endl;
+ cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
+ //debugging purpose end
+ pnlsr.getAdl().setStatusOfNeighbor(neighbor,1);
+ pnlsr.getAdl().setTimedOutInterestCount(neighbor,0);
+ int newStatus=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+ infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
+ //debugging purpose
+ cout <<"After Updates: " <<endl;
+ cout <<"Neighbor : "<<neighbor<<endl;
+ cout<<"Status: "<< newStatus << endl;
+ cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
+ //debugging purpose end
+ if ( ( oldStatus-newStatus)!= 0 ) // change in Adjacency list
+ {
+ pnlsr.incrementAdjBuildCount();
+ /* Need to schedule event for Adjacency LSA building */
+ if ( pnlsr.getIsBuildAdjLsaSheduled() == 0 )
+ {
+ pnlsr.setIsBuildAdjLsaSheduled(1);
+ // event here
+ pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
+ ndn::bind(&Lsdb::scheduledAdjLsaBuild, pnlsr.getLsdb(),
+ boost::ref(pnlsr)));
+ }
+ }
+ }
+
+ void
+ DataManager::processContentLsa(Nlsr& pnlsr, string& dataName,
+ string& dataContent)
+ {
+ nlsrTokenizer nt(dataName,"/");
+ string chkString("LSA");
+ string origRouter=nt.getTokenString(nt.getTokenPosition(chkString)+1,
+ nt.getTokenNumber()-4);
+ string lsTypeString=nt.getToken(nt.getTokenNumber()-3);
+ string lsSeNoString=nt.getToken(nt.getTokenNumber()-2);
+ uint32_t interestedLsSeqNo;
+ try
+ {
+ interestedLsSeqNo=boost::lexical_cast<uint32_t>(lsSeNoString);
+ }
+ catch(std::exception &e)
+ {
+ return;
+ }
+ if( lsTypeString == "1" ) //Name Lsa
+ {
+ processContentNameLsa(pnlsr, origRouter+"/"+lsTypeString,
+ interestedLsSeqNo, dataContent);
+ }
+ else if( lsTypeString == "2" ) //Adj Lsa
+ {
+ processContentAdjLsa(pnlsr, origRouter+"/"+lsTypeString,
+ interestedLsSeqNo, dataContent);
+ }
+ else if( lsTypeString == "3" ) //Cor Lsa
+ {
+ processContentCorLsa(pnlsr, origRouter+"/"+lsTypeString,
+ interestedLsSeqNo, dataContent);
+ }
+ else
+ {
+ cout<<"Unrecognized LSA Type :("<<endl;
+ }
+ }
+
+ void
+ DataManager::processContentNameLsa(Nlsr& pnlsr, string lsaKey,
+ uint32_t lsSeqNo, string& dataContent)
+ {
+ if ( pnlsr.getLsdb().isNameLsaNew(lsaKey,lsSeqNo))
+ {
+ NameLsa nameLsa;
+ if( nameLsa.initNameLsaFromContent(dataContent) )
+ {
+ pnlsr.getLsdb().installNameLsa(pnlsr, nameLsa);
+ }
+ else
+ {
+ cout<<"LSA data decoding error :("<<endl;
+ }
+ }
+ }
+
+ void
+ DataManager::processContentAdjLsa(Nlsr& pnlsr, string lsaKey,
+ uint32_t lsSeqNo, string& dataContent)
+ {
+ if ( pnlsr.getLsdb().isAdjLsaNew(lsaKey,lsSeqNo))
+ {
+ AdjLsa adjLsa;
+ if( adjLsa.initAdjLsaFromContent(dataContent) )
+ {
+ pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
+ }
+ else
+ {
+ cout<<"LSA data decoding error :("<<endl;
+ }
+ }
+ }
+
+ void
+ DataManager::processContentCorLsa(Nlsr& pnlsr, string lsaKey,
+ uint32_t lsSeqNo, string& dataContent)
+ {
+ if ( pnlsr.getLsdb().isCorLsaNew(lsaKey,lsSeqNo))
+ {
+ CorLsa corLsa;
+ if( corLsa.initCorLsaFromContent(dataContent) )
+ {
+ pnlsr.getLsdb().installCorLsa(pnlsr, corLsa);
+ }
+ else
+ {
+ cout<<"LSA data decoding error :("<<endl;
+ }
+ }
+ }
+
+ void
+ DataManager::processContentKeys(Nlsr& pnlsr, const ndn::Data& data)
+ {
+ std::ofstream outFile("data_received");
+ ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
+ cout<<" processContentKeys called "<<endl;
+ SignatureSha256WithRsa signature(data.getSignature());
+ cout<<"D: <<"<<data<<endl;
+ cout<<"Key Locator: "<<signature.getKeyLocator().getName().toUri()<<endl;
+ ndn::shared_ptr<ndn::IdentityCertificate> cert=ndn::make_shared<ndn::IdentityCertificate>();
+ cert->wireDecode(data.getContent().blockFromValue());
+ cout<<*(cert)<<endl;
+
+ if( pnlsr.getKeyManager().verifySignature(*(cert),cert->getPublicKeyInfo()))
+ {
+ cout<<"Verified Data"<<endl;
+ }
+ }
+}//namespace nlsr
diff --git a/src/communication/nlsr_dm.hpp b/src/communication/nlsr_dm.hpp
new file mode 100644
index 0000000..fdb45db
--- /dev/null
+++ b/src/communication/nlsr_dm.hpp
@@ -0,0 +1,40 @@
+#ifndef NLSR_DM_HPP
+#define NLSR_DM_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "nlsr_im.hpp"
+
+namespace nlsr
+{
+
+ using namespace ndn;
+ using namespace std;
+
+ class Nlsr;
+
+ class DataManager
+ {
+ public:
+ void processContent(Nlsr& pnlsr, const ndn::Interest &interest,
+ const ndn::Data& data, interestManager& im);
+ private:
+ void processContentInfo(Nlsr& pnlsr, string& dataName,
+ string& dataContent);
+ void processContentLsa(Nlsr& pnlsr, string& dataName,
+ string& dataContent);
+ void processContentNameLsa(Nlsr& pnlsr, string lsaKey,
+ uint32_t lsSeqNo, string& dataContent);
+ void processContentAdjLsa(Nlsr& pnlsr, string lsaKey,
+ uint32_t lsSeqNo, string& dataContent);
+ void processContentCorLsa(Nlsr& pnlsr, string lsaKey,
+ uint32_t lsSeqNo, string& dataContent);
+ void processContentKeys(Nlsr& pnlsr, const ndn::Data& data);
+
+
+ };
+
+}//namespace nlsr
+#endif
diff --git a/src/communication/nlsr_im.cpp b/src/communication/nlsr_im.cpp
new file mode 100644
index 0000000..7495265
--- /dev/null
+++ b/src/communication/nlsr_im.cpp
@@ -0,0 +1,300 @@
+#include<iostream>
+#include<cstdlib>
+
+
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/util/io.hpp>
+
+#include "nlsr.hpp"
+#include "nlsr_im.hpp"
+#include "nlsr_dm.hpp"
+#include "utility/nlsr_tokenizer.hpp"
+#include "nlsr_lsdb.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+ using namespace ndn;
+
+ void
+ interestManager::processInterest( Nlsr& pnlsr,
+ const ndn::Name &name,
+ const ndn::Interest &interest)
+ {
+ cout << "<< I: " << interest << endl;
+ string intName=interest.getName().toUri();
+ cout << "Interest Received for Name: "<< intName <<endl;
+ nlsrTokenizer nt(intName,"/");
+ string chkString("info");
+ if( nt.doesTokenExist(chkString) )
+ {
+ string nbr=nt.getTokenString(nt.getTokenPosition(chkString)+1);
+ cout <<"Neighbor: " << nbr <<endl;
+ processInterestInfo(pnlsr,nbr,interest);
+ }
+ chkString="LSA";
+ if( nt.doesTokenExist(chkString) )
+ {
+ processInterestLsa(pnlsr,interest);
+ }
+ chkString="keys";
+ if( nt.doesTokenExist(chkString) )
+ {
+ processInterestKeys(pnlsr,interest);
+ }
+ //Data data(ndn::Name(interest->getName()).append("testApp").appendVersion());
+ //data.setFreshnessPeriod(1000); // 10 sec
+ //data.setContent((const uint8_t*)"HELLO KITTY", sizeof("HELLO KITTY"));
+ //pnlsr.getKeyChain().sign(data);
+ //cout << ">> D: " << data << endl;
+ //pnlsr.getNlsrFace().put(data);
+ }
+
+ void
+ interestManager::processInterestInfo(Nlsr& pnlsr, string& neighbor,
+ const ndn::Interest &interest)
+ {
+ if ( pnlsr.getAdl().isNeighbor(neighbor) )
+ {
+ Data data(ndn::Name(interest.getName()).appendVersion());
+ data.setFreshnessPeriod(1000); // 10 sec
+ data.setContent((const uint8_t*)"info", sizeof("info"));
+ pnlsr.getKeyManager().signData(data);
+ cout << ">> D: " << data << endl;
+ pnlsr.getNlsrFace()->put(data);
+ int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+ if ( status == 0 )
+ {
+ string intName=neighbor +"/"+"info"+
+ pnlsr.getConfParameter().getRouterPrefix();
+ expressInterest( pnlsr,intName,2,
+ pnlsr.getConfParameter().getInterestResendTime());
+ }
+ }
+ }
+
+ void
+ interestManager::processInterestLsa(Nlsr& pnlsr,const ndn::Interest &interest)
+ {
+ string intName=interest.getName().toUri();
+ nlsrTokenizer nt(intName,"/");
+ string chkString("LSA");
+ string origRouter=nt.getTokenString(nt.getTokenPosition(chkString)+1,
+ nt.getTokenNumber()-3);
+ string lsTypeString=nt.getToken(nt.getTokenNumber()-2);
+ string lsSeqString=nt.getToken(nt.getTokenNumber()-1);
+ cout<<"Router Name: "<<origRouter<<endl;
+ cout<<"Ls Type : "<<lsTypeString<<endl;
+ cout<<"Ls Seq : "<<lsSeqString<<endl;
+ uint8_t interestedLsType;
+ uint32_t interestedLsSeqNo;
+ try
+ {
+ interestedLsType=boost::lexical_cast<uint8_t>(lsTypeString);
+ interestedLsSeqNo=boost::lexical_cast<uint32_t>(lsSeqString);
+ }
+ catch(std::exception &e)
+ {
+ return;
+ }
+ cout <<"Ls Type: "<<interestedLsType<<endl;
+ if( lsTypeString == "1" ) //Name Lsa
+ {
+ processInterestForNameLsa(pnlsr, interest,
+ origRouter+"/"+lsTypeString, interestedLsSeqNo);
+ }
+ else if( lsTypeString == "2" ) //Adj Lsa
+ {
+ processInterestForAdjLsa(pnlsr, interest,
+ origRouter+"/"+lsTypeString, interestedLsSeqNo);
+ }
+ else if( lsTypeString == "3" ) //Cor Lsa
+ {
+ processInterestForCorLsa(pnlsr, interest,
+ origRouter+"/"+lsTypeString, interestedLsSeqNo);
+ }
+ else
+ {
+ cout<<"Unrecognized LSA Type :("<<endl;
+ }
+ }
+
+ void
+ interestManager::processInterestForNameLsa(Nlsr& pnlsr,
+ const ndn::Interest &interest,
+ string lsaKey, uint32_t interestedlsSeqNo)
+ {
+ std::pair<NameLsa&, bool> nameLsa=pnlsr.getLsdb().getNameLsa(lsaKey);
+ if( nameLsa.second )
+ {
+ if ( nameLsa.first.getLsSeqNo() >= interestedlsSeqNo )
+ {
+ Data data(ndn::Name(interest.getName()).appendVersion());
+ data.setFreshnessPeriod(1000); // 10 sec
+ string content=nameLsa.first.getNameLsaData();
+ data.setContent((const uint8_t*)content.c_str(),content.size());
+ pnlsr.getKeyManager().signData(data);
+ cout << ">> D: " << data << endl;
+ pnlsr.getNlsrFace()->put(data);
+ }
+ }
+ }
+
+ void
+ interestManager::processInterestForAdjLsa(Nlsr& pnlsr,
+ const ndn::Interest &interest,
+ string lsaKey, uint32_t interestedlsSeqNo)
+ {
+ std::pair<AdjLsa&, bool> adjLsa=pnlsr.getLsdb().getAdjLsa(lsaKey);
+ if( adjLsa.second )
+ {
+ if ( adjLsa.first.getLsSeqNo() >= interestedlsSeqNo )
+ {
+ Data data(ndn::Name(interest.getName()).appendVersion());
+ data.setFreshnessPeriod(1000); // 10 sec
+ string content=adjLsa.first.getAdjLsaData();
+ data.setContent((const uint8_t*)content.c_str(),content.size());
+ pnlsr.getKeyManager().signData(data);
+ cout << ">> D: " << data << endl;
+ pnlsr.getNlsrFace()->put(data);
+ }
+ }
+ }
+
+ void
+ interestManager::processInterestForCorLsa(Nlsr& pnlsr,
+ const ndn::Interest &interest,
+ string lsaKey, uint32_t interestedlsSeqNo)
+ {
+ std::pair<CorLsa&, bool> corLsa=pnlsr.getLsdb().getCorLsa(lsaKey);
+ if( corLsa.second )
+ {
+ if ( corLsa.first.getLsSeqNo() >= interestedlsSeqNo )
+ {
+ Data data(ndn::Name(interest.getName()).appendVersion());
+ data.setFreshnessPeriod(1000); // 10 sec
+ string content=corLsa.first.getCorLsaData();
+ data.setContent((const uint8_t*)content.c_str(),content.size());
+ pnlsr.getKeyManager().signData(data);
+ cout << ">> D: " << data << endl;
+ pnlsr.getNlsrFace()->put(data);
+ }
+ }
+ }
+
+ void
+ interestManager::processInterestKeys(Nlsr& pnlsr,const ndn::Interest &interest)
+ {
+ cout<<" processInterestKeys called "<<endl;
+ ndn::shared_ptr<ndn::IdentityCertificate> cert=pnlsr.getKeyManager().getCertificate("dummy");
+ Data data(ndn::Name(interest.getName()).appendVersion());
+ data.setFreshnessPeriod(1000); // 10 sec
+ data.setContent(cert->wireEncode());
+ pnlsr.getKeyManager().signData(data);
+ std::ofstream outFile("data_sent");
+ ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
+ pnlsr.getNlsrFace()->put(data);
+ }
+
+
+ void
+ interestManager::processInterestTimedOut(Nlsr& pnlsr,
+ const ndn::Interest &interest)
+ {
+ cout << "Timed out interest : " << interest.getName().toUri() << endl;
+ string intName= interest.getName().toUri();
+ nlsrTokenizer nt(intName,"/");
+ string chkString("info");
+ if( nt.doesTokenExist(chkString) )
+ {
+ string nbr=nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
+ processInterestTimedOutInfo( pnlsr , nbr , interest);
+ }
+ chkString="LSA";
+ if( nt.doesTokenExist(chkString) )
+ {
+ processInterestTimedOutLsa(pnlsr, interest);
+ }
+ }
+
+ void
+ interestManager::processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
+ const ndn::Interest &interest)
+ {
+ pnlsr.getAdl().incrementTimedOutInterestCount(neighbor);
+ int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+ int infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
+ cout<<"Neighbor: "<< neighbor << endl;
+ cout<<"Status: "<< status << endl;
+ cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
+ if((infoIntTimedOutCount < pnlsr.getConfParameter().getInterestRetryNumber()))
+ {
+ string intName=neighbor +"/"+"info"+
+ pnlsr.getConfParameter().getRouterPrefix();
+ expressInterest( pnlsr,intName,2,
+ pnlsr.getConfParameter().getInterestResendTime());
+ }
+ else if ( (status == 1) &&
+ (infoIntTimedOutCount == pnlsr.getConfParameter().getInterestRetryNumber()))
+ {
+ pnlsr.getAdl().setStatusOfNeighbor(neighbor,0);
+ pnlsr.incrementAdjBuildCount();
+ if ( pnlsr.getIsBuildAdjLsaSheduled() == 0 )
+ {
+ pnlsr.setIsBuildAdjLsaSheduled(1);
+ // event here
+ pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
+ ndn::bind(&Lsdb::scheduledAdjLsaBuild,&pnlsr.getLsdb(),
+ boost::ref(pnlsr)));
+ }
+ }
+ }
+
+ void
+ interestManager::processInterestTimedOutLsa(Nlsr& pnlsr,
+ const ndn::Interest &interest)
+ {
+ }
+
+ void
+ interestManager::expressInterest(Nlsr& pnlsr,const string& interestNamePrefix,
+ int scope, int seconds)
+ {
+ cout<<"Expressing Interest :"<<interestNamePrefix<<endl;
+ ndn::Interest i((ndn::Name(interestNamePrefix)));
+ //i.setScope(scope);
+ i.setInterestLifetime(seconds*1000);
+ i.setMustBeFresh(true);
+ pnlsr.getNlsrFace()->expressInterest(i,
+ ndn::func_lib::bind(&DataManager::processContent,
+ &pnlsr.getDm(), boost::ref(pnlsr),_1, _2,boost::ref(*this)),
+ ndn::func_lib::bind(&interestManager::processInterestTimedOut,
+ this,boost::ref(pnlsr),_1));
+ }
+
+
+ void
+ interestManager::sendScheduledInfoInterest(Nlsr& pnlsr, int seconds)
+ {
+ std::list<Adjacent> adjList=pnlsr.getAdl().getAdjList();
+ for(std::list<Adjacent>::iterator it=adjList.begin(); it!=adjList.end(); ++it)
+ {
+ string adjName=(*it).getAdjacentName()+"/"+"info"+
+ pnlsr.getConfParameter().getRouterPrefix();
+ expressInterest( pnlsr,adjName,2,
+ pnlsr.getConfParameter().getInterestResendTime());
+ }
+ scheduleInfoInterest(pnlsr, pnlsr.getConfParameter().getInfoInterestInterval());
+ }
+
+ void
+ interestManager::scheduleInfoInterest(Nlsr& pnlsr, int seconds)
+ {
+ EventId eid=pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(seconds),
+ ndn::bind(&interestManager::sendScheduledInfoInterest, this,
+ boost::ref(pnlsr),seconds));
+ }
+
+
+} //namespace nlsr
diff --git a/src/communication/nlsr_im.hpp b/src/communication/nlsr_im.hpp
new file mode 100644
index 0000000..330874f
--- /dev/null
+++ b/src/communication/nlsr_im.hpp
@@ -0,0 +1,52 @@
+#ifndef NLSR_IM_HPP
+#define NLSR_IM_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+namespace nlsr
+{
+
+ using namespace ndn;
+ using namespace std;
+
+ class Nlsr;
+
+ class interestManager
+ {
+ public:
+ interestManager()
+ {
+ }
+ void processInterest(Nlsr& pnlsr, const ndn::Name &name,
+ const ndn::Interest &interest);
+ void processInterestInfo(Nlsr& pnlsr, string& neighbor,
+ const ndn::Interest &interest);
+ void processInterestLsa(Nlsr& pnlsr,const ndn::Interest &interest);
+ void processInterestForNameLsa(Nlsr& pnlsr, const ndn::Interest &interest,
+ string lsaKey, uint32_t interestedlsSeqNo);
+ void processInterestForAdjLsa(Nlsr& pnlsr, const ndn::Interest &interest,
+ string lsaKey, uint32_t interestedlsSeqNo);
+ void processInterestForCorLsa(Nlsr& pnlsr, const ndn::Interest &interest,
+ string lsaKey, uint32_t interestedlsSeqNo);
+
+ void processInterestKeys(Nlsr& pnlsr,const ndn::Interest &interest);
+
+ void processInterestTimedOut(Nlsr& pnlsr, const ndn::Interest &interest);
+ void processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
+ const ndn::Interest &interest);
+ void processInterestTimedOutLsa(Nlsr& pnlsr,const ndn::Interest &interest);
+ void expressInterest(Nlsr& pnlsr,const string& interestNamePrefix, int scope,
+ int seconds);
+ void sendScheduledInfoInterest(Nlsr& pnlsr, int seconds);
+ void scheduleInfoInterest(Nlsr& pnlsr, int seconds);
+
+ private:
+
+
+ };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/communication/nlsr_slh.cpp b/src/communication/nlsr_slh.cpp
new file mode 100644
index 0000000..ac29148
--- /dev/null
+++ b/src/communication/nlsr_slh.cpp
@@ -0,0 +1,147 @@
+#include "nlsr.hpp"
+#include "nlsr_slh.hpp"
+#include "security/nlsr_km.hpp"
+#include "utility/nlsr_tokenizer.hpp"
+
+
+namespace nlsr
+{
+ void
+ SyncLogicHandler::createSyncSocket(Nlsr &pnlsr )
+ {
+ cout<<"Creating Sync socket ......"<<endl;
+ cout<<"Sync prefix: "<<syncPrefix.toUri()<<endl;
+ syncSocket=make_shared<SyncSocket>(syncPrefix, validator, syncFace,
+ bind(&SyncLogicHandler::nsyncUpdateCallBack,this,
+ _1, _2,boost::ref(pnlsr)),
+ bind(&SyncLogicHandler::nsyncRemoveCallBack, this,
+ _1,boost::ref(pnlsr)));
+ }
+
+ void
+ SyncLogicHandler::nsyncUpdateCallBack(const vector<MissingDataInfo> &v,
+ SyncSocket *socket, Nlsr& pnlsr)
+ {
+ cout<<"nsyncUpdateCallBack called ...."<<endl;
+ int n = v.size();
+ for(int i=0; i < n; i++)
+ {
+ std::cout<<"Data Name: "<<v[i].prefix<<" Seq: "<<v[i].high.getSeq()<<endl;
+ processUpdateFromSync(v[i].prefix,v[i].high.getSeq(),pnlsr);
+ }
+ }
+
+ void
+ SyncLogicHandler::nsyncRemoveCallBack(const string& prefix, Nlsr& pnlsr)
+ {
+ cout<<"nsyncRemoveCallBack called ...."<<endl;
+ }
+
+ void
+ SyncLogicHandler::removeRouterFromSyncing(string& routerPrefix)
+ {
+ }
+
+ void
+ SyncLogicHandler::processUpdateFromSync(std::string updateName,
+ uint64_t seqNo, Nlsr& pnlsr)
+ {
+ nlsrTokenizer nt(updateName,"/");
+ string chkString("LSA");
+ if( nt.doesTokenExist(chkString) )
+ {
+ //process LSA Update here
+ string routerName=nt.getTokenString(nt.getTokenPosition(chkString)+1);
+ processRoutingUpdateFromSync(routerName, seqNo, pnlsr);
+ }
+ chkString="keys";
+ if( nt.doesTokenExist(chkString) )
+ {
+ //process keys update here
+ processKeysUpdateFromSync(updateName,seqNo, pnlsr);
+ }
+ }
+
+ void
+ SyncLogicHandler::processRoutingUpdateFromSync(std::string routerName,
+ uint64_t seqNo, Nlsr& pnlsr)
+ {
+ if( routerName != pnlsr.getConfParameter().getRouterPrefix() )
+ {
+ SequencingManager sm(seqNo);
+ cout<<sm;
+ cout<<"Router Name: "<<routerName<<endl;
+ if ( pnlsr.getLsdb().isNameLsaNew(routerName+"/1",sm.getNameLsaSeq()))
+ {
+ cout<<"Updated Name LSA. Need to fetch it"<<endl;
+ string lsaPrefix=
+ pnlsr.getConfParameter().getChronosyncLsaPrefix() +
+ routerName + "/1/" +
+ boost::lexical_cast<std::string>(sm.getNameLsaSeq());
+ pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+ pnlsr.getConfParameter().getInterestResendTime());
+ }
+ if ( pnlsr.getLsdb().isAdjLsaNew(routerName+"/2",sm.getAdjLsaSeq()))
+ {
+ cout<<"Updated Adj LSA. Need to fetch it"<<endl;
+ string lsaPrefix=
+ pnlsr.getConfParameter().getChronosyncLsaPrefix() +
+ routerName + "/2/" +
+ boost::lexical_cast<std::string>(sm.getAdjLsaSeq());
+ pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+ pnlsr.getConfParameter().getInterestResendTime());
+ }
+ if ( pnlsr.getLsdb().isCorLsaNew(routerName+"/3",sm.getCorLsaSeq()))
+ {
+ cout<<"Updated Cor LSA. Need to fetch it"<<endl;
+ string lsaPrefix=
+ pnlsr.getConfParameter().getChronosyncLsaPrefix() +
+ routerName + "/3/" +
+ boost::lexical_cast<std::string>(sm.getCorLsaSeq());
+ pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+ pnlsr.getConfParameter().getInterestResendTime());
+ }
+ }
+ }
+
+ void
+ SyncLogicHandler::processKeysUpdateFromSync(std::string certName,
+ uint64_t seqNo, Nlsr& pnlsr)
+ {
+ string certNamePrefix=certName + "/" + boost::lexical_cast<string>(seqNo);
+ pnlsr.getIm().expressInterest(pnlsr, certNamePrefix, 3,
+ pnlsr.getConfParameter().getInterestResendTime());
+ }
+
+ void
+ SyncLogicHandler::publishRoutingUpdate(SequencingManager& sm,
+ string updatePrefix)
+ {
+ sm.writeSeqNoToFile();
+ publishSyncUpdate(updatePrefix,sm.getCombinedSeqNo());
+ }
+
+ void
+ SyncLogicHandler::publishKeyUpdate(KeyManager& km)
+ {
+ publishSyncUpdate(km.getRouterCertName().toUri(),km.getCertSeqNo());
+ }
+
+ void
+ SyncLogicHandler::publishIdentityUpdate(string identityName)
+ {
+ publishSyncUpdate(identityName,0);
+ }
+
+ void
+ SyncLogicHandler::publishSyncUpdate(string updatePrefix, uint64_t seqNo)
+ {
+ cout<<"Publishing Sync Update ......"<<endl;
+ cout<<"Update in prefix: "<<updatePrefix<<endl;
+ cout<<"Seq No: "<<seqNo<<endl;
+ ndn::Name updateName(updatePrefix);
+ string data("NoData");
+ syncSocket->publishData(updateName,0,data.c_str(),data.size(),1000,seqNo);
+ }
+
+}
diff --git a/src/communication/nlsr_slh.hpp b/src/communication/nlsr_slh.hpp
new file mode 100644
index 0000000..3fef612
--- /dev/null
+++ b/src/communication/nlsr_slh.hpp
@@ -0,0 +1,65 @@
+#ifndef NLSR_SLH_HPP
+#define NLSR_SLH_HPP
+
+#include <iostream>
+
+#include <ndn-cpp-dev/face.hpp>
+#include <nsync/sync-socket.h>
+#include <ndn-cpp-dev/security/validator-null.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "nlsr_sm.hpp"
+
+class KeyManager;
+
+extern "C" {
+#include <unistd.h>
+}
+
+using namespace ndn;
+using namespace Sync;
+using namespace std;
+
+class interestManager;
+class ConfParameter;
+
+namespace nlsr
+{
+ class SyncLogicHandler
+ {
+ public:
+ SyncLogicHandler(ndn::shared_ptr<boost::asio::io_service> ioService)
+ : validator(new ndn::ValidatorNull())
+ , syncFace(new ndn::Face(ioService))
+ {}
+
+
+ void createSyncSocket(Nlsr& pnlsr);
+ void nsyncUpdateCallBack(const vector<MissingDataInfo> &v,
+ SyncSocket *socket, Nlsr& pnlsr );
+ void nsyncRemoveCallBack(const string& prefix, Nlsr &pnlsr);
+ void removeRouterFromSyncing(string& routerPrefix);
+ void publishRoutingUpdate(SequencingManager& sm, string updatePrefix);
+ void publishKeyUpdate(KeyManager& km);
+ void publishIdentityUpdate(string identityName);
+ void setSyncPrefix(string sp)
+ {
+ syncPrefix.clear();
+ syncPrefix.set(sp);
+ }
+ private:
+ void processUpdateFromSync(std::string updateName, uint64_t seqNo,
+ Nlsr& pnlsr);
+ void processRoutingUpdateFromSync(std::string routerName, uint64_t seqNo,
+ Nlsr& pnlsr);
+ void processKeysUpdateFromSync(std::string certName, uint64_t seqNo,
+ Nlsr& pnlsr);
+ void publishSyncUpdate(string updatePrefix, uint64_t seqNo);
+ private:
+ ndn::shared_ptr<ndn::ValidatorNull> validator;
+ ndn::shared_ptr<ndn::Face> syncFace;
+ ndn::shared_ptr<SyncSocket> syncSocket;
+ ndn::Name syncPrefix;
+ };
+}
+#endif
diff --git a/src/route/nlsr_fe.cpp b/src/route/nlsr_fe.cpp
new file mode 100644
index 0000000..5f4811c
--- /dev/null
+++ b/src/route/nlsr_fe.cpp
@@ -0,0 +1,48 @@
+#include <list>
+#include "nlsr_fe.hpp"
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ bool
+ FibEntry::isEqualNextHops(Nhl &nhlOther)
+ {
+ if ( nhl.getNhlSize() != nhlOther.getNhlSize() )
+ {
+ return false;
+ }
+ else
+ {
+ int nhCount=0;
+ std::list<NextHop>::iterator it1, it2;
+ for ( it1=nhl.getNextHopList().begin(),
+ it2 = nhlOther.getNextHopList().begin() ;
+ it1 != nhl.getNextHopList().end() ; it1++, it2++)
+ {
+ if ((*it1).getConnectingFace() == (*it2).getConnectingFace() )
+ {
+ (*it1).setRouteCost((*it2).getRouteCost());
+ nhCount++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ return nhCount == nhl.getNhlSize();
+ }
+ }
+
+ ostream&
+ operator<<(ostream& os, FibEntry& fe)
+ {
+ os<<"Name Prefix: "<<fe.getName()<<endl;
+ os<<"Time to Refresh: "<<fe.getTimeToRefresh()<<endl;
+ os<<fe.getNhl()<<endl;
+ return os;
+ }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_fe.hpp b/src/route/nlsr_fe.hpp
new file mode 100644
index 0000000..c85e045
--- /dev/null
+++ b/src/route/nlsr_fe.hpp
@@ -0,0 +1,85 @@
+#ifndef NLSR_FE_HPP
+#define NLSR_FE_HPP
+
+#include<list>
+#include <iostream>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "nlsr_nexthop.hpp"
+#include "nlsr_nhl.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ class FibEntry
+ {
+ public:
+ FibEntry()
+ : name()
+ , timeToRefresh(0)
+ , feSeqNo(0)
+ {
+ }
+
+ FibEntry(string n)
+ {
+ name=n;
+ }
+
+ string getName()
+ {
+ return name;
+ }
+
+ Nhl& getNhl()
+ {
+ return nhl;
+ }
+
+ int getTimeToRefresh()
+ {
+ return timeToRefresh;
+ }
+
+ void setTimeToRefresh(int ttr)
+ {
+ timeToRefresh=ttr;
+ }
+
+ void setFeExpiringEventId(ndn::EventId feid)
+ {
+ feExpiringEventId=feid;
+ }
+
+ ndn::EventId getFeExpiringEventId()
+ {
+ return feExpiringEventId;
+ }
+
+ void setFeSeqNo(int fsn)
+ {
+ feSeqNo=fsn;
+ }
+
+ int getFeSeqNo()
+ {
+ return feSeqNo;
+ }
+
+ bool isEqualNextHops(Nhl &nhlOther);
+
+ private:
+ string name;
+ int timeToRefresh;
+ ndn::EventId feExpiringEventId;
+ int feSeqNo;
+ Nhl nhl;
+ };
+
+ ostream& operator<<(ostream& os, FibEntry& fe);
+
+} //namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_fib.cpp b/src/route/nlsr_fib.cpp
new file mode 100644
index 0000000..8fb7928
--- /dev/null
+++ b/src/route/nlsr_fib.cpp
@@ -0,0 +1,168 @@
+#include<list>
+#include "nlsr_fe.hpp"
+#include "nlsr_fib.hpp"
+#include "nlsr_nhl.hpp"
+#include "nlsr.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+ using namespace ndn;
+
+ static bool
+ fibEntryNameCompare(FibEntry& fe, string name)
+ {
+ return fe.getName() == name ;
+ }
+
+ void
+ Fib::cancelScheduledFeExpiringEvent(Nlsr& pnlsr, EventId eid)
+ {
+ pnlsr.getScheduler().cancelEvent(eid);
+ }
+
+
+ ndn::EventId
+ Fib::scheduleFibEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
+ int refreshTime)
+ {
+ return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(refreshTime),
+ ndn::bind(&Fib::refreshFibEntry,this,name,feSeqNum));
+ }
+
+ void
+ Fib::refreshFibEntry(string name, int feSeqNum)
+ {
+ }
+
+ void
+ Fib::removeFromFib(Nlsr& pnlsr, string name)
+ {
+ std::list<FibEntry >::iterator it = std::find_if( fibTable.begin(),
+ fibTable.end(), bind(&fibEntryNameCompare, _1, name));
+ if( it != fibTable.end() )
+ {
+ for(std::list<NextHop>::iterator nhit=(*it).getNhl().getNextHopList().begin();
+ nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
+ {
+ //remove entry from NDN-FIB
+ }
+ cancelScheduledFeExpiringEvent(pnlsr, (*it).getFeExpiringEventId());
+ fibTable.erase(it);
+ }
+ }
+
+
+ void
+ Fib::updateFib(Nlsr& pnlsr,string name, Nhl& nextHopList, int maxFacesPerPrefix)
+ {
+ int startFace=0;
+ int endFace=getNumberOfFacesForName(nextHopList,maxFacesPerPrefix);
+ std::list<FibEntry >::iterator it = std::find_if( fibTable.begin(),
+ fibTable.end(), bind(&fibEntryNameCompare, _1, name));
+ if( it != fibTable.end() )
+ {
+ nextHopList.sortNhl();
+ if ( !(*it).isEqualNextHops(nextHopList) )
+ {
+ std::list<NextHop>::iterator nhit=nextHopList.getNextHopList().begin();
+ (*it).getNhl().addNextHop((*nhit));
+ removeFibEntryHop((*it).getNhl(),(*nhit).getConnectingFace());
+ startFace++;
+ nhit++;
+ for( int i=startFace; i< endFace; nhit++,i++)
+ {
+ (*it).getNhl().addNextHop((*nhit));
+ }
+ (*it).setTimeToRefresh(fibEntryRefreshTime);
+ }
+ (*it).getNhl().sortNhl();
+ cancelScheduledFeExpiringEvent(pnlsr, (*it).getFeExpiringEventId());
+ (*it).setFeSeqNo((*it).getFeSeqNo()+1);
+ (*it).setFeExpiringEventId(scheduleFibEntryRefreshing(pnlsr,
+ (*it).getName() ,
+ (*it).getFeSeqNo(),fibEntryRefreshTime));
+ //update NDN-FIB
+ }
+ else
+ {
+ nextHopList.sortNhl();
+ FibEntry newEntry(name);
+ std::list<NextHop>::iterator nhit=nextHopList.getNextHopList().begin();
+ for(int i=startFace; i< endFace ; i++)
+ {
+ newEntry.getNhl().addNextHop((*nhit));
+ ++nhit;
+ }
+ newEntry.getNhl().sortNhl();
+ newEntry.setTimeToRefresh(fibEntryRefreshTime);
+ newEntry.setFeSeqNo(1);
+ fibTable.push_back(newEntry);
+ //cancelScheduledFeExpiringEvent(pnlsr, newEntry().getFeExpiringEventId());
+ //Update NDN-FIB
+ }
+ }
+
+
+
+ void Fib::cleanFib(Nlsr& pnlsr)
+ {
+ for( std::list<FibEntry >::iterator it=fibTable.begin(); it != fibTable.end();
+ ++it)
+ {
+ for(std::list<NextHop>::iterator nhit=(*it).getNhl().getNextHopList().begin();
+ nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
+ {
+ cancelScheduledFeExpiringEvent(pnlsr,(*it).getFeExpiringEventId());
+ //remove entry from NDN-FIB
+ }
+ }
+ if ( fibTable.size() > 0 )
+ {
+ fibTable.clear();
+ }
+ }
+
+
+ void
+ Fib::removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId)
+ {
+ for( std::list<NextHop >::iterator it=nl.getNextHopList().begin();
+ it != nl.getNextHopList().end(); ++it)
+ {
+ if ( (*it).getConnectingFace() != doNotRemoveHopFaceId )
+ {
+ nl.getNextHopList().erase(it);
+ }
+ }
+ }
+
+
+ int
+ Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
+ {
+ int endFace=0;
+ if((maxFacesPerPrefix == 0) || (nextHopList.getNhlSize() <= maxFacesPerPrefix))
+ {
+ return nextHopList.getNhlSize();
+ }
+ else
+ {
+ return maxFacesPerPrefix;
+ }
+ return endFace;
+ }
+
+ void
+ Fib::printFib()
+ {
+ cout<<"-------------------FIB-----------------------------"<<endl;
+ for(std::list<FibEntry>::iterator it = fibTable.begin(); it!=fibTable.end();
+ ++it)
+ {
+ cout<<(*it);
+ }
+ }
+
+} //namespace nlsr
diff --git a/src/route/nlsr_fib.hpp b/src/route/nlsr_fib.hpp
new file mode 100644
index 0000000..d93d972
--- /dev/null
+++ b/src/route/nlsr_fib.hpp
@@ -0,0 +1,48 @@
+#ifndef NLSR_FIB_HPP
+#define NLSR_FIB_HPP
+
+#include <list>
+#include "nlsr_fe.hpp"
+
+namespace nlsr
+{
+
+ class Nlsr;
+
+ using namespace std;
+ using namespace ndn;
+
+ class Fib
+ {
+ public:
+ Fib()
+ {
+ }
+
+ void removeFromFib(Nlsr& pnlsr, string name);
+ void updateFib(Nlsr& pnlsr, string name, Nhl& nextHopList,
+ int maxFacesPerPrefix);
+ void cleanFib(Nlsr& pnlsr);
+ void setFibEntryRefreshTime(int fert)
+ {
+ fibEntryRefreshTime=fert;
+ }
+
+ void printFib();
+
+ private:
+ void removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId);
+ int getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix);
+ ndn::EventId
+ scheduleFibEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
+ int refreshTime);
+ void cancelScheduledFeExpiringEvent(Nlsr& pnlsr, EventId eid);
+ void refreshFibEntry(string name, int feSeqNum);
+
+ private:
+ std::list<FibEntry> fibTable;
+ int fibEntryRefreshTime;
+ };
+
+}//namespace nlsr
+#endif
diff --git a/src/route/nlsr_map.cpp b/src/route/nlsr_map.cpp
new file mode 100644
index 0000000..47b02ec
--- /dev/null
+++ b/src/route/nlsr_map.cpp
@@ -0,0 +1,124 @@
+#include<iostream>
+#include<list>
+
+#include "nlsr.hpp"
+#include "nlsr_adjacent.hpp"
+#include "nlsr_lsa.hpp"
+#include "nlsr_lsdb.hpp"
+#include "nlsr_map.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ ostream&
+ operator<<(ostream& os, MapEntry& mpe)
+ {
+ os<<"MapEntry: ( Router: "<<mpe.getRouter()<<" Mapping No: ";
+ os<<mpe.getMappingNumber()<<" )"<<endl;
+ return os;
+ }
+
+ static bool
+ mapEntryCompareByRouter(MapEntry& mpe1, string& rtrName)
+ {
+ return mpe1.getRouter()==rtrName;
+ }
+
+ static bool
+ mapEntryCompareByMappingNo(MapEntry& mpe1, int mappingNo)
+ {
+ return mpe1.getMappingNumber()==mappingNo;
+ }
+
+ void
+ Map::addMapElement(string& rtrName)
+ {
+ MapEntry me(rtrName,mappingIndex);
+ if ( addMapElement(me) )
+ {
+ mappingIndex++;
+ }
+ }
+
+ bool
+ Map::addMapElement(MapEntry& mpe)
+ {
+ //cout << mpe;
+ std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
+ rMap.end(),
+ bind(&mapEntryCompareByRouter, _1, mpe.getRouter()));
+ if ( it == rMap.end() )
+ {
+ rMap.push_back(mpe);
+ return true;
+ }
+ return false;
+ }
+
+ string
+ Map::getRouterNameByMappingNo(int mn)
+ {
+ std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
+ rMap.end(),
+ bind(&mapEntryCompareByMappingNo, _1, mn));
+ if ( it != rMap.end() )
+ {
+ return (*it).getRouter();
+ }
+ return "";
+ }
+
+ int
+ Map::getMappingNoByRouterName(string& rName)
+ {
+ std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
+ rMap.end(),
+ bind(&mapEntryCompareByRouter, _1, rName));
+ if ( it != rMap.end() )
+ {
+ return (*it).getMappingNumber();
+ }
+ return -1;
+ }
+
+ void
+ Map::createMapFromAdjLsdb(Nlsr& pnlsr)
+ {
+ std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
+ for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
+ it!= adjLsdb.end() ; it++)
+ {
+ string linkStartRouter=(*it).getOrigRouter();
+ addMapElement(linkStartRouter);
+ std::list<Adjacent> adl=(*it).getAdl().getAdjList();
+ for( std::list<Adjacent>::iterator itAdl=adl.begin();
+ itAdl!= adl.end() ; itAdl++)
+ {
+ string linkEndRouter=(*itAdl).getAdjacentName();
+ addMapElement(linkEndRouter);
+ }
+ }
+ }
+
+ void
+ Map::resetMap()
+ {
+ rMap.clear();
+ mappingIndex=0;
+ }
+
+ ostream&
+ operator<<(ostream& os, Map& rMap)
+ {
+ os<<"---------------Map----------------------"<<endl;
+ std::list< MapEntry > ml=rMap.getMapList();
+ for( std::list<MapEntry>::iterator it=ml.begin(); it!= ml.end() ; it++)
+ {
+ os<< (*it);
+ }
+ return os;
+ }
+
+} //namespace nlsr
diff --git a/src/route/nlsr_map.hpp b/src/route/nlsr_map.hpp
new file mode 100644
index 0000000..0352d1d
--- /dev/null
+++ b/src/route/nlsr_map.hpp
@@ -0,0 +1,88 @@
+#ifndef NLSR_MAP_HPP
+#define NLSR_MAP_HPP
+
+#include <iostream>
+#include <list>
+
+#include <ndn-cpp-dev/face.hpp>
+
+namespace nlsr
+{
+
+ class Nlsr;
+
+ using namespace std;
+
+ class MapEntry
+ {
+ public:
+ MapEntry()
+ : router()
+ , mappingNumber(-1)
+ {
+ }
+
+ ~MapEntry()
+ {
+ }
+
+ MapEntry(string rtr, int mn)
+ {
+ router=rtr;
+ mappingNumber=mn;
+ }
+
+ string getRouter()
+ {
+ return router;
+ }
+
+ int getMappingNumber()
+ {
+ return mappingNumber;
+ }
+ private:
+ string router;
+ int mappingNumber;
+ };
+
+ ostream&
+ operator<<(ostream& os, MapEntry& mpe);
+
+ class Map
+ {
+ public:
+ Map()
+ : mappingIndex(0)
+ {
+ }
+
+
+ void addMapElement(string& rtrName);
+ void createMapFromAdjLsdb(Nlsr& pnlsr);
+ string getRouterNameByMappingNo(int mn);
+ int getMappingNoByRouterName(string& rName);
+ void resetMap();
+ std::list< MapEntry >& getMapList()
+ {
+ return rMap;
+ }
+
+ int getMapSize()
+ {
+ return rMap.size();
+ }
+
+
+ private:
+ bool addMapElement(MapEntry& mpe);
+
+ int mappingIndex;
+ std::list< MapEntry > rMap;
+ };
+
+ ostream&
+ operator<<(ostream& os, Map& rMap);
+
+} // namespace nlsr
+#endif
diff --git a/src/route/nlsr_nexthop.cpp b/src/route/nlsr_nexthop.cpp
new file mode 100644
index 0000000..e58b23c
--- /dev/null
+++ b/src/route/nlsr_nexthop.cpp
@@ -0,0 +1,13 @@
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+ ostream&
+ operator<<(ostream& os, NextHop& nh)
+ {
+ os<<"Face: "<<nh.getConnectingFace()<<" Route Cost: "<<nh.getRouteCost();
+ return os;
+ }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_nexthop.hpp b/src/route/nlsr_nexthop.hpp
new file mode 100644
index 0000000..1361d52
--- /dev/null
+++ b/src/route/nlsr_nexthop.hpp
@@ -0,0 +1,56 @@
+#ifndef NLSR_NEXTHOP_HPP
+#define NLSR_NEXTHOP_HPP
+
+#include<iostream>
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ class NextHop
+ {
+ public:
+ NextHop()
+ : connectingFace(0)
+ , routeCost(0)
+ {
+ }
+
+ NextHop(int cf, double rc)
+ {
+ connectingFace=cf;
+ routeCost=rc;
+ }
+
+ int getConnectingFace()
+ {
+ return connectingFace;
+ }
+
+ void setConnectingFace(int cf)
+ {
+ connectingFace=cf;
+ }
+
+ double getRouteCost()
+ {
+ return routeCost;
+ }
+
+ void setRouteCost(double rc)
+ {
+ routeCost=rc;
+ }
+ private:
+ int connectingFace;
+ double routeCost;
+ };
+
+
+ ostream&
+ operator<<(ostream& os, NextHop& nh);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_nhl.cpp b/src/route/nlsr_nhl.cpp
new file mode 100644
index 0000000..2aaa2a6
--- /dev/null
+++ b/src/route/nlsr_nhl.cpp
@@ -0,0 +1,90 @@
+#include <iostream>
+
+#include "nlsr_nhl.hpp"
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ static bool
+ nexthopCompare(NextHop& nh1, NextHop& nh2)
+ {
+ return nh1.getConnectingFace()==nh2.getConnectingFace();
+ }
+
+ static bool
+ nexthopRemoveCompare(NextHop& nh1, NextHop& nh2)
+ {
+ return (nh1.getConnectingFace()==nh2.getConnectingFace() &&
+ nh1.getRouteCost() == nh2.getRouteCost()) ;
+ }
+
+ static bool
+ nextHopSortingComparator(NextHop& nh1, NextHop& nh2)
+ {
+ return nh1.getRouteCost() < nh2.getRouteCost();
+ }
+
+ /**
+ Add next hop to the Next Hop list
+ If next hop is new it is added
+ If next hop already exists in next
+ hop list then updates the route
+ cost with new next hop's route cost
+ */
+
+ void
+ Nhl::addNextHop(NextHop& nh)
+ {
+ std::list<NextHop >::iterator it = std::find_if( nexthopList.begin(),
+ nexthopList.end(),
+ bind(&nexthopCompare, _1, nh));
+ if ( it == nexthopList.end() )
+ {
+ nexthopList.push_back(nh);
+ }
+ if ( (*it).getRouteCost() > nh.getRouteCost() )
+ {
+ (*it).setRouteCost(nh.getRouteCost());
+ }
+ }
+
+ /**
+ Remove a next hop only if both next hop face and route cost are same
+
+ */
+
+ void
+ Nhl::removeNextHop(NextHop &nh)
+ {
+ std::list<NextHop >::iterator it = std::find_if( nexthopList.begin(),
+ nexthopList.end(),
+ bind(&nexthopRemoveCompare, _1, nh));
+ if ( it != nexthopList.end() )
+ {
+ nexthopList.erase(it);
+ }
+ }
+
+ void
+ Nhl::sortNhl()
+ {
+ nexthopList.sort(nextHopSortingComparator);
+ }
+
+ ostream&
+ operator<<(ostream& os, Nhl& nhl)
+ {
+ std::list< NextHop > nexthopList = nhl.getNextHopList();
+ int i=1;
+ for( std::list<NextHop>::iterator it=nexthopList.begin();
+ it!= nexthopList.end() ; it++,i++)
+ {
+ os << "Nexthop "<<i<<": "<<(*it)<<endl;
+ }
+ return os;
+ }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_nhl.hpp b/src/route/nlsr_nhl.hpp
new file mode 100644
index 0000000..9f6bd76
--- /dev/null
+++ b/src/route/nlsr_nhl.hpp
@@ -0,0 +1,54 @@
+#ifndef NLSR_NHL_HPP
+#define NLSR_NHL_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include "nlsr_adjacent.hpp"
+#include <list>
+#include <iostream>
+
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ class Nhl
+ {
+ public:
+ Nhl()
+ {
+ }
+
+ ~Nhl()
+ {
+ }
+ void addNextHop(NextHop &nh);
+ void removeNextHop(NextHop &nh);
+ void sortNhl();
+ int getNhlSize()
+ {
+ return nexthopList.size();
+ }
+ void resetNhl()
+ {
+ if (nexthopList.size() > 0 )
+ {
+ nexthopList.clear();
+ }
+ }
+ std::list< NextHop >& getNextHopList()
+ {
+ return nexthopList;
+ }
+
+ private:
+ std::list< NextHop > nexthopList;
+ };
+
+ ostream&
+ operator<<(ostream& os, Nhl& nhl);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_npt.cpp b/src/route/nlsr_npt.cpp
new file mode 100644
index 0000000..9c4d4cb
--- /dev/null
+++ b/src/route/nlsr_npt.cpp
@@ -0,0 +1,142 @@
+#include <list>
+#include <utility>
+#include <algorithm>
+
+#include "nlsr_npt.hpp"
+#include "nlsr_npte.hpp"
+#include "nlsr.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ static bool
+ npteCompare(Npte& npte, string& name)
+ {
+ return npte.getNamePrefix()==name;
+ }
+
+// Following two methods will update FIB with response to change in NPT
+
+ void
+ Npt::addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+ {
+ std::list<Npte >::iterator it = std::find_if( npteList.begin(),
+ npteList.end(), bind(&npteCompare, _1, name));
+ if ( it == npteList.end() )
+ {
+ Npte newEntry( name);
+ newEntry.addRoutingTableEntry(rte);
+ newEntry.generateNhlfromRteList();
+ npteList.push_back(newEntry);
+ // update FIB here with nhl list newEntry.getNhl()
+ pnlsr.getFib().updateFib(pnlsr, name,newEntry.getNhl(),
+ pnlsr.getConfParameter().getMaxFacesPerPrefix());
+ }
+ else
+ {
+ (*it).addRoutingTableEntry(rte);
+ (*it).generateNhlfromRteList();
+ // update FIB here with nhl list from (*it).getNhl()
+ pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl() ,
+ pnlsr.getConfParameter().getMaxFacesPerPrefix());
+ }
+ }
+
+ void
+ Npt::removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+ {
+ std::list<Npte >::iterator it = std::find_if( npteList.begin(),
+ npteList.end(), bind(&npteCompare, _1, name));
+ if ( it != npteList.end() )
+ {
+ string destRouter=rte.getDestination();
+ (*it).removeRoutingTableEntry(rte);
+ if ( ((*it).getRteListSize() == 0 ) &&
+ (!pnlsr.getLsdb().doesLsaExist(destRouter+"/1",1) ) &&
+ (!pnlsr.getLsdb().doesLsaExist(destRouter+"/2",2) ) &&
+ (!pnlsr.getLsdb().doesLsaExist(destRouter+"/3",3) ) )
+ {
+ npteList.erase(it); // remove entry from NPT
+ // remove FIB entry with this name
+ pnlsr.getFib().removeFromFib(pnlsr,name);
+ }
+ else
+ {
+ (*it).generateNhlfromRteList();
+ // update FIB entry with new NHL
+ pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl(),
+ pnlsr.getConfParameter().getMaxFacesPerPrefix());
+ }
+ }
+ }
+
+
+ void
+ Npt::addNpte(string name, string destRouter, Nlsr& pnlsr)
+ {
+ std::pair<RoutingTableEntry& , bool> rteCheck=
+ pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
+ if(rteCheck.second)
+ {
+ addNpte(name,rteCheck.first,pnlsr);
+ }
+ else
+ {
+ RoutingTableEntry rte(destRouter);
+ addNpte(name, rte,pnlsr);
+ }
+ }
+
+ void
+ Npt::removeNpte(string name, string destRouter, Nlsr& pnlsr)
+ {
+ std::pair<RoutingTableEntry& , bool> rteCheck=
+ pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
+ if(rteCheck.second)
+ {
+ removeNpte(name,rteCheck.first,pnlsr);
+ }
+ else
+ {
+ RoutingTableEntry rte(destRouter);
+ removeNpte(name, rte,pnlsr);
+ }
+ }
+
+ void
+ Npt::updateNptWithNewRoute(Nlsr& pnlsr)
+ {
+ for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
+ {
+ std::list<RoutingTableEntry> rteList=(*it).getRteList();
+ for(std::list<RoutingTableEntry >::iterator rteit=rteList.begin();
+ rteit !=rteList.end(); ++rteit)
+ {
+ std::pair<RoutingTableEntry& , bool> rteCheck=
+ pnlsr.getRoutingTable().findRoutingTableEntry((*rteit).getDestination());
+ if(rteCheck.second)
+ {
+ addNpte((*it).getNamePrefix(),rteCheck.first,pnlsr);
+ }
+ else
+ {
+ RoutingTableEntry rte((*rteit).getDestination());
+ addNpte((*it).getNamePrefix(), rte,pnlsr);
+ }
+ }
+ }
+ }
+
+ void
+ Npt::printNpt()
+ {
+ cout<<"----------------NPT----------------------"<<endl;
+ for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
+ {
+ cout <<(*it)<<endl;
+ }
+ }
+
+}
diff --git a/src/route/nlsr_npt.hpp b/src/route/nlsr_npt.hpp
new file mode 100644
index 0000000..f4ddbf9
--- /dev/null
+++ b/src/route/nlsr_npt.hpp
@@ -0,0 +1,34 @@
+#ifndef NLSR_NPT_HPP
+#define NLSR_NPT_HPP
+
+#include <list>
+#include "nlsr_npte.hpp"
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ class Nlsr;
+
+ class Npt
+ {
+ public:
+ Npt()
+ {
+ }
+ void addNpte(string name, string destRouter, Nlsr& pnlsr);
+ void removeNpte(string name, string destRouter, Nlsr& pnlsr);
+ void updateNptWithNewRoute(Nlsr& pnlsr);
+ void printNpt();
+ private:
+ void addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+ void removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+ private:
+ std::list<Npte> npteList;
+ };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_npte.cpp b/src/route/nlsr_npte.cpp
new file mode 100644
index 0000000..60013ff
--- /dev/null
+++ b/src/route/nlsr_npte.cpp
@@ -0,0 +1,83 @@
+#include <list>
+#include <utility>
+#include "nlsr_npte.hpp"
+#include "nlsr_rte.hpp"
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ void
+ Npte::generateNhlfromRteList()
+ {
+ nhl.resetNhl();
+ for( std::list<RoutingTableEntry>::iterator it=rteList.begin();
+ it != rteList.end(); ++it )
+ {
+ for(std::list< NextHop >::iterator nhit=(*it).getNhl().getNextHopList().begin();
+ nhit != (*it).getNhl().getNextHopList().end(); ++nhit)
+ {
+ nhl.addNextHop((*nhit));
+ }
+ }
+ }
+
+
+
+ static bool
+ rteCompare(RoutingTableEntry& rte, string& destRouter)
+ {
+ return rte.getDestination()==destRouter;
+ }
+
+ void
+ Npte::removeRoutingTableEntry(RoutingTableEntry& rte)
+ {
+ std::list<RoutingTableEntry >::iterator it = std::find_if( rteList.begin(),
+ rteList.end(),
+ bind(&rteCompare, _1, rte.getDestination()));
+ if ( it != rteList.end() )
+ {
+ rteList.erase(it);
+ }
+ }
+
+ void
+ Npte::addRoutingTableEntry(RoutingTableEntry &rte)
+ {
+ std::list<RoutingTableEntry >::iterator it = std::find_if( rteList.begin(),
+ rteList.end(),
+ bind(&rteCompare, _1, rte.getDestination()));
+ if ( it == rteList.end() )
+ {
+ rteList.push_back(rte);
+ }
+ else
+ {
+ (*it).getNhl().resetNhl(); // reseting existing routing table's next hop
+ for(std::list< NextHop >::iterator nhit=rte.getNhl().getNextHopList().begin();
+ nhit != rte.getNhl().getNextHopList().end(); ++nhit)
+ {
+ (*it).getNhl().addNextHop((*nhit));
+ }
+ }
+ }
+
+//debugging purpose
+ ostream&
+ operator<<(ostream& os, Npte& npte)
+ {
+ os<<"Name: "<<npte.getNamePrefix()<<endl;
+ std::list<RoutingTableEntry> rteList=npte.getRteList();
+ for(std::list<RoutingTableEntry >::iterator it=rteList.begin();
+ it !=rteList.end(); ++it)
+ {
+ cout<<(*it);
+ }
+ os<<npte.getNhl();
+ return os;
+ }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_npte.hpp b/src/route/nlsr_npte.hpp
new file mode 100644
index 0000000..e64328c
--- /dev/null
+++ b/src/route/nlsr_npte.hpp
@@ -0,0 +1,61 @@
+#ifndef NLSR_NPTE_HPP
+#define NLSR_NPTE_HPP
+
+#include <list>
+#include <utility>
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ class Npte
+ {
+ public:
+ Npte()
+ : namePrefix()
+ , nhl()
+ {
+ }
+ Npte(string np)
+ : nhl()
+ {
+ namePrefix=np;
+ }
+
+ string getNamePrefix()
+ {
+ return namePrefix;
+ }
+
+ std::list<RoutingTableEntry>& getRteList()
+ {
+ return rteList;
+ }
+
+ int getRteListSize()
+ {
+ return rteList.size();
+ }
+
+ Nhl& getNhl()
+ {
+ return nhl;
+ }
+ void generateNhlfromRteList();
+ void removeRoutingTableEntry(RoutingTableEntry& rte);
+ void addRoutingTableEntry(RoutingTableEntry &rte);
+
+ private:
+ string namePrefix;
+ std::list<RoutingTableEntry> rteList;
+ Nhl nhl;
+ };
+
+ ostream&
+ operator<<(ostream& os, Npte& npte);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rt.cpp b/src/route/nlsr_rt.cpp
new file mode 100644
index 0000000..f9923f2
--- /dev/null
+++ b/src/route/nlsr_rt.cpp
@@ -0,0 +1,231 @@
+#include<iostream>
+#include<string>
+#include<list>
+
+#include "nlsr_rt.hpp"
+#include "nlsr.hpp"
+#include "nlsr_map.hpp"
+#include "nlsr_rtc.hpp"
+#include "nlsr_rte.hpp"
+#include "nlsr_npt.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ void
+ RoutingTable::calculate(Nlsr& pnlsr)
+ {
+ //debugging purpose
+ pnlsr.getNpt().printNpt();
+ pnlsr.getLsdb().printAdjLsdb();
+ pnlsr.getLsdb().printCorLsdb();
+ pnlsr.getLsdb().printNameLsdb();
+ if ( pnlsr.getIsRoutingTableCalculating() == 0 )
+ {
+ pnlsr.setIsRoutingTableCalculating(1); //setting routing table calculation
+ if ( pnlsr.getLsdb().doesLsaExist(
+ pnlsr.getConfParameter().getRouterPrefix()+"/"+"2",2) )
+ {
+ if(pnlsr.getIsBuildAdjLsaSheduled() != 1)
+ {
+ cout<<"CLearing old routing table ....."<<endl;
+ clearRoutingTable();
+ clearDryRoutingTable(); // for dry run options
+ // calculate Link State routing
+ if( (pnlsr.getConfParameter().getIsHyperbolicCalc() == 0 )
+ || (pnlsr.getConfParameter().getIsHyperbolicCalc() == 2 ) )
+ {
+ calculateLsRoutingTable(pnlsr);
+ }
+ //calculate hyperbolic routing
+ if ( pnlsr.getConfParameter().getIsHyperbolicCalc() == 1 )
+ {
+ calculateHypRoutingTable(pnlsr);
+ }
+ //calculate dry hyperbolic routing
+ if ( pnlsr.getConfParameter().getIsHyperbolicCalc() == 2 )
+ {
+ calculateHypDryRoutingTable(pnlsr);
+ }
+ //need to update NPT here
+ pnlsr.getNpt().updateNptWithNewRoute(pnlsr);
+ //debugging purpose
+ printRoutingTable();
+ pnlsr.getNpt().printNpt();
+ pnlsr.getFib().printFib();
+ //debugging purpose end
+ }
+ else
+ {
+ cout<<"Adjacency building is scheduled, so ";
+ cout<<"routing table can not be calculated :("<<endl;
+ }
+ }
+ else
+ {
+ cout<<"No Adj LSA of router itself,";
+ cout<< " so Routing table can not be calculated :("<<endl;
+ clearRoutingTable();
+ clearDryRoutingTable(); // for dry run options
+ // need to update NPT here
+ pnlsr.getNpt().updateNptWithNewRoute(pnlsr);
+ //debugging purpose
+ printRoutingTable();
+ pnlsr.getNpt().printNpt();
+ pnlsr.getFib().printFib();
+ //debugging purpose end
+ }
+ pnlsr.setIsRouteCalculationScheduled(0); //clear scheduled flag
+ pnlsr.setIsRoutingTableCalculating(0); //unsetting routing table calculation
+ }
+ else
+ {
+ scheduleRoutingTableCalculation(pnlsr);
+ }
+ }
+
+
+ void
+ RoutingTable::calculateLsRoutingTable(Nlsr& pnlsr)
+ {
+ cout<<"RoutingTable::calculateLsRoutingTable Called"<<endl;
+ Map vMap;
+ vMap.createMapFromAdjLsdb(pnlsr);
+ int numOfRouter=vMap.getMapSize();
+ LinkStateRoutingTableCalculator lsrtc(numOfRouter);
+ lsrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
+ }
+
+ void
+ RoutingTable::calculateHypRoutingTable(Nlsr& pnlsr)
+ {
+ Map vMap;
+ vMap.createMapFromAdjLsdb(pnlsr);
+ int numOfRouter=vMap.getMapSize();
+ HypRoutingTableCalculator hrtc(numOfRouter,0);
+ hrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
+ }
+
+ void
+ RoutingTable::calculateHypDryRoutingTable(Nlsr& pnlsr)
+ {
+ Map vMap;
+ vMap.createMapFromAdjLsdb(pnlsr);
+ int numOfRouter=vMap.getMapSize();
+ HypRoutingTableCalculator hrtc(numOfRouter,1);
+ hrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
+ }
+
+ void
+ RoutingTable::scheduleRoutingTableCalculation(Nlsr& pnlsr)
+ {
+ if ( pnlsr.getIsRouteCalculationScheduled() != 1 )
+ {
+ pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(15),
+ ndn::bind(&RoutingTable::calculate,this,boost::ref(pnlsr)));
+ pnlsr.setIsRouteCalculationScheduled(1);
+ }
+ }
+
+ static bool
+ routingTableEntryCompare(RoutingTableEntry& rte, string& destRouter)
+ {
+ return rte.getDestination()==destRouter;
+ }
+
+// function related to manipulation of routing table
+ void
+ RoutingTable::addNextHop(string destRouter, NextHop& nh)
+ {
+ std::pair<RoutingTableEntry&, bool> rte=findRoutingTableEntry(destRouter);
+ if( !rte.second )
+ {
+ RoutingTableEntry rte(destRouter);
+ rte.getNhl().addNextHop(nh);
+ rTable.push_back(rte);
+ }
+ else
+ {
+ (rte.first).getNhl().addNextHop(nh);
+ }
+ }
+
+ std::pair<RoutingTableEntry&, bool>
+ RoutingTable::findRoutingTableEntry(string destRouter)
+ {
+ std::list<RoutingTableEntry >::iterator it = std::find_if( rTable.begin(),
+ rTable.end(),
+ bind(&routingTableEntryCompare, _1, destRouter));
+ if ( it != rTable.end() )
+ {
+ return std::make_pair(boost::ref((*it)),true);
+ }
+ RoutingTableEntry rteEmpty;
+ return std::make_pair(boost::ref(rteEmpty),false);
+ }
+
+ void
+ RoutingTable::printRoutingTable()
+ {
+ cout<<"---------------Routing Table------------------"<<endl;
+ for(std::list<RoutingTableEntry>::iterator it=rTable.begin() ;
+ it != rTable.end(); ++it)
+ {
+ cout<<(*it)<<endl;
+ }
+ }
+
+
+//function related to manipulation of dry routing table
+ void
+ RoutingTable::addNextHopToDryTable(string destRouter, NextHop& nh)
+ {
+ std::list<RoutingTableEntry >::iterator it = std::find_if( dryTable.begin(),
+ dryTable.end(),
+ bind(&routingTableEntryCompare, _1, destRouter));
+ if ( it == dryTable.end() )
+ {
+ RoutingTableEntry rte(destRouter);
+ rte.getNhl().addNextHop(nh);
+ dryTable.push_back(rte);
+ }
+ else
+ {
+ (*it).getNhl().addNextHop(nh);
+ }
+ }
+
+ void
+ RoutingTable::printDryRoutingTable()
+ {
+ cout<<"--------Dry Run's Routing Table--------------"<<endl;
+ for(std::list<RoutingTableEntry>::iterator it=dryTable.begin() ;
+ it != dryTable.end(); ++it)
+ {
+ cout<<(*it)<<endl;
+ }
+ }
+
+
+ void
+ RoutingTable::clearRoutingTable()
+ {
+ if( rTable.size() > 0 )
+ {
+ rTable.clear();
+ }
+ }
+
+ void
+ RoutingTable::clearDryRoutingTable()
+ {
+ if (dryTable.size()>0 )
+ {
+ dryTable.clear();
+ }
+ }
+
+}//namespace nlsr
+
diff --git a/src/route/nlsr_rt.hpp b/src/route/nlsr_rt.hpp
new file mode 100644
index 0000000..fb9a060
--- /dev/null
+++ b/src/route/nlsr_rt.hpp
@@ -0,0 +1,50 @@
+#ifndef NLSR_RT_HPP
+#define NLSR_RT_HPP
+
+#include<iostream>
+#include<utility>
+#include<string>
+
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+ class Nlsr;
+ class NextHop;
+
+ using namespace std;
+
+ class RoutingTable
+ {
+ public:
+ RoutingTable()
+ : NO_NEXT_HOP(-12345)
+ {
+ }
+ void calculate(Nlsr& pnlsr);
+ void addNextHop(string destRouter, NextHop& nh);
+ void printRoutingTable();
+
+ void addNextHopToDryTable(string destRouter, NextHop& nh);
+ void printDryRoutingTable();
+ std::pair<RoutingTableEntry&, bool> findRoutingTableEntry(string destRouter);
+ void scheduleRoutingTableCalculation(Nlsr& pnlsr);
+
+ private:
+ void calculateLsRoutingTable(Nlsr& pnlsr);
+ void calculateHypRoutingTable(Nlsr& pnlsr);
+ void calculateHypDryRoutingTable(Nlsr&pnlsr);
+
+ void clearRoutingTable();
+ void clearDryRoutingTable();
+
+ const int NO_NEXT_HOP;
+
+ std::list< RoutingTableEntry > rTable;
+ std::list< RoutingTableEntry > dryTable;
+ };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rtc.cpp b/src/route/nlsr_rtc.cpp
new file mode 100644
index 0000000..acdf6d5
--- /dev/null
+++ b/src/route/nlsr_rtc.cpp
@@ -0,0 +1,504 @@
+#include <iostream>
+#include <cmath>
+#include "nlsr_lsdb.hpp"
+#include "nlsr_rtc.hpp"
+#include "nlsr_map.hpp"
+#include "nlsr_lsa.hpp"
+#include "nlsr_nexthop.hpp"
+#include "nlsr.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ void
+ RoutingTableCalculator::allocateAdjMatrix()
+ {
+ adjMatrix = new double*[numOfRouter];
+ for(int i = 0; i < numOfRouter; ++i)
+ {
+ adjMatrix[i] = new double[numOfRouter];
+ }
+ }
+
+ void
+ RoutingTableCalculator::initMatrix()
+ {
+ for(int i=0; i<numOfRouter; i++)
+ {
+ for(int j=0; j<numOfRouter; j++)
+ adjMatrix[i][j]=0;
+ }
+ }
+
+ void
+ RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
+ {
+ std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
+ for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
+ it!= adjLsdb.end() ; it++)
+ {
+ string linkStartRouter=(*it).getOrigRouter();
+ int row=pMap.getMappingNoByRouterName(linkStartRouter);
+ std::list<Adjacent> adl=(*it).getAdl().getAdjList();
+ for( std::list<Adjacent>::iterator itAdl=adl.begin();
+ itAdl!= adl.end() ; itAdl++)
+ {
+ string linkEndRouter=(*itAdl).getAdjacentName();
+ int col=pMap.getMappingNoByRouterName(linkEndRouter);
+ double cost=(*itAdl).getLinkCost();
+ if ( (row >= 0 && row<numOfRouter) && (col >= 0 && col<numOfRouter) )
+ {
+ adjMatrix[row][col]=cost;
+ }
+ }
+ }
+ }
+
+ void
+ RoutingTableCalculator::printAdjMatrix()
+ {
+ for(int i=0; i<numOfRouter; i++)
+ {
+ for(int j=0; j<numOfRouter; j++)
+ printf("%f ",adjMatrix[i][j]);
+ printf("\n");
+ }
+ }
+
+ void
+ RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
+ {
+ for ( int i = 0; i < numOfRouter; i++ )
+ {
+ if ( i == link )
+ {
+ adjMatrix[source][i]=linkCost;
+ }
+ else
+ {
+ adjMatrix[source][i]=0;
+ }
+ }
+ }
+
+ int
+ RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
+ {
+ int noLink=0;
+ for(int i=0; i<numOfRouter; i++)
+ {
+ if ( adjMatrix[sRouter][i] > 0 )
+ {
+ noLink++;
+ }
+ }
+ return noLink;
+ }
+
+ void
+ RoutingTableCalculator::getLinksFromAdjMatrix(int *links,
+ double *linkCosts, int source)
+ {
+ int j=0;
+ for (int i=0; i <numOfRouter; i++)
+ {
+ if ( adjMatrix[source][i] > 0 )
+ {
+ links[j]=i;
+ linkCosts[j]=adjMatrix[source][i];
+ j++;
+ }
+ }
+ }
+
+ void
+ RoutingTableCalculator::freeAdjMatrix()
+ {
+ for(int i = 0; i < numOfRouter; ++i)
+ {
+ delete [] adjMatrix[i];
+ }
+ delete [] adjMatrix;
+ }
+
+
+ void
+ RoutingTableCalculator::allocateLinks()
+ {
+ links=new int[vNoLink];
+ }
+
+ void RoutingTableCalculator::allocateLinkCosts()
+ {
+ linkCosts=new double[vNoLink];
+ }
+
+
+ void
+ RoutingTableCalculator::freeLinks()
+ {
+ delete [] links;
+ }
+ void
+ RoutingTableCalculator::freeLinksCosts()
+ {
+ delete [] linkCosts;
+ }
+
+ void
+ LinkStateRoutingTableCalculator::calculatePath(Map& pMap,
+ RoutingTable& rt, Nlsr& pnlsr)
+ {
+ cout<<"LinkStateRoutingTableCalculator::calculatePath Called"<<endl;
+ allocateAdjMatrix();
+ initMatrix();
+ makeAdjMatrix(pnlsr,pMap);
+ cout<<pMap;
+ printAdjMatrix();
+ string routerName=pnlsr.getConfParameter().getRouterPrefix();
+ int sourceRouter=pMap.getMappingNoByRouterName(routerName);
+ int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
+ allocateParent();
+ allocateDistance();
+ if ( pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1 )
+ {
+ // Single Path
+ doDijkstraPathCalculation(sourceRouter);
+ // print all ls path -- debugging purpose
+ printAllLsPath(sourceRouter);
+ // update routing table
+ addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
+ }
+ else
+ {
+ // Multi Path
+ setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
+ allocateLinks();
+ allocateLinkCosts();
+ getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
+ for (int i=0 ; i < vNoLink; i++)
+ {
+ adjustAdMatrix(sourceRouter,links[i], linkCosts[i]);
+ printAdjMatrix();
+ doDijkstraPathCalculation(sourceRouter);
+ // print all ls path -- debugging purpose
+ printAllLsPath(sourceRouter);
+ //update routing table
+ addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
+ }
+ freeLinks();
+ freeLinksCosts();
+ }
+ freeParent();
+ freeDistance();
+ freeAdjMatrix();
+ }
+
+ void
+ LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
+ {
+ int i;
+ int v,u;
+ int *Q=new int[numOfRouter];
+ int head=0;
+ /* Initiate the Parent */
+ for (i = 0 ; i < numOfRouter; i++)
+ {
+ parent[i]=EMPTY_PARENT;
+ distance[i]=INF_DISTANCE;
+ Q[i]=i;
+ }
+ if ( sourceRouter != NO_MAPPING_NUM )
+ {
+ distance[sourceRouter]=0;
+ sortQueueByDistance(Q,distance,head,numOfRouter);
+ while (head < numOfRouter )
+ {
+ u=Q[head];
+ if(distance[u] == INF_DISTANCE)
+ {
+ break;
+ }
+ for(v=0 ; v <numOfRouter; v++)
+ {
+ if( adjMatrix[u][v] > 0 )
+ {
+ if ( isNotExplored(Q,v,head+1,numOfRouter) )
+ {
+ if( distance[u] + adjMatrix[u][v] < distance[v])
+ {
+ distance[v]=distance[u] + adjMatrix[u][v] ;
+ parent[v]=u;
+ }
+ }
+ }
+ }
+ head++;
+ sortQueueByDistance(Q,distance,head,numOfRouter);
+ }
+ }
+ delete [] Q;
+ }
+
+ void
+ LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
+ RoutingTable& rt, Map& pMap, int sourceRouter)
+ {
+ cout<<"LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
+ cout<<endl;
+ for(int i=0; i < numOfRouter ; i++)
+ {
+ if ( i!= sourceRouter )
+ {
+ int nextHopRouter=getLsNextHop(i,sourceRouter);
+ double routeCost=distance[i];
+ string nextHopRouterName=pMap.getRouterNameByMappingNo(nextHopRouter);
+ int nxtHopFace=
+ pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
+ cout<<"Dest Router: "<<pMap.getRouterNameByMappingNo(i)<<endl;
+ cout<<"Next hop Router: "<<nextHopRouterName<<endl;
+ cout<<"Next hop Face: "<<nxtHopFace<<endl;
+ cout<<"Route Cost: "<<routeCost<<endl;
+ cout<<endl;
+ // Add next hop to routing table
+ NextHop nh(nxtHopFace,routeCost);
+ rt.addNextHop(pMap.getRouterNameByMappingNo(i),nh);
+ }
+ }
+ }
+
+ int
+ LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
+ {
+ int nextHop;
+ while ( parent[dest] != EMPTY_PARENT )
+ {
+ nextHop=dest;
+ dest=parent[dest];
+ }
+ if ( dest != source )
+ {
+ nextHop=NO_NEXT_HOP;
+ }
+ return nextHop;
+ }
+
+ void
+ LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
+ {
+ cout<<"LinkStateRoutingTableCalculator::printAllLsPath Called"<<endl;
+ cout<<"Source Router: "<<sourceRouter<<endl;
+ for(int i=0; i < numOfRouter ; i++)
+ {
+ if ( i!= sourceRouter )
+ {
+ printLsPath(i);
+ cout<<endl;
+ }
+ }
+ }
+
+ void
+ LinkStateRoutingTableCalculator::printLsPath(int destRouter)
+ {
+ if (parent[destRouter] != EMPTY_PARENT )
+ {
+ printLsPath(parent[destRouter]);
+ }
+ cout<<" "<<destRouter;
+ }
+
+ void
+ LinkStateRoutingTableCalculator::sortQueueByDistance(int *Q,
+ double *dist,int start,int element)
+ {
+ for ( int i=start ; i < element ; i ++)
+ {
+ for( int j=i+1; j<element; j ++)
+ {
+ if (dist[Q[j]] < dist[Q[i]])
+ {
+ int tempU=Q[j];
+ Q[j]=Q[i];
+ Q[i]=tempU;
+ }
+ }
+ }
+ }
+
+ int
+ LinkStateRoutingTableCalculator::isNotExplored(int *Q,
+ int u,int start, int element)
+ {
+ int ret=0;
+ for(int i=start; i< element; i++)
+ {
+ if ( Q[i] == u )
+ {
+ ret=1;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ void
+ LinkStateRoutingTableCalculator::allocateParent()
+ {
+ parent=new int[numOfRouter];
+ }
+
+ void
+ LinkStateRoutingTableCalculator::allocateDistance()
+ {
+ distance= new double[numOfRouter];
+ }
+
+ void
+ LinkStateRoutingTableCalculator::freeParent()
+ {
+ delete [] parent;
+ }
+
+ void LinkStateRoutingTableCalculator::freeDistance()
+ {
+ delete [] distance;
+ }
+
+
+
+ void
+ HypRoutingTableCalculator::calculatePath(Map& pMap,
+ RoutingTable& rt, Nlsr& pnlsr)
+ {
+ makeAdjMatrix(pnlsr,pMap);
+ string routerName=pnlsr.getConfParameter().getRouterPrefix();
+ int sourceRouter=pMap.getMappingNoByRouterName(routerName);
+ int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
+ setNoLink(noLink);
+ allocateLinks();
+ allocateLinkCosts();
+ getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
+ for(int i=0 ; i < numOfRouter ; ++i)
+ {
+ int k=0;
+ if ( i != sourceRouter)
+ {
+ allocateLinkFaces();
+ allocateDistanceToNeighbor();
+ allocateDistFromNbrToDest();
+ for(int j=0; j<vNoLink; j++)
+ {
+ string nextHopRouterName=pMap.getRouterNameByMappingNo(links[j]);
+ int nextHopFace=
+ pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
+ double distToNbr=getHyperbolicDistance(pnlsr,pMap,
+ sourceRouter,links[j]);
+ double distToDestFromNbr=getHyperbolicDistance(pnlsr,
+ pMap,links[j],i);
+ if ( distToDestFromNbr >= 0 )
+ {
+ linkFaces[k] = nextHopFace;
+ distanceToNeighbor[k] = distToNbr;
+ distFromNbrToDest[k] = distToDestFromNbr;
+ k++;
+ }
+ }
+ addHypNextHopsToRoutingTable(pnlsr,pMap,rt,k,i);
+ freeLinkFaces();
+ freeDistanceToNeighbor();
+ freeDistFromNbrToDest();
+ }
+ }
+ freeLinks();
+ freeLinksCosts();
+ freeAdjMatrix();
+ }
+
+ void
+ HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
+ RoutingTable& rt, int noFaces, int dest)
+ {
+ for(int i=0 ; i < noFaces ; ++i)
+ {
+ string destRouter=pMap.getRouterNameByMappingNo(dest);
+ NextHop nh(linkFaces[i],distFromNbrToDest[i]);
+ rt.addNextHop(destRouter,nh);
+ if( isDryRun == 1 )
+ {
+ rt.addNextHopToDryTable(destRouter,nh);
+ }
+ }
+ }
+
+ double
+ HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
+ Map& pMap, int src, int dest)
+ {
+ double distance=0.0;
+ string srcRouterKey=pMap.getRouterNameByMappingNo(src)+"/3";
+ string destRouterKey=pMap.getRouterNameByMappingNo(dest)+"/3";
+ double srcRadius=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorRadius();
+ double srcTheta=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorTheta();
+ double destRadius=(pnlsr.getLsdb().getCorLsa(
+ destRouterKey).first).getCorRadius();
+ double destTheta=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorTheta();
+ double diffTheta = fabs (srcTheta - destTheta);
+ if (diffTheta > MATH_PI)
+ {
+ diffTheta = 2 * MATH_PI - diffTheta;
+ }
+ if ( srcRadius != -1 && destRadius != -1 )
+ {
+ if (diffTheta == 0)
+ distance = fabs (srcRadius - destRadius);
+ else
+ distance = acosh((cosh(srcRadius)*cosh(destRadius))-
+ (sinh(srcRadius)*sinh(destRadius)*cos(diffTheta)));
+ }
+ else
+ {
+ distance = -1;
+ }
+ return distance;
+ }
+
+ void
+ HypRoutingTableCalculator::allocateLinkFaces()
+ {
+ linkFaces=new int[vNoLink];
+ }
+
+ void
+ HypRoutingTableCalculator::allocateDistanceToNeighbor()
+ {
+ distanceToNeighbor=new double[vNoLink];
+ }
+
+ void
+ HypRoutingTableCalculator::allocateDistFromNbrToDest()
+ {
+ distFromNbrToDest=new double[vNoLink];
+ }
+
+ void
+ HypRoutingTableCalculator::freeLinkFaces()
+ {
+ delete [] linkFaces;
+ }
+
+ void
+ HypRoutingTableCalculator::freeDistanceToNeighbor()
+ {
+ delete [] distanceToNeighbor;
+ }
+
+ void
+ HypRoutingTableCalculator::freeDistFromNbrToDest()
+ {
+ delete [] distFromNbrToDest;
+ }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_rtc.hpp b/src/route/nlsr_rtc.hpp
new file mode 100644
index 0000000..987686e
--- /dev/null
+++ b/src/route/nlsr_rtc.hpp
@@ -0,0 +1,145 @@
+#ifndef NLSR_RTC_HPP
+#define NLSR_RTC_HPP
+
+#include <list>
+#include <iostream>
+
+namespace nlsr
+{
+
+ class Map;
+ class RoutingTable;
+ class Nlsr;
+
+
+ using namespace std;
+
+ class RoutingTableCalculator
+ {
+ public:
+ RoutingTableCalculator()
+ {
+ }
+ RoutingTableCalculator(int rn)
+ {
+ numOfRouter=rn;
+ }
+ protected:
+ void allocateAdjMatrix();
+ void initMatrix();
+ void makeAdjMatrix(Nlsr& pnlsr,Map pMap);
+ void printAdjMatrix();
+ int getNumOfLinkfromAdjMatrix(int sRouter);
+ void freeAdjMatrix();
+ void adjustAdMatrix(int source, int link, double linkCost);
+ void getLinksFromAdjMatrix(int *links, double *linkCosts, int source);
+
+ void allocateLinks();
+ void allocateLinkCosts();
+ void freeLinks();
+ void freeLinksCosts();
+
+ void setNoLink(int nl)
+ {
+ vNoLink=nl;
+ }
+
+ protected:
+ double ** adjMatrix;
+ int numOfRouter;
+
+ int vNoLink;
+ int *links;
+ double *linkCosts;
+ };
+
+ class LinkStateRoutingTableCalculator: public RoutingTableCalculator
+ {
+ public:
+ LinkStateRoutingTableCalculator(int rn)
+ : EMPTY_PARENT(-12345)
+ , INF_DISTANCE(2147483647)
+ , NO_MAPPING_NUM(-1)
+ , NO_NEXT_HOP(-12345)
+ {
+ numOfRouter=rn;
+ }
+
+
+ void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
+
+
+ private:
+ void doDijkstraPathCalculation(int sourceRouter);
+ void sortQueueByDistance(int *Q, double *dist,int start,int element);
+ int isNotExplored(int *Q, int u,int start, int element);
+ void printAllLsPath(int sourceRouter);
+ void printLsPath(int destRouter);
+ void addAllLsNextHopsToRoutingTable(Nlsr& pnlsr, RoutingTable& rt,
+ Map& pMap,int sourceRouter);
+ int getLsNextHop(int dest, int source);
+
+ void allocateParent();
+ void allocateDistance();
+ void freeParent();
+ void freeDistance();
+
+
+
+
+ private:
+ int *parent;
+ double *distance;
+
+
+ const int EMPTY_PARENT;
+ const double INF_DISTANCE;
+ const int NO_MAPPING_NUM;
+ const int NO_NEXT_HOP;
+
+ };
+
+ class HypRoutingTableCalculator: public RoutingTableCalculator
+ {
+ public:
+ HypRoutingTableCalculator(int rn)
+ : MATH_PI(3.141592654)
+ {
+ numOfRouter=rn;
+ isDryRun=0;
+ }
+ HypRoutingTableCalculator(int rn, int idr)
+ : MATH_PI(3.141592654)
+ {
+ numOfRouter=rn;
+ isDryRun=idr;
+ }
+
+ void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
+
+ private:
+ void allocateLinkFaces();
+ void allocateDistanceToNeighbor();
+ void allocateDistFromNbrToDest();
+ void freeLinkFaces();
+ void freeDistanceToNeighbor();
+ void freeDistFromNbrToDest();
+
+ double getHyperbolicDistance(Nlsr& pnlsr,Map& pMap, int src, int dest);
+ void addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
+ RoutingTable& rt, int noFaces,int dest);
+
+ private:
+ int isDryRun;
+
+ int *linkFaces;
+ double *distanceToNeighbor;
+ double *distFromNbrToDest;
+
+ const double MATH_PI;
+
+ };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rte.cpp b/src/route/nlsr_rte.cpp
new file mode 100644
index 0000000..f96da11
--- /dev/null
+++ b/src/route/nlsr_rte.cpp
@@ -0,0 +1,26 @@
+#include <iostream>
+#include <string>
+
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ ostream&
+ operator<<(ostream& os, RoutingTableEntry &rte)
+ {
+ os<<"Destination: "<<rte.getDestination()<<endl;
+ os<<"Nexthops: "<<endl;
+ int i=1;
+ std::list< NextHop > nhl = rte.getNhl().getNextHopList();
+ for( std::list<NextHop>::iterator it=nhl.begin();
+ it!= nhl.end() ; it++,i++)
+ {
+ os <<" Nexthop "<<i<<": "<<(*it)<<endl;
+ }
+ return os;
+ }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_rte.hpp b/src/route/nlsr_rte.hpp
new file mode 100644
index 0000000..27d3601
--- /dev/null
+++ b/src/route/nlsr_rte.hpp
@@ -0,0 +1,52 @@
+#ifndef NLSR_RTE_HPP
+#define NLSR_RTE_HPP
+
+#include<iostream>
+
+#include "nlsr_nhl.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+
+ class RoutingTableEntry
+ {
+ public:
+ RoutingTableEntry()
+ : destination()
+ , nhl()
+ {
+ }
+
+ ~RoutingTableEntry()
+ {
+ }
+
+ RoutingTableEntry(string dest)
+ : nhl()
+ {
+ destination=dest;
+ }
+
+ string getDestination()
+ {
+ return destination;
+ }
+
+ Nhl& getNhl()
+ {
+ return nhl;
+ }
+
+ private:
+ string destination;
+ Nhl nhl;
+ };
+
+ ostream&
+ operator<<(ostream& os, RoutingTableEntry &rte);
+
+}
+
+#endif
diff --git a/src/security/nlsr_cert_store.hpp b/src/security/nlsr_cert_store.hpp
new file mode 100644
index 0000000..5bbef9e
--- /dev/null
+++ b/src/security/nlsr_cert_store.hpp
@@ -0,0 +1,6 @@
+#ifndef NLSR_CERT_STORE_HPP
+#define NLSR_CERT_STORE_HPP
+
+
+
+#endif
diff --git a/src/security/nlsr_km.cpp b/src/security/nlsr_km.cpp
new file mode 100644
index 0000000..69052eb
--- /dev/null
+++ b/src/security/nlsr_km.cpp
@@ -0,0 +1,84 @@
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/encoding/block.hpp>
+#include "nlsr_sm.hpp"
+#include "nlsr_km.hpp"
+
+namespace nlsr
+{
+ void
+ KeyManager::initKeyManager(ConfParameter &cp)
+ {
+ string processIdentityName(cp.getRootKeyPrefix());
+ processIdentityName += "/";
+ processIdentityName += cp.getSiteName();
+ processIdentityName += "/";
+ processIdentityName += "R.Start";
+ processIdentityName += "/";
+ processIdentityName += cp.getRouterName();
+ processIdentityName += "/";
+ processIdentityName += "nlsr";
+ cout<<"Proces Identity Name: "<<processIdentityName<<endl;
+ ndn::Name identityName(processIdentityName);
+ routerIdentity=identityName;
+ ndn::KeyChain::deleteIdentity(routerIdentity);
+ routerCertName = ndn::KeyChain::createIdentity(routerIdentity);
+ cout<<"Certificate Name: "<<routerCertName.toUri()<<endl;
+ routerKeyName=
+ ndn::IdentityCertificate::certificateNameToPublicKeyName(routerCertName);
+ cout<<"Key Name: "<<routerKeyName.toUri()<<endl;
+ initCertSeqFromFile(cp.getSeqFileDir());
+ }
+
+ ndn::Name
+ KeyManager::getRouterCertName()
+ {
+ return routerCertName;
+ }
+
+ uint32_t
+ KeyManager::getCertSeqNo()
+ {
+ return certSeqNo;
+ }
+
+ void
+ KeyManager::setCerSeqNo(uint32_t csn)
+ {
+ certSeqNo=csn;
+ }
+
+ void
+ KeyManager::initCertSeqFromFile(string certSeqFileDir)
+ {
+ certSeqFileNameWithPath=certSeqFileDir;
+ if( certSeqFileNameWithPath.empty() )
+ {
+ SequencingManager sm;
+ certSeqFileNameWithPath=sm.getUserHomeDirectory();
+ }
+ certSeqFileNameWithPath += "/nlsrCertSeqNo.txt";
+ cout<<"Key Seq File Name: "<< certSeqFileNameWithPath<<endl;
+ std::ifstream inputFile(certSeqFileNameWithPath.c_str(),ios::binary);
+ if ( inputFile.good() )
+ {
+ inputFile>>certSeqNo;
+ certSeqNo++;
+ }
+ else
+ {
+ certSeqNo=1;
+ }
+ writeCertSeqToFile();
+ }
+
+ void
+ KeyManager::writeCertSeqToFile()
+ {
+ std::ofstream outputFile(certSeqFileNameWithPath.c_str(),ios::binary);
+ outputFile<<certSeqNo;
+ outputFile.close();
+ }
+}
+
+
+
diff --git a/src/security/nlsr_km.hpp b/src/security/nlsr_km.hpp
new file mode 100644
index 0000000..7b3b7ba
--- /dev/null
+++ b/src/security/nlsr_km.hpp
@@ -0,0 +1,158 @@
+#ifndef NLSR_KM_HPP
+#define NLSR_KM_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/data.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/security/validator.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+#include <ndn-cpp-dev/util/random.hpp>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
+
+#include <ndn-cpp-dev/security/sec-public-info-sqlite3.hpp>
+#include <ndn-cpp-dev/security/sec-public-info-memory.hpp>
+//TPM
+#include <ndn-cpp-dev/security/sec-tpm-file.hpp>
+#include <ndn-cpp-dev/security/sec-tpm-memory.hpp>
+
+#ifdef NDN_CPP_HAVE_OSX_SECURITY
+#include <ndn-cpp-dev/security/sec-tpm-osx.hpp>
+#endif
+
+#include <list>
+#include "nlsr_conf_param.hpp"
+
+namespace nlsr
+{
+ enum nlsrKeyType
+ {
+ KEY_TYPE_ROOT,
+ KEY_TYPE_SITE,
+ KEY_TYPE_OPERATOR,
+ KEY_TYPE_ROUTER,
+ KEY_TYPE_PROCESS
+ };
+
+ class KeyManager: public ndn::KeyChain, public ndn::Validator
+ {
+ typedef SecPublicInfo::Error InfoError;
+ typedef SecTpm::Error TpmError;
+ public:
+ KeyManager()
+ : certSeqNo(1)
+ {
+ }
+
+ void initKeyManager(ConfParameter &cp);
+
+ void
+ checkPolicy (const ndn::Data& data,
+ int stepCount,
+ const ndn::OnDataValidated &onValidated,
+ const ndn::OnDataValidationFailed &onValidationFailed,
+ std::vector<ndn::shared_ptr<ndn::ValidationRequest> > &nextSteps)
+ {}
+
+ void
+ checkPolicy (const ndn::Interest& interest,
+ int stepCount,
+ const ndn::OnInterestValidated &onValidated,
+ const ndn::OnInterestValidationFailed &onValidationFailed,
+ std::vector<ndn::shared_ptr<ndn::ValidationRequest> > &nextSteps)
+ {}
+
+ void signData(ndn::Data& data)
+ {
+ ndn::KeyChain::signByIdentity(data,routerIdentity);
+ //ndn::SignatureSha256WithRsa signature(data.getSignature());
+ //signature.setKeyLocator(routerCertName);
+ }
+
+ ndn::shared_ptr<ndn::IdentityCertificate>
+ getCertificate(ndn::Name certificateName)
+ {
+ return ndn::KeyChain::getCertificate(routerCertName);
+ }
+
+ ndn::Name
+ createIdentity(const ndn::Name identityName, const ndn::Name signee)
+ {
+ ndn::KeyChain::addIdentity(identityName);
+ ndn::Name keyName;
+ try
+ {
+ keyName = ndn::KeyChain::getDefaultKeyNameForIdentity(identityName);
+ }
+ catch(InfoError& e)
+ {
+ keyName = ndn::KeyChain::generateRSAKeyPairAsDefault(identityName, true);
+ }
+ ndn::shared_ptr<ndn::PublicKey> pubKey;
+ try
+ {
+ pubKey = ndn::KeyChain::getPublicKey(keyName);
+ }
+ catch(InfoError& e)
+ {
+ //return ndn::shared_ptr<ndn::IdentityCertificate>()->getName();
+ return identityName;
+ }
+ ndn::Name certName;
+ try
+ {
+ certName = ndn::KeyChain::getDefaultCertificateNameForKey(keyName);
+ }
+ catch(InfoError& e)
+ {
+ ndn::shared_ptr<ndn::IdentityCertificate> certificate =
+ ndn::make_shared<ndn::IdentityCertificate>();
+ ndn::Name certificateName = keyName.getPrefix(-1);
+ certificateName.append("KEY").append(
+ keyName.get(-1)).append("ID-CERT").appendVersion();
+ certificate->setName(certificateName);
+ certificate->setNotBefore(ndn::getNow());
+ certificate->setNotAfter(ndn::getNow() + 31536000 /* 1 year*/);
+ certificate->setPublicKeyInfo(*pubKey);
+ certificate->addSubjectDescription(
+ ndn::CertificateSubjectDescription("2.5.4.41",
+ keyName.toUri()));
+ certificate->encode();
+ try
+ {
+ ndn::KeyChain::signByIdentity(*certificate,signee);
+ }
+ catch(InfoError& e)
+ {
+ try
+ {
+ ndn::KeyChain::deleteIdentity(identityName);
+ }
+ catch(InfoError& e)
+ {
+ }
+ return identityName;
+ }
+ certName=certificate->getName();
+ }
+ return certName;
+ }
+
+ ndn::Name getRouterCertName();
+
+ uint32_t getCertSeqNo();
+ void setCerSeqNo(uint32_t csn);
+ void initCertSeqFromFile(string certSeqFileDir);
+ void writeCertSeqToFile();
+
+ private:
+ ndn::Name routerIdentity;
+ ndn::Name routerCertName;
+ ndn::Name routerKeyName;
+ uint32_t certSeqNo;
+ string certSeqFileNameWithPath;
+
+ };
+}
+
+#endif
diff --git a/src/utility/nlsr_logger.cpp b/src/utility/nlsr_logger.cpp
new file mode 100644
index 0000000..804ef98
--- /dev/null
+++ b/src/utility/nlsr_logger.cpp
@@ -0,0 +1,59 @@
+#include "nlsr_logger.hpp"
+
+namespace nlsr
+{
+
+ string
+ NlsrLogger::getEpochTime()
+ {
+ std::stringstream ss;
+ boost::posix_time::ptime time_t_epoch(boost::gregorian::date(1970,1,1));
+ boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
+ boost::posix_time::time_duration diff = now - time_t_epoch;
+ ss<<diff.total_seconds()<<"."<<boost::format("%06i")%(diff.total_microseconds()
+ %1000000);
+ return ss.str();
+ }
+
+ string
+ NlsrLogger::getUserHomeDirectory()
+ {
+ string homeDirPath(getpwuid(getuid())->pw_dir);
+ if( homeDirPath.empty() )
+ {
+ homeDirPath = getenv("HOME");
+ }
+ return homeDirPath;
+ }
+
+ void
+ NlsrLogger::initNlsrLogger(std::string dirPath)
+ {
+ string logDirPath(dirPath);
+ if( dirPath.empty() )
+ {
+ logDirPath=getUserHomeDirectory()+"/nlsrLog";
+ }
+ cout<<"Log Dir Path: "<< logDirPath<<endl;
+ typedef sinks::synchronous_sink< sinks::text_file_backend > file_sink;
+ shared_ptr< file_sink > sink(new file_sink(
+ keywords::file_name = logDirPath
+ +"/NLSR%Y%m%d%H%M%S_%3N.log",
+ keywords::rotation_size = 128 * 1024 * 1024,
+ keywords::time_based_rotation = sinks::file::rotation_at_time_point(12, 0, 0),
+ keywords::auto_flush = true
+ ));
+ sink->locked_backend()->set_file_collector(sinks::file::make_collector(
+ keywords::target = logDirPath,
+ keywords::max_size = 16 * 1024 * 1024 * 1024,
+ keywords::min_free_space = 128 * 1024 * 1024
+ ));
+ sink->set_formatter(
+ expr::format("%1%: %2%")
+ % getEpochTime()
+ % expr::smessage
+ );
+ logging::core::get()->add_sink(sink);
+ }
+
+}//namespace nlsr
diff --git a/src/utility/nlsr_logger.hpp b/src/utility/nlsr_logger.hpp
new file mode 100644
index 0000000..222ac52
--- /dev/null
+++ b/src/utility/nlsr_logger.hpp
@@ -0,0 +1,62 @@
+#ifndef NLSR_LOGGER_HPP
+#define NLSR_LOGGER_HPP
+
+#define BOOST_LOG_DYN_LINK 1
+
+#include <stdexcept>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <pwd.h>
+#include <cstdlib>
+#include <string>
+#include <unistd.h>
+#include <boost/format.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/date_time/local_time/local_time.hpp>
+#include <boost/log/common.hpp>
+#include <boost/log/expressions.hpp>
+#include <boost/log/attributes.hpp>
+#include <boost/log/sources/logger.hpp>
+#include <boost/log/sinks/sync_frontend.hpp>
+#include <boost/log/sinks/text_file_backend.hpp>
+
+namespace nlsr
+{
+
+ namespace logging = boost::log;
+ namespace attrs = boost::log::attributes;
+ namespace src = boost::log::sources;
+ namespace sinks = boost::log::sinks;
+ namespace expr = boost::log::expressions;
+ namespace keywords = boost::log::keywords;
+
+ using boost::shared_ptr;
+ using namespace std;
+
+
+ class NlsrLogger
+ {
+ public:
+ NlsrLogger()
+ {
+ }
+
+ void initNlsrLogger(std::string dirPath);
+
+ src::logger& getLogger()
+ {
+ return mLogger;
+ }
+
+ private:
+ string getEpochTime();
+ string getUserHomeDirectory();
+
+ private:
+ src::logger mLogger;
+ };
+
+}//namespace nlsr
+#endif
diff --git a/src/utility/nlsr_tokenizer.cpp b/src/utility/nlsr_tokenizer.cpp
new file mode 100644
index 0000000..809e395
--- /dev/null
+++ b/src/utility/nlsr_tokenizer.cpp
@@ -0,0 +1,110 @@
+#include <iostream>
+#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string.hpp>
+#include <string>
+#include <algorithm>
+
+#include "nlsr_tokenizer.hpp"
+
+namespace nlsr
+{
+
+ using namespace std;
+ using namespace boost;
+
+ void
+ nlsrTokenizer::makeToken()
+ {
+ char_separator<char> sep(seps.c_str());
+ tokenizer< char_separator<char> >tokens(originalString, sep);
+ tokenizer< char_separator<char> >::iterator tok_iter = tokens.begin();
+ for ( ; tok_iter != tokens.end(); ++tok_iter)
+ {
+ string oneToken(*tok_iter);
+ trim(oneToken);
+ if(!oneToken.empty())
+ {
+ insertToken(oneToken);
+ }
+ }
+ firstToken=vTokenList[0];
+ makeRestOfTheLine();
+ }
+
+ void
+ nlsrTokenizer::insertToken(const string& token)
+ {
+ tokenList.push_back(token);
+ vTokenList.push_back(token);
+ }
+
+ int
+ nlsrTokenizer::getTokenPosition(string& token)
+ {
+ int pos=-1;
+ int i=0;
+ for(std::list<string>::iterator it=tokenList.begin();
+ it!=tokenList.end(); it++)
+ {
+ if( (*it) == token )
+ {
+ break;
+ }
+ i++;
+ }
+ if( i < tokenList.size() )
+ {
+ pos=i;
+ }
+ return pos;
+ }
+
+ string
+ nlsrTokenizer::getTokenString(int from , int to)
+ {
+ string returnString="";
+ if((from>=0 && to<tokenList.size()) &&
+ (to>=from && to <tokenList.size()))
+ {
+ for(int i=from; i<=to; i++)
+ {
+ returnString+=seps;
+ returnString+=vTokenList[i];
+ }
+ }
+ trim(returnString);
+ return returnString;
+ }
+
+ string
+ nlsrTokenizer::getTokenString(int from)
+ {
+ return getTokenString(from,tokenList.size()-1);
+ }
+
+ static bool
+ tokenCompare(string& s1, string& s2)
+ {
+ return s1==s2;
+ }
+
+ void
+ nlsrTokenizer::makeRestOfTheLine()
+ {
+ restOfTheLine=getTokenString(1);
+ }
+
+ bool
+ nlsrTokenizer::doesTokenExist(string token)
+ {
+ std::list<string >::iterator it = std::find_if( tokenList.begin(),
+ tokenList.end(),
+ bind(&tokenCompare, _1 , token));
+ if( it != tokenList.end() )
+ {
+ return true;
+ }
+ return false;
+ }
+
+}//namespace nlsr
diff --git a/src/utility/nlsr_tokenizer.hpp b/src/utility/nlsr_tokenizer.hpp
new file mode 100644
index 0000000..6cd97e0
--- /dev/null
+++ b/src/utility/nlsr_tokenizer.hpp
@@ -0,0 +1,104 @@
+#ifndef NLSR_TOKENIZER_HPP
+#define NLSR_TOKENIZER_HPP
+
+#include <iostream>
+#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string.hpp>
+#include <string>
+#include <list>
+#include <vector>
+#include <ndn-cpp-dev/face.hpp>
+
+namespace nlsr
+{
+
+ using namespace std;
+ using namespace boost;
+
+ class nlsrTokenizer
+ {
+ public:
+ nlsrTokenizer(const string& inputString)
+ : firstToken()
+ , restOfTheLine()
+ , currentPosition(0)
+ {
+ seps = " ";
+ originalString = inputString;
+ makeToken();
+ }
+
+ nlsrTokenizer(const string& inputString, const string& separator)
+ : firstToken()
+ , restOfTheLine()
+ , currentPosition(0)
+ {
+ seps = separator;
+ originalString = inputString;
+ makeToken();
+ }
+
+ string getFirstToken()
+ {
+ return firstToken;
+ }
+
+ string getRestOfLine()
+ {
+ return restOfTheLine;
+ }
+
+ void resetCurrentPosition(uint32_t cp=0)
+ {
+ if( cp >=0 && cp <= vTokenList.size() )
+ {
+ currentPosition=cp;
+ }
+ }
+
+ string getNextToken()
+ {
+ if(currentPosition >= 0 && currentPosition <= (vTokenList.size()-1))
+ {
+ return vTokenList[currentPosition++];
+ }
+ return "";
+ }
+
+ uint32_t getTokenNumber()
+ {
+ return tokenList.size();
+ }
+
+ string getToken(int position)
+ {
+ if( position >=0 && position <vTokenList.size() )
+ {
+ return vTokenList[position];
+ }
+ return "";
+ }
+
+ int getTokenPosition(string& token);
+ string getTokenString(int from , int to);
+ string getTokenString(int from);
+ bool doesTokenExist(string token);
+
+
+ private:
+
+ void makeToken();
+ void insertToken(const string& token);
+ void makeRestOfTheLine();
+
+ string seps;
+ string originalString;
+ string firstToken;
+ string restOfTheLine;
+ std::list<string> tokenList;
+ std::vector<string> vTokenList;
+ uint32_t currentPosition;
+ };
+
+}//namespace nlsr
+#endif
diff --git a/waf-tools/boost.pyc b/waf-tools/boost.pyc
new file mode 100644
index 0000000..22854fd
--- /dev/null
+++ b/waf-tools/boost.pyc
Binary files differ
diff --git a/waf-tools/cryptopp.py b/waf-tools/cryptopp.py
new file mode 100644
index 0000000..a05326b
--- /dev/null
+++ b/waf-tools/cryptopp.py
@@ -0,0 +1,77 @@
+#! /usr/bin/env python
+# encoding: utf-8
+
+'''
+
+When using this tool, the wscript will look like:
+
+ def options(opt):
+ opt.tool_options('cryptopp', tooldir=["waf-tools"])
+
+ def configure(conf):
+ conf.load('compiler_cxx cryptopp')
+
+ def build(bld):
+ bld(source='main.cpp', target='app', use='CRYPTOPP')
+
+Options are generated, in order to specify the location of cryptopp includes/libraries.
+
+
+'''
+import sys
+import re
+from waflib import Utils,Logs,Errors
+from waflib.Configure import conf
+CRYPTOPP_DIR=['/usr','/usr/local','/opt/local','/sw']
+CRYPTOPP_VERSION_FILE='config.h'
+CRYPTOPP_VERSION_CODE='''
+#include <iostream>
+#include <cryptopp/config.h>
+int main() { std::cout << CRYPTOPP_VERSION; }
+'''
+
+def options(opt):
+ opt.add_option('--cryptopp',type='string',default='',dest='cryptopp_dir',help='''path to where cryptopp is installed, e.g. /opt/local''')
+@conf
+def __cryptopp_get_version_file(self,dir):
+ try:
+ return self.root.find_dir(dir).find_node('%s/%s' % ('include/cryptopp', CRYPTOPP_VERSION_FILE))
+ except:
+ return None
+@conf
+def cryptopp_get_version(self,dir):
+ val=self.check_cxx(fragment=CRYPTOPP_VERSION_CODE,includes=['%s/%s' % (dir, 'include')], execute=True, define_ret = True, mandatory=True)
+ return val
+@conf
+def cryptopp_get_root(self,*k,**kw):
+ root=k and k[0]or kw.get('path',None)
+ # Logs.pprint ('RED', ' %s' %root)
+ if root and self.__cryptopp_get_version_file(root):
+ return root
+ for dir in CRYPTOPP_DIR:
+ if self.__cryptopp_get_version_file(dir):
+ return dir
+ if root:
+ self.fatal('CryptoPP not found in %s'%root)
+ else:
+ self.fatal('CryptoPP not found, please provide a --cryptopp argument (see help)')
+@conf
+def check_cryptopp(self,*k,**kw):
+ if not self.env['CXX']:
+ self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
+
+ var=kw.get('uselib_store','CRYPTOPP')
+ self.start_msg('Checking Crypto++ lib')
+ root = self.cryptopp_get_root(*k,**kw)
+ self.env.CRYPTOPP_VERSION=self.cryptopp_get_version(root)
+
+ self.env['INCLUDES_%s'%var]= '%s/%s' % (root, "include")
+ self.env['LIB_%s'%var] = "cryptopp"
+ self.env['LIBPATH_%s'%var] = '%s/%s' % (root, "lib")
+
+ self.end_msg(self.env.CRYPTOPP_VERSION)
+ if Logs.verbose:
+ Logs.pprint('CYAN',' CRYPTOPP include : %s'%self.env['INCLUDES_%s'%var])
+ Logs.pprint('CYAN',' CRYPTOPP lib : %s'%self.env['LIB_%s'%var])
+ Logs.pprint('CYAN',' CRYPTOPP libpath : %s'%self.env['LIBPATH_%s'%var])
+
diff --git a/waf-tools/cryptopp.pyc b/waf-tools/cryptopp.pyc
new file mode 100644
index 0000000..60fed1e
--- /dev/null
+++ b/waf-tools/cryptopp.pyc
Binary files differ