blob: de1343a97ececcd2d93d22fbe8527a2a7a5e00ec [file] [log] [blame]
#include<string>
#include<utility>
#include "nlsr_lsdb.hpp"
#include "nlsr.hpp"
using namespace std;
void
Lsdb::cancelScheduleLsaExpiringEvent(nlsr& pnlsr, EventId eid)
{
pnlsr.getScheduler().cancelEvent(eid);
}
static bool
nameLsaCompareByKey(NameLsa& nlsa1, string& key){
return nlsa1.getNameLsaKey()==key;
}
bool
Lsdb::buildAndInstallOwnNameLsa(nlsr& pnlsr)
{
NameLsa nameLsa(pnlsr.getConfParameter().getRouterPrefix()
, 1
, pnlsr.getSm().getNameLsaSeq()+1
, pnlsr.getConfParameter().getRouterDeadInterval()
, pnlsr.getNpl() );
pnlsr.getSm().setNameLsaSeq(pnlsr.getSm().getNameLsaSeq()+1);
return installNameLsa(pnlsr,nameLsa);
}
std::pair<NameLsa&, bool>
Lsdb::getNameLsa(string key)
{
std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
nameLsdb.end(),
bind(nameLsaCompareByKey, _1, key));
if( it != nameLsdb.end())
{
return std::make_pair(boost::ref((*it)),true);
}
NameLsa nlsa;
return std::make_pair(boost::ref(nlsa),false);
}
ndn::EventId
Lsdb::scheduleNameLsaExpiration(nlsr& pnlsr, string key, int seqNo, int expTime)
{
return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
ndn::bind(&Lsdb::exprireOrRefreshNameLsa,
this,boost::ref(pnlsr), key, seqNo));
}
bool
Lsdb::installNameLsa(nlsr& pnlsr, NameLsa &nlsa)
{
int timeToExpire=lsaRefreshTime;
std::pair<NameLsa& , bool> chkNameLsa=getNameLsa(nlsa.getNameLsaKey());
if ( !chkNameLsa.second )
{
addNameLsa(nlsa);
printNameLsdb();
if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
{
pnlsr.getNpt().addNpte(nlsa.getOrigRouter(),nlsa.getOrigRouter(),pnlsr);
std::list<string> nameList=nlsa.getNpl().getNameList();
for(std::list<string>::iterator it=nameList.begin(); it!=nameList.end();it++)
{
if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
{
pnlsr.getNpt().addNpte((*it),nlsa.getOrigRouter(),pnlsr);
}
}
}
if(nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
{
timeToExpire=nlsa.getLifeTime();
}
nlsa.setLsaExpiringEventId(scheduleNameLsaExpiration( pnlsr,
nlsa.getNameLsaKey(), nlsa.getLsSeqNo(), timeToExpire));
}
else
{
if ( chkNameLsa.first.getLsSeqNo() < nlsa.getLsSeqNo() )
{
chkNameLsa.first.setLsSeqNo(nlsa.getLsSeqNo());
chkNameLsa.first.setLifeTime(nlsa.getLifeTime());
chkNameLsa.first.getNpl().sortNpl();
nlsa.getNpl().sortNpl();
std::list<string> nameToAdd;
std::set_difference(nlsa.getNpl().getNameList().begin(),
nlsa.getNpl().getNameList().end(),
chkNameLsa.first.getNpl().getNameList().begin(),
chkNameLsa.first.getNpl().getNameList().end(),
std::inserter(nameToAdd, nameToAdd.begin()));
for(std::list<string>::iterator it=nameToAdd.begin(); it!=nameToAdd.end();
++it)
{
chkNameLsa.first.addNameToLsa((*it));
if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
{
if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
{
pnlsr.getNpt().addNpte((*it),nlsa.getOrigRouter(),pnlsr);
}
}
}
std::list<string> nameToRemove;
std::set_difference(chkNameLsa.first.getNpl().getNameList().begin(),
chkNameLsa.first.getNpl().getNameList().end(),
nlsa.getNpl().getNameList().begin(),
nlsa.getNpl().getNameList().end(),
std::inserter(nameToRemove, nameToRemove.begin()));
for(std::list<string>::iterator it=nameToRemove.begin();
it!=nameToRemove.end(); ++it)
{
chkNameLsa.first.removeNameFromLsa((*it));
if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
{
if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
{
pnlsr.getNpt().removeNpte((*it),nlsa.getOrigRouter(),pnlsr);
}
}
}
if(nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
{
timeToExpire=nlsa.getLifeTime();
}
cancelScheduleLsaExpiringEvent(pnlsr,
chkNameLsa.first.getLsaExpiringEventId());
chkNameLsa.first.setLsaExpiringEventId(scheduleNameLsaExpiration( pnlsr,
nlsa.getNameLsaKey(), nlsa.getLsSeqNo(), timeToExpire));
}
}
return true;
}
bool
Lsdb::addNameLsa(NameLsa &nlsa)
{
std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
nameLsdb.end(), bind(nameLsaCompareByKey, _1, nlsa.getNameLsaKey()));
if( it == nameLsdb.end())
{
nameLsdb.push_back(nlsa);
return true;
}
return false;
}
bool
Lsdb::removeNameLsa(nlsr& pnlsr, string& key)
{
std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
nameLsdb.end(),
bind(nameLsaCompareByKey, _1, key));
if ( it != nameLsdb.end() )
{
if ( (*it).getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix() )
{
pnlsr.getNpt().removeNpte((*it).getOrigRouter(),(*it).getOrigRouter(),pnlsr);
for( std::list<string>::iterator nit=(*it).getNpl().getNameList().begin();
nit!=(*it).getNpl().getNameList().end(); ++nit)
{
if ( (*nit) !=pnlsr.getConfParameter().getRouterPrefix())
{
pnlsr.getNpt().removeNpte((*nit),(*it).getOrigRouter(),pnlsr);
}
}
}
nameLsdb.erase(it);
return true;
}
return false;
}
bool
Lsdb::doesNameLsaExist(string key)
{
std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
nameLsdb.end(),
bind(nameLsaCompareByKey, _1, key));
if( it == nameLsdb.end()){
return false;
}
return true;
}
void
Lsdb::printNameLsdb()
{
cout<<"---------------Name LSDB-------------------"<<endl;
for( std::list<NameLsa>::iterator it=nameLsdb.begin();
it!= nameLsdb.end() ; it++)
{
cout<< (*it) <<endl;
}
}
// Cor LSA and LSDB related Functions start here
static bool
corLsaCompareByKey(CorLsa& clsa, string& key){
return clsa.getCorLsaKey()==key;
}
bool
Lsdb::buildAndInstallOwnCorLsa(nlsr& pnlsr){
CorLsa corLsa(pnlsr.getConfParameter().getRouterPrefix()
, 3
, pnlsr.getSm().getCorLsaSeq()+1
, pnlsr.getConfParameter().getRouterDeadInterval()
, pnlsr.getConfParameter().getCorR()
, pnlsr.getConfParameter().getCorTheta() );
pnlsr.getSm().setCorLsaSeq(pnlsr.getSm().getCorLsaSeq()+1);
installCorLsa(pnlsr, corLsa);
return true;
}
std::pair<CorLsa&, bool>
Lsdb::getCorLsa(string key)
{
std::list< CorLsa >::iterator it = std::find_if( corLsdb.begin(),
corLsdb.end(),
bind(corLsaCompareByKey, _1, key));
if( it != corLsdb.end()){
return std::make_pair(boost::ref((*it)), true);
}
CorLsa clsa;
return std::make_pair(boost::ref(clsa),false);
}
ndn::EventId
Lsdb::scheduleCorLsaExpiration(nlsr& pnlsr, string key, int seqNo, int expTime)
{
return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
ndn::bind(&Lsdb::exprireOrRefreshCorLsa,
this,boost::ref(pnlsr),key,seqNo));
}
bool
Lsdb::installCorLsa(nlsr& pnlsr, CorLsa &clsa)
{
int timeToExpire=lsaRefreshTime;
std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(clsa.getCorLsaKey());
if ( !chkCorLsa.second )
{
addCorLsa(clsa);
printCorLsdb(); //debugging purpose
if ( clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
{
pnlsr.getNpt().addNpte(clsa.getOrigRouter(),clsa.getOrigRouter(),pnlsr);
}
if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
{
pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
}
if(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
{
timeToExpire=clsa.getLifeTime();
}
scheduleCorLsaExpiration(pnlsr,clsa.getCorLsaKey(),
clsa.getLsSeqNo(), timeToExpire);
}
else
{
if ( chkCorLsa.first.getLsSeqNo() < clsa.getLsSeqNo() )
{
chkCorLsa.first.setLsSeqNo(clsa.getLsSeqNo());
chkCorLsa.first.setLifeTime(clsa.getLifeTime());
if ( !chkCorLsa.first.isLsaContentEqual(clsa) )
{
chkCorLsa.first.setCorRadius(clsa.getCorRadius());
chkCorLsa.first.setCorTheta(clsa.getCorTheta());
if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
{
pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
}
}
if(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
{
timeToExpire=clsa.getLifeTime();
}
cancelScheduleLsaExpiringEvent(pnlsr,
chkCorLsa.first.getLsaExpiringEventId());
chkCorLsa.first.setLsaExpiringEventId(scheduleCorLsaExpiration(pnlsr,
clsa.getCorLsaKey(),
clsa.getLsSeqNo(), timeToExpire));
}
}
return true;
}
bool
Lsdb::addCorLsa(CorLsa& clsa)
{
std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(),
corLsdb.end(),
bind(corLsaCompareByKey, _1, clsa.getCorLsaKey()));
if( it == corLsdb.end())
{
corLsdb.push_back(clsa);
return true;
}
return false;
}
bool
Lsdb::removeCorLsa(nlsr& pnlsr, string& key)
{
std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(),
corLsdb.end(),
bind(corLsaCompareByKey, _1, key));
if ( it != corLsdb.end() )
{
if ( (*it).getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
{
pnlsr.getNpt().removeNpte((*it).getOrigRouter(),(*it).getOrigRouter(),pnlsr);
}
corLsdb.erase(it);
return true;
}
return false;
}
bool
Lsdb::doesCorLsaExist(string key)
{
std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(),
corLsdb.end(),
bind(corLsaCompareByKey, _1, key));
if( it == corLsdb.end()){
return false;
}
return true;
}
void
Lsdb::printCorLsdb() //debugging
{
cout<<"---------------Cor LSDB-------------------"<<endl;
for( std::list<CorLsa>::iterator it=corLsdb.begin();
it!= corLsdb.end() ; it++)
{
cout<< (*it) <<endl;
}
}
// Adj LSA and LSDB related function starts here
static bool
adjLsaCompareByKey(AdjLsa& alsa, string& key){
return alsa.getAdjLsaKey()==key;
}
void
Lsdb::scheduledAdjLsaBuild(nlsr& pnlsr)
{
cout<<"scheduledAdjLsaBuild Called"<<endl;
pnlsr.setIsBuildAdjLsaSheduled(0);
if( pnlsr.getAdl().isAdjLsaBuildable(pnlsr))
{
int adjBuildCount=pnlsr.getAdjBuildCount();
if(adjBuildCount>0 )
{
if (pnlsr.getAdl().getNumOfActiveNeighbor()>0)
{
buildAndInstallOwnAdjLsa(pnlsr);
}
else
{
string key=pnlsr.getConfParameter().getRouterPrefix()+"/2";
removeAdjLsa(pnlsr,key);
pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
}
pnlsr.setAdjBuildCount(pnlsr.getAdjBuildCount()-adjBuildCount);
}
}
else
{
pnlsr.setIsBuildAdjLsaSheduled(1);
int schedulingTime=pnlsr.getConfParameter().getInterestRetryNumber()*
pnlsr.getConfParameter().getInterestResendTime();
pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(schedulingTime),
ndn::bind(&Lsdb::scheduledAdjLsaBuild, pnlsr.getLsdb(),
boost::ref(pnlsr)));
}
}
bool
Lsdb::addAdjLsa(AdjLsa &alsa)
{
std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
adjLsdb.end(),
bind(adjLsaCompareByKey, _1, alsa.getAdjLsaKey()));
if( it == adjLsdb.end()){
adjLsdb.push_back(alsa);
return true;
}
return false;
}
std::pair<AdjLsa& , bool>
Lsdb::getAdjLsa(string key)
{
std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
adjLsdb.end(),
bind(adjLsaCompareByKey, _1, key));
if( it != adjLsdb.end()){
return std::make_pair(boost::ref((*it)),true);
}
AdjLsa alsa;
return std::make_pair(boost::ref(alsa),false);
}
ndn::EventId
Lsdb::scheduleAdjLsaExpiration(nlsr& pnlsr, string key, int seqNo, int expTime)
{
return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
ndn::bind(&Lsdb::exprireOrRefreshAdjLsa,
this,boost::ref(pnlsr),key,seqNo));
}
bool
Lsdb::installAdjLsa(nlsr& pnlsr, AdjLsa &alsa)
{
int timeToExpire=lsaRefreshTime;
std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(alsa.getAdjLsaKey());
if ( !chkAdjLsa.second )
{
addAdjLsa(alsa);
alsa.addNptEntriesForAdjLsa(pnlsr);
pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
if(alsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
{
timeToExpire=alsa.getLifeTime();
}
scheduleAdjLsaExpiration(pnlsr,alsa.getAdjLsaKey(),
alsa.getLsSeqNo(),timeToExpire);
}
else
{
if ( chkAdjLsa.first.getLsSeqNo() < alsa.getLsSeqNo() )
{
chkAdjLsa.first.setLsSeqNo(alsa.getLsSeqNo());
chkAdjLsa.first.setLifeTime(alsa.getLifeTime());
if ( ! chkAdjLsa.first.isLsaContentEqual(alsa))
{
chkAdjLsa.first.getAdl().resetAdl();
chkAdjLsa.first.getAdl().addAdjacentsFromAdl(alsa.getAdl());
pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
}
if(alsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
{
timeToExpire=alsa.getLifeTime();
}
cancelScheduleLsaExpiringEvent(pnlsr,
chkAdjLsa.first.getLsaExpiringEventId());
chkAdjLsa.first.setLsaExpiringEventId(scheduleAdjLsaExpiration(pnlsr,
alsa.getAdjLsaKey(), alsa.getLsSeqNo(),timeToExpire));
}
}
printAdjLsdb();
return true;
}
bool
Lsdb::buildAndInstallOwnAdjLsa(nlsr& pnlsr)
{
AdjLsa adjLsa(pnlsr.getConfParameter().getRouterPrefix()
, 2
, pnlsr.getSm().getAdjLsaSeq()+1
, pnlsr.getConfParameter().getRouterDeadInterval()
, pnlsr.getAdl().getNumOfActiveNeighbor()
, pnlsr.getAdl() );
pnlsr.getSm().setAdjLsaSeq(pnlsr.getSm().getAdjLsaSeq()+1);
return installAdjLsa(pnlsr, adjLsa);
}
bool
Lsdb::removeAdjLsa(nlsr& pnlsr, string& key)
{
std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
adjLsdb.end(),
bind(adjLsaCompareByKey, _1, key));
if ( it != adjLsdb.end() )
{
(*it).removeNptEntriesForAdjLsa(pnlsr);
adjLsdb.erase(it);
return true;
}
return false;
}
bool
Lsdb::doesAdjLsaExist(string key)
{
std::list< AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
adjLsdb.end(),
bind(adjLsaCompareByKey, _1, key));
if( it == adjLsdb.end()){
return false;
}
return true;
}
std::list<AdjLsa>&
Lsdb::getAdjLsdb()
{
return adjLsdb;
}
void
Lsdb::setLsaRefreshTime(int lrt)
{
lsaRefreshTime=lrt;
}
void
Lsdb::setThisRouterPrefix(string trp)
{
thisRouterPrefix=trp;
}
void
Lsdb::exprireOrRefreshNameLsa(nlsr& pnlsr, string lsaKey, int seqNo)
{
cout<<"Lsdb::exprireOrRefreshNameLsa Called "<<endl;
cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<endl;
std::pair<NameLsa& , bool> chkNameLsa=getNameLsa(lsaKey);
if( chkNameLsa.second )
{
cout<<" LSA Exists with seq no: "<<chkNameLsa.first.getLsSeqNo()<<endl;
if ( chkNameLsa.first.getLsSeqNo() == seqNo )
{
if(chkNameLsa.first.getOrigRouter() == thisRouterPrefix )
{
cout<<"Own Name LSA, so refreshing name LSA"<<endl;
chkNameLsa.first.setLsSeqNo(chkNameLsa.first.getLsSeqNo()+1);
pnlsr.getSm().setNameLsaSeq(chkNameLsa.first.getLsSeqNo());
// publish routing update
}
else
{
cout<<"Other's Name LSA, so removing form LSDB"<<endl;
removeNameLsa(pnlsr, lsaKey);
}
}
}
}
void
Lsdb::exprireOrRefreshAdjLsa(nlsr& pnlsr, string lsaKey, int seqNo)
{
cout<<"Lsdb::exprireOrRefreshAdjLsa Called "<<endl;
cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<endl;
std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(lsaKey);
if( chkAdjLsa.second )
{
cout<<" LSA Exists with seq no: "<<chkAdjLsa.first.getLsSeqNo()<<endl;
if ( chkAdjLsa.first.getLsSeqNo() == seqNo )
{
if(chkAdjLsa.first.getOrigRouter() == thisRouterPrefix )
{
cout<<"Own Adj LSA, so refreshing Adj LSA"<<endl;
chkAdjLsa.first.setLsSeqNo(chkAdjLsa.first.getLsSeqNo()+1);
pnlsr.getSm().setAdjLsaSeq(chkAdjLsa.first.getLsSeqNo());
// publish routing update
}
else
{
cout<<"Other's Adj LSA, so removing form LSDB"<<endl;
removeAdjLsa(pnlsr, lsaKey);
}
// schedule Routing table calculaiton
pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
}
}
}
void
Lsdb::exprireOrRefreshCorLsa(nlsr& pnlsr, string lsaKey, int seqNo)
{
cout<<"Lsdb::exprireOrRefreshCorLsa Called "<<endl;
cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<endl;
std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(lsaKey);
if( chkCorLsa.second )
{
cout<<" LSA Exists with seq no: "<<chkCorLsa.first.getLsSeqNo()<<endl;
if ( chkCorLsa.first.getLsSeqNo() == seqNo )
{
if(chkCorLsa.first.getOrigRouter() == thisRouterPrefix )
{
cout<<"Own Cor LSA, so refreshing Cor LSA"<<endl;
chkCorLsa.first.setLsSeqNo(chkCorLsa.first.getLsSeqNo()+1);
pnlsr.getSm().setCorLsaSeq(chkCorLsa.first.getLsSeqNo());
// publish routing update
}
else
{
cout<<"Other's Cor LSA, so removing form LSDB"<<endl;
removeCorLsa(pnlsr, lsaKey);
}
if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
{
pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
}
}
}
}
void
Lsdb::printAdjLsdb()
{
cout<<"---------------Adj LSDB-------------------"<<endl;
for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
it!= adjLsdb.end() ; it++)
{
cout<< (*it) <<endl;
}
}
//-----utility function -----
bool
Lsdb::doesLsaExist(string key, int lsType)
{
if ( lsType == 1)
{
return doesNameLsaExist(key);
}
else if ( lsType == 2)
{
return doesAdjLsaExist(key);
}
else if ( lsType == 3)
{
return doesCorLsaExist(key);
}
return false;
}