ls.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:27k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * ls.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: ls.cc,v 1.5 2005/08/25 18:58:06 johnh Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. //
  46. // Other copyrights might apply to parts of this software and are so
  47. // noted when applicable.
  48. //
  49. //  Copyright (C) 1998 by Mingzhou Sun. All rights reserved.
  50. //  This software is developed at Rensselaer Polytechnic Institute under 
  51. //  DARPA grant No. F30602-97-C-0274
  52. //  Redistribution and use in source and binary forms are permitted
  53. //  provided that the above copyright notice and this paragraph are
  54. //  duplicated in all such forms and that any documentation, advertising
  55. //  materials, and other materials related to such distribution and use
  56. //  acknowledge that the software was developed by Mingzhou Sun at the
  57. //  Rensselaer  Polytechnic Institute.  The name of the University may not 
  58. //  be used to endorse or promote products derived from this software 
  59. //  without specific prior written permission.
  60. //
  61. // $Header: /cvsroot/nsnam/ns-2/linkstate/ls.cc,v 1.5 2005/08/25 18:58:06 johnh Exp $
  62. #include "config.h"
  63. #ifdef HAVE_STL
  64. #include "ls.h"
  65. // a global variable
  66. LsMessageCenter LsMessageCenter::msgctr_;
  67. int LsRouting::msgSizes[LS_MESSAGE_TYPES];
  68. static class initRouting {
  69. public:
  70. initRouting() {
  71. LsRouting::msgSizes[LS_MSG_LSA] = LS_LSA_MESSAGE_SIZE;
  72. LsRouting::msgSizes[LS_MSG_TPM] =  LS_TOPO_MESSAGE_SIZE;
  73. LsRouting::msgSizes[LS_MSG_LSAACK] = LS_ACK_MESSAGE_SIZE;
  74. LsRouting::msgSizes[LS_MSG_TPMACK] = LS_ACK_MESSAGE_SIZE;
  75. }
  76. } lsRoutingInitializer;
  77. static void ls_error(char* msg) 
  78. fprintf(stderr, "%sn", msg);
  79. abort();
  80. }
  81. /*
  82.   LsNodeIdList methods
  83. */
  84. int LsNodeIdList::appendUnique (const LsNodeIdList & x) 
  85. {
  86. int newHopCount = 0;
  87. for (LsNodeIdList::const_iterator itr1 = x.begin(); 
  88.      itr1 != x.end(); itr1++) {
  89. LsNodeIdList::iterator itr2;
  90. for (itr2 = begin(); itr2 != end(); itr2++)
  91. // check for duplicate
  92. if ((*itr1) == (*itr2))
  93. break;
  94. if (itr2 == end()) {
  95. // no duplicate, insert it 
  96. push_back(*itr1);
  97. newHopCount++; // forgot what newHopCount is used for
  98. }
  99. }
  100. return newHopCount;
  101. }
  102. /*
  103.   LsTopoMap methods
  104. */
  105. LsLinkStateList * 
  106. LsTopoMap::insertLinkState (int nodeId, const LsLinkState& linkState)
  107. {
  108. LsLinkStateList* lsp = LsLinkStateListMap::findPtr(nodeId);
  109. if (lsp != NULL) {
  110. // there's a node with other linkState, not checking if there's
  111. // duplicate
  112. lsp->push_back(linkState);
  113. return lsp;
  114. }
  115. // else new node
  116. LsLinkStateList lsl; // an empty one
  117. iterator itr = insert(nodeId, lsl);
  118. if (itr !=end()){
  119. // successful
  120. (*itr).second.push_back(linkState);
  121. return &((*itr).second);
  122. }
  123. // else something is wrong
  124. ls_error("LsTopoMap::insertLinkState failedn"); // debug
  125. return (LsLinkStateList *) NULL;
  126. }
  127. // -- update --, return true if anything's changed 
  128. bool LsTopoMap::update(int nodeId, 
  129.        const LsLinkStateList& linkStateList)
  130. {
  131. LsLinkStateList * LSLptr = findPtr (nodeId);
  132. if (LSLptr == NULL) {
  133. insert(nodeId, linkStateList);
  134. return true;
  135. }
  136. bool retCode = false;
  137. LsLinkStateList::iterator itrOld;
  138. for (LsLinkStateList::const_iterator itrNew = linkStateList.begin();
  139.      itrNew != linkStateList.end(); itrNew++ ) {
  140.   
  141. for (itrOld = LSLptr->begin();
  142.      itrOld != LSLptr->end(); itrOld++) {
  143. if ((*itrNew).neighborId_ == (*itrOld).neighborId_) {
  144. // old link state found
  145. if (nodeId != myNodeId_)
  146. // update the sequence number, if 
  147. // it's not  my own link state
  148. (*itrOld).sequenceNumber_ = 
  149. (*itrNew).sequenceNumber_;
  150. if ((*itrNew).status_ != (*itrOld).status_) {
  151. (*itrOld).status_ = (*itrNew).status_;
  152. retCode = true;
  153. }
  154. if ((*itrNew).cost_ != (*itrOld).cost_) {
  155. (*itrOld).cost_ = (*itrNew).cost_;
  156. retCode = true;
  157. }
  158. break; // no need to search for more old link state;
  159. } // end if old link state found
  160. } // end for old link states
  161. if (itrOld == LSLptr->end()) {
  162. // no old link found
  163. LSLptr->push_back(*itrNew);
  164. retCode = true;
  165. }
  166. }// end for new link states 
  167. return retCode;
  168. }
  169. /*
  170.   LsPaths methods
  171. */
  172. // insertPath(), returns end() if error, else return iterator 
  173. LsPaths::iterator LsPaths::insertPath(int destId, int cost, int nextHop) 
  174. {
  175. iterator itr = LsEqualPathsMap::find(destId);
  176. // if new path, insert it and return iterator
  177. if (itr == end())
  178. return insertPathNoChecking(destId, cost, nextHop);
  179. LsEqualPaths * ptrEP = &(*itr).second;
  180. // if the old path is better, ignore it, return end() 
  181. // to flag the error
  182. if (ptrEP->cost < cost)
  183. return end(); 
  184. // else if the new path is better, erase the old ones and save the new one
  185. LsNodeIdList & nhList = ptrEP->nextHopList;
  186. if (ptrEP->cost > cost) {
  187. ptrEP->cost = cost;
  188. nhList.erase(nhList.begin(), nhList.end());
  189. nhList.push_back(nextHop);
  190. return itr;
  191. }
  192. // else the old path is the same cost, check for duplicate
  193. for (LsNodeIdList::iterator itrList = nhList.begin();
  194.      itrList != nhList.end(); itrList++)
  195. // if duplicate found, return 0 to flag the error 
  196. if ((*itrList) == nextHop)
  197. return end(); 
  198. // else, the new path is installed indeed, the total number of nextHops
  199. // is returned. 
  200. nhList.push_back(nextHop);
  201. return itr;
  202. }
  203. LsPaths::iterator 
  204. LsPaths::insertNextHopList(int destId, int cost, 
  205.    const LsNodeIdList& nextHopList) 
  206. {
  207. iterator itr = LsEqualPathsMap::find(destId);
  208. // if new path, insert it and return iterator 
  209. if (itr == end()) {
  210. LsEqualPaths ep(cost, nextHopList);
  211. itr = insert(destId, ep);
  212. return itr;
  213. }
  214. // else get the old ep
  215. LsEqualPaths* ptrOldEp = &(*itr).second;
  216. // if the old path is better, ignore it, return end() to flag error
  217. if (ptrOldEp->cost < cost)
  218. return end();
  219. // else if the new path is better, replace the old one with the new one
  220. if (ptrOldEp->cost > cost) {
  221. ptrOldEp->cost = cost;
  222. ptrOldEp->nextHopList = nextHopList ; // copy
  223. return itr;
  224. }
  225. // equal cost: append the new next hops with checking for duplicates
  226. ptrOldEp->appendNextHopList(nextHopList);
  227. return itr;
  228. }
  229. /*
  230.   LsPathsTentative methods
  231. */
  232. LsPath LsPathsTentative::popShortestPath() 
  233. {
  234. findMinEqualPaths();
  235. LsPath path;
  236. if (empty() || (minCostIterator == end()))
  237. return path; // an invalid one
  238. LsNodeIdList& nhList = (*minCostIterator).second.nextHopList;
  239. if (nhList.empty() && (findMinEqualPaths() == end()))
  240. return path;
  241. path.destination = (*minCostIterator).first;
  242. path.cost=(*minCostIterator).second.cost;
  243. // the first 'nextHop'
  244. path.nextHop = nhList.front();
  245. nhList.pop_front();
  246. // if this pops out the last nextHop in the EqualPaths, find a new one.
  247. if (nhList.empty()) {
  248. erase(minCostIterator);
  249. findMinEqualPaths();
  250. }
  251. return path;
  252. }
  253. LsPathsTentative::iterator LsPathsTentative::findMinEqualPaths()
  254. {
  255. minCost = LS_MAX_COST + 1; 
  256. minCostIterator = end();
  257. for (iterator itr = begin(); itr != end(); itr++){
  258. if ((minCost > (*itr).second.cost) && 
  259.     !(*itr).second.nextHopList.empty()) {
  260. minCost = (*itr).second.cost;
  261. minCostIterator = itr;
  262. }
  263. }
  264. return minCostIterator;
  265. }
  266. /*
  267.   LsMessageCenter methods
  268. */
  269. LsMessage* LsMessageCenter::newMessage(int nodeId, ls_message_type_t type) 
  270. {
  271. // check if max_message_number is invalid, call init ()
  272. if (max_size == 0)
  273. init(); 
  274. // if max_size reached, recycle
  275. message_storage* storagePtr;
  276. u_int32_t currentId;
  277. // current_lsa_id and current_other_id are odd and even, respectively
  278. if ((type == LS_MSG_LSA) || (type == LS_MSG_TPM)) { 
  279. storagePtr = & lsa_messages;
  280. currentId = current_lsa_id;
  281. if ((current_lsa_id += 2) == LS_INVALID_MESSAGE_ID)  
  282. current_lsa_id += 2;
  283. } else {
  284. storagePtr = &other_messages;
  285. currentId = current_other_id;
  286. if ((current_other_id += 2) == LS_INVALID_MESSAGE_ID)  
  287. current_other_id +=2;
  288. }
  289. if (storagePtr->size() >= max_size)
  290. storagePtr->erase(storagePtr->begin());
  291. LsMessage* msgPtr = (LsMessage *)NULL;
  292. message_storage::iterator itr = 
  293. storagePtr->insert(currentId, 
  294.    LsMessage(currentId, nodeId, type));
  295. if (itr == storagePtr->end())
  296. ls_error("Can't insert new message in "
  297.  "LsMessageCenter::newMessage.n");
  298. else
  299. msgPtr = &((*itr).second);
  300. return msgPtr;
  301. }
  302. bool LsMessageCenter::deleteMessage(u_int32_t msgId)
  303. {
  304. message_storage::iterator itr = other_messages.find (msgId); 
  305. if (itr == other_messages.end())
  306. return false;
  307. other_messages.erase(itr);
  308. return true;
  309. }
  310. // init()
  311. void LsMessageCenter::init() 
  312. {
  313. // only when nothing is provided by tcl code
  314. max_size = 300;
  315. }
  316. /*
  317.   LsMessageHistory methods 
  318. */
  319. // TODO, rewrite this method for topo message
  320. bool LsMessageHistory::isNewMessage ( const LsMessage& msg ) 
  321. {
  322. iterator itr = find(msg.originNodeId_);
  323. if (itr != end()) {
  324. if (((*itr).second < msg.sequenceNumber_) || 
  325.     ((*itr).second - msg.sequenceNumber_ > 
  326.      LS_WRAPAROUND_THRESHOLD)) {
  327. // The new message is more up-to-date than the old one
  328. (*itr).second = msg.sequenceNumber_;
  329. return true;
  330. } else {
  331. // We had a more up-to-date or same message from 
  332. // this node before
  333. return false;
  334. }
  335. } else {
  336. // We never received message from this node before 
  337. insert(msg.originNodeId_, msg.sequenceNumber_);
  338. return true;
  339. }
  340.  
  341. }
  342. /* LsRetransmissionManager Methods */
  343. void LsRetransmissionManager::initTimeout(LsDelayMap * delayMapPtr) 
  344. {
  345. if (delayMapPtr == NULL)
  346. return;
  347. for (LsDelayMap::iterator itr = delayMapPtr->begin();
  348.      itr != delayMapPtr->end(); itr++)
  349. // timeout is LS_TIMEOUT_FACTOR*one-way-delay estimate
  350. insert((*itr).first, 
  351.        LsUnackPeer(this, (*itr).first, 
  352.    LS_TIMEOUT_FACTOR*(*itr).second));
  353. }
  354. void LsRetransmissionManager::cancelTimer (int nbrId) 
  355. {
  356. LsUnackPeer* peerPtr = findPtr(nbrId);
  357. if (peerPtr == NULL) 
  358. return;
  359. peerPtr->tpmSeq_ = LS_INVALID_MESSAGE_ID;
  360. peerPtr->lsaMap_.eraseAll();
  361. peerPtr->timer_.force_cancel();
  362. }
  363. // Called by LsRouting when a message is sent out
  364. int LsRetransmissionManager::messageOut(int peerId, 
  365. const LsMessage& msg)
  366. {
  367. LsUnackPeer* peerPtr = findPtr(peerId);
  368. if (peerPtr == NULL) {
  369. iterator itr = insert(peerId, LsUnackPeer(this, peerId));
  370. if (itr == end()) { 
  371. ls_error ("Can't insert."); 
  372. }
  373. peerPtr = &((*itr).second);
  374. }
  375. LsIdSeq* idSeqPtr;
  376. switch (msg.type_) {
  377. case LS_MSG_TPM:
  378. peerPtr->tpmSeq_ = msg.sequenceNumber_;
  379. break;
  380. case LS_MSG_LSA:
  381. idSeqPtr =  peerPtr->lsaMap_.findPtr(msg.originNodeId_);
  382. if (idSeqPtr == NULL)
  383. peerPtr->lsaMap_.insert(msg.originNodeId_, 
  384.  LsIdSeq(msg.messageId_, msg.sequenceNumber_));
  385. else {
  386. idSeqPtr->msgId_ = msg.messageId_;
  387. idSeqPtr->seq_ = msg.sequenceNumber_;
  388. }
  389. break;
  390. case LS_MSG_TPMACK:
  391. case LS_MSG_LSAACK:
  392. case LS_MSG_LSM:
  393. default:
  394. // nothing, just to avoid compiler warning
  395. break;
  396. }
  397.  
  398. // reschedule timer to allow account for this latest message
  399. peerPtr->timer_.resched(peerPtr->rtxTimeout_);
  400.   
  401. return 0;
  402. }
  403.   
  404. // Called by LsRouting,  when an ack is received
  405. // Or by messageIn, some the message can serve as ack
  406. int LsRetransmissionManager::ackIn(int peerId, const LsMessage& msg)
  407. {
  408. LsUnackPeer* peerPtr = findPtr(peerId);
  409. if ((peerPtr == NULL) ||
  410.     (peerPtr->tpmSeq_ == LS_INVALID_MESSAGE_ID) &&
  411.     peerPtr->lsaMap_.empty())
  412. // no pending ack for this neighbor 
  413. return 0;
  414. LsMap<int, LsIdSeq>::iterator itr;
  415. switch (msg.type_) {
  416. case LS_MSG_TPMACK:
  417. if (peerPtr->tpmSeq_ == msg.sequenceNumber_)
  418. // We've got the right ack, so erase the unack record
  419. peerPtr->tpmSeq_ = LS_INVALID_MESSAGE_ID;
  420. break;
  421. case LS_MSG_LSAACK:
  422. itr = peerPtr->lsaMap_.find(msg.originNodeId_);
  423. if ((itr != peerPtr->lsaMap_.end()) && 
  424.     ((*itr).second.seq_ == msg.sequenceNumber_)) 
  425. // We've got the right ack, so erase the unack record
  426. peerPtr->lsaMap_.erase(itr);
  427. break;
  428. case LS_MSG_TPM:
  429. case LS_MSG_LSA: 
  430. case LS_MSG_LSM:
  431. default:
  432. break;
  433. }
  434. if ((peerPtr->tpmSeq_ == LS_INVALID_MESSAGE_ID) &&
  435.     (peerPtr->lsaMap_.empty()))
  436. // No more pending ack, cancel timer
  437. peerPtr->timer_.cancel();
  438. // ack deleted in calling function LsRouting::receiveMessage
  439. return 0;
  440. }
  441. // resendMessage
  442. int LsRetransmissionManager::resendMessages (int peerId) 
  443. {
  444. LsUnackPeer* peerPtr = findPtr (peerId);
  445. if (peerPtr == NULL) 
  446. // That's funny, We should never get in here
  447. ls_error ("Wait a minute, nothing to send for this neighbor");
  448. // resend topo map
  449. if (peerPtr->tpmSeq_ != LS_INVALID_MESSAGE_ID) 
  450. lsRouting_.resendMessage(peerId, peerPtr->tpmSeq_, LS_MSG_TPM);
  451.   
  452. // resend all other unack'ed LSA
  453. for (LsMap<int, LsIdSeq>::iterator itr = peerPtr->lsaMap_.begin();
  454.      itr != peerPtr->lsaMap_.end(); ++itr)
  455. lsRouting_.resendMessage(peerId, (*itr).second.msgId_, 
  456.  LS_MSG_LSA);
  457. // reschedule retransmit timer
  458. peerPtr->timer_.resched(peerPtr->rtxTimeout_);
  459. return 0;
  460. /*
  461.   LsRouting methods
  462. */
  463. bool LsRouting::init(LsNode * nodePtr) 
  464. {
  465. if (nodePtr == NULL) 
  466. return false;
  467. myNodePtr_ = nodePtr;
  468. myNodeId_ = myNodePtr_->getNodeId();
  469. linkStateDatabase_.setNodeId(myNodeId_);
  470. peerIdListPtr_ = myNodePtr_->getPeerIdListPtr();
  471. linkStateListPtr_ = myNodePtr_->getLinkStateListPtr();
  472. if (linkStateListPtr_ != NULL) 
  473. linkStateDatabase_.insert(myNodeId_, *linkStateListPtr_);
  474. LsDelayMap* delayMapPtr = myNodePtr_->getDelayMapPtr();
  475. if (delayMapPtr != NULL)
  476. ackManager_.initTimeout(delayMapPtr) ;
  477. return true;
  478. }  
  479. void LsRouting::linkStateChanged () 
  480. {
  481. if (linkStateListPtr_ == NULL)
  482. ls_error("LsRouting::linkStateChanged: linkStateListPtr nulln");
  483.    
  484. LsLinkStateList* oldLsPtr = linkStateDatabase_.findPtr(myNodeId_);
  485. if (oldLsPtr == NULL) 
  486. // Should never happen,something's wrong, we didn't 
  487. // initialize properly
  488. ls_error("LsRouting::linkStateChanged: oldLsPtr null!!n");
  489. // save the old link state for processing
  490. LsLinkStateList oldlsl(*oldLsPtr);
  491. // if there's any changes, compute new routes and send link states
  492. // Note: we do want to send link states before topo
  493. bool changed=linkStateDatabase_.update(myNodeId_, *linkStateListPtr_);
  494. if (changed) {
  495. computeRoutes();
  496. sendLinkStates(/* buffer before sending */ true); 
  497. // tcl code will call sendBufferedMessage
  498. }
  499. // Check if there's need to send topo or cancel timer
  500. LsLinkStateList::iterator oldLsItr = oldlsl.begin();
  501. for (LsLinkStateList::iterator newLsItr = linkStateListPtr_->begin();
  502.       newLsItr != linkStateListPtr_->end();
  503.       newLsItr++, oldLsItr++) {
  504. // here we are assuming the two link state list are the same 
  505. // except the status and costs, buggy    
  506. if ((*newLsItr).neighborId_ != (*oldLsItr).neighborId_)
  507. // something's wrong
  508. ls_error("New and old link State list are not aligned.n");
  509. // if link goes down, clear neighbor's not ack'ed entry
  510. if ((*newLsItr).status_ == LS_STATUS_DOWN)
  511. ackManager_.cancelTimer((*newLsItr).neighborId_);
  512. if (((*newLsItr).status_ == LS_STATUS_DOWN) || 
  513.     ((*oldLsItr).status_ == LS_STATUS_UP))
  514. // Don't have to send out tpm if the link goes from 
  515. // up to down, or it was originally up
  516. continue;
  517. // else we have to set out the whole topology map that we have 
  518. // to our neighbor that just resumes peering with us
  519. // the messages are buffered, will flush the buffer after the 
  520. // routes are installed in the node
  521. // But don't worry, only a const ptr to our topo map is sent
  522. sendTopo( (*newLsItr).neighborId_);
  523. }
  524. }
  525. /* -- isUp -- */
  526. // a linear search, but not too bad if most nodes will have 
  527. // less than a couple of interfaces
  528. bool LsRouting::isUp(int neighborId) 
  529. {
  530. if (linkStateListPtr_ == NULL) 
  531. return false;
  532. for (LsLinkStateList::iterator itr = linkStateListPtr_->begin();
  533.      itr!= linkStateListPtr_->end(); itr++)
  534. if ((*itr).neighborId_ == neighborId)
  535. return ((*itr).status_ == LS_STATUS_UP) ? true : false;
  536. return false;
  537. }
  538. /* -- receiveMessage -- */
  539. /* return true if there's a need to re-compute routes */
  540. bool LsRouting::receiveMessage (int senderId, u_int32_t msgId)
  541. {
  542. if (senderId == LS_INVALID_NODE_ID)
  543. return false;
  544. LsMessage* msgPtr = msgctr().retrieveMessagePtr(msgId);
  545. if (msgPtr == NULL)
  546. return false;
  547. // A switch statement to see the type.
  548. // and handle differently
  549. bool retCode = false;
  550. switch (msgPtr->type_){
  551. case LS_MSG_LSM:
  552. // not supported yet
  553. break;
  554. case LS_MSG_TPM:
  555. retCode = receiveTopo (senderId, msgPtr);
  556. break;
  557. case LS_MSG_LSA:  // Link State Update 
  558. retCode = receiveLSA (senderId, msgPtr);
  559. break;
  560. case LS_MSG_LSAACK: 
  561. case LS_MSG_TPMACK: 
  562. receiveAck(senderId, msgPtr);
  563. msgctr().deleteMessage(msgId);
  564. break;
  565. default:
  566. break;
  567. }
  568. return retCode;
  569. }
  570. // LsRouting::receiveAck is in-line in header file
  571. bool LsRouting::receiveLSA(int senderId, LsMessage* msgPtr)
  572. {
  573. if (msgPtr == NULL) 
  574. return false;
  575. u_int32_t msgId = msgPtr->messageId_;
  576. int originNodeId = msgPtr->originNodeId_;
  577. sendAck(senderId, LS_MSG_LSAACK, originNodeId, msgId);
  578.        
  579. if ((originNodeId == myNodeId_) ||
  580.      !lsaHistory_.isNewMessage(*msgPtr)) 
  581. return false; 
  582. // looks like we've got a new message LSA
  583. int peerId;
  584. if ((peerIdListPtr_ != NULL) && (myNodePtr_ != NULL)) {
  585. // forwards to peers whose links are up, except the sender 
  586. // and the originator 
  587. for (LsNodeIdList::iterator itr = peerIdListPtr_->begin();
  588.      itr != peerIdListPtr_->end(); itr++) {
  589. peerId = *itr;
  590. if ((peerId == originNodeId) || (peerId == senderId))
  591. continue; 
  592. if (isUp(peerId) && ((peerId) != senderId)) {
  593. ackManager_.messageOut(peerId, *msgPtr);
  594. myNodePtr_->sendMessage(peerId, msgId);
  595. }
  596. }
  597. }
  598. // Get the content of the message 
  599. if (msgPtr->contentPtr_ == NULL) 
  600. return false;
  601. bool changed = linkStateDatabase_.update(msgPtr->originNodeId_,
  602.  *(msgPtr->lslPtr_));
  603. if (changed)
  604. // linkstate database has changed, re-compute routes
  605. computeRoutes();
  606. return changed;
  607. }
  608. // -- sendLinkStates --
  609. bool LsRouting::sendLinkStates(bool buffer /* = false */) 
  610. {
  611. if (myNodePtr_ == NULL)
  612. return false;
  613. if ((peerIdListPtr_ == NULL) || peerIdListPtr_->empty())
  614. return false;
  615. LsLinkStateList* myLSLptr = linkStateDatabase_.findPtr(myNodeId_);
  616. if ((myLSLptr == NULL) || myLSLptr->empty())
  617. return false;
  618. LsMessage* msgPtr = msgctr().newMessage(myNodeId_, LS_MSG_LSA);
  619. if (msgPtr == NULL) 
  620. return false; // can't get new message
  621. u_int32_t msgId = msgPtr->messageId_;
  622. u_int32_t seq = msgPtr->sequenceNumber_;
  623. // update the sequence number in my own data base
  624. for (LsLinkStateList::iterator itr = myLSLptr->begin();
  625.      itr != myLSLptr->end(); itr++)
  626. (*itr).sequenceNumber_ = seq;
  627.   
  628. LsLinkStateList* newLSLptr = new LsLinkStateList( *myLSLptr);
  629. if (newLSLptr == NULL) {
  630. ls_error ("Can't get new link state list, in LsRouting::sendLinkStatesn");
  631. // can't get new link state list
  632. msgctr().deleteMessage(msgId);
  633. return false;
  634. }
  635. msgPtr->lslPtr_ = newLSLptr;
  636. for (LsNodeIdList::iterator itr = peerIdListPtr_->begin();
  637.      itr != peerIdListPtr_->end(); itr++) {
  638. if (!isUp(*itr))
  639. continue; // link is down 
  640. if (!buffer) {
  641. myNodePtr_->sendMessage((*itr), msgId);
  642. ackManager_.messageOut((*itr), *msgPtr);
  643. } else {
  644. // put in buffer for later sending
  645. bufferedSend((*itr), msgPtr);
  646. }
  647. }
  648. return true;
  649. }
  650. // send acknowledgment, called self
  651. bool LsRouting::sendAck (int nbrId, ls_message_type_t type, 
  652.  int originNodeIdAcked, u_int32_t seqAcked) 
  653. {
  654. // Get a new message fom messageCenter
  655. LsMessage * msgPtr = msgctr().newMessage(myNodeId_, type);
  656. if (msgPtr == NULL)
  657. return false; // can't get new message
  658. u_int32_t msgId = msgPtr->messageId_;
  659. // fill in the blank
  660. // msgPtr->type = type;
  661. msgPtr->originNodeId_ = originNodeIdAcked;
  662. msgPtr->sequenceNumber_ = seqAcked;
  663. // Call node to send out message
  664. myNodePtr_->sendMessage (nbrId, msgId, LS_ACK_MESSAGE_SIZE);
  665. return true;
  666. }
  667. // After a link comes up, receive Topology update from the 
  668. // corresponding neighbor
  669. bool LsRouting::receiveTopo(int neighborId, LsMessage * msgPtr)
  670. {
  671. // TODO
  672. bool changed = false;
  673. // send Ack 
  674. sendAck(neighborId, LS_MSG_TPMACK, neighborId, 
  675. msgPtr->sequenceNumber_);
  676. // check if it's a new message
  677. if (!tpmHistory_.isNewMessage(*msgPtr))
  678. return false;
  679. if (msgPtr->topoPtr_ == NULL)
  680. return false;
  681. // Compare with my own database
  682. for (LsTopoMap::const_iterator recItr = msgPtr->topoPtr_->begin();
  683.      recItr != msgPtr->topoPtr_->end(); recItr++) {
  684. if ((*recItr).first == myNodeId_)
  685. // Don't need peer to tell me my own link state 
  686. continue; 
  687. // find my own record of the LSA of the node being examined
  688. LsLinkStateList* myRecord = 
  689. linkStateDatabase_.findPtr((*recItr).first);
  690. if ((myRecord == NULL) || // we don't have it
  691.     myRecord->empty() ||
  692.     // or we have an older record
  693.     ((*(myRecord->begin())).sequenceNumber_ <
  694.      (*((*recItr).second.begin())).sequenceNumber_) ||
  695.     ((*(myRecord->begin())).sequenceNumber_ - 
  696.      (*((*recItr).second.begin())).sequenceNumber_ > 
  697.      LS_WRAPAROUND_THRESHOLD)) {
  698. // Update our database
  699. changed = true;
  700. if (myRecord == NULL)
  701. linkStateDatabase_.insert((*recItr).first, 
  702.  (*recItr).second);
  703. else 
  704. *myRecord = (*recItr).second ;
  705. // Regenerate the LSA message and send to my peers, 
  706. // except the sender of the topo and the 
  707. // originator of the LSA
  708. regenAndSend (/* to except */neighborId, 
  709.       /* originator */(*recItr).first, 
  710.       /* the linkstateList */(*recItr).second);
  711. }
  712. }
  713. if (changed)
  714. computeRoutes();
  715. // if anything relevant has changed, recompute routes
  716. return changed;
  717. }
  718. // replicate a LSA and send it out
  719. void LsRouting::regenAndSend(int exception, int origin, 
  720.      const LsLinkStateList& lsl)
  721. {
  722. if (lsl.empty())
  723. ls_error("lsl is empty, in LsRouting::regenAndSend.n");
  724. LsLinkStateList* newLSLptr = new LsLinkStateList(lsl);
  725. if (newLSLptr == NULL) { 
  726. ls_error("Can't get new link state list, in "
  727.  "LsRouting::sendLinkStatesn");
  728. return;
  729. }
  730. // replicate the LSA 
  731. LsMessage* msgPtr =  msgctr().newMessage(origin, LS_MSG_LSA);
  732. msgPtr->sequenceNumber_ = (*lsl.begin()).sequenceNumber_;
  733. msgPtr->originNodeId_ = origin;
  734. for (LsNodeIdList::iterator itr = peerIdListPtr_->begin();
  735.      itr != peerIdListPtr_->end(); itr++) {
  736. if ((*itr == origin) || (*itr == exception) || !isUp(*itr))
  737. continue; 
  738. bufferedSend(*itr, msgPtr);
  739. // debug 
  740. //   cout << "Node " << myNodeId << " regenAndSend " 
  741. //        << (*(lsl.begin())).sequenceNumber << " from origin  " << origin 
  742. //        << " to peer " << *itr << endl;
  743. }
  744. }
  745.        
  746. // After a link comes up, receive Topo with the corresponding neighbor
  747. void LsRouting::sendTopo(int neighborId) 
  748. {
  749. // if we've gone so far, messageCenterPtr should not be null, 
  750. // don't check
  751. LsMessage* msgPtr= msgctr().newMessage(myNodeId_, LS_MSG_TPM);
  752. // XXX, here we are going to send the pointer that points
  753. // to my own topo, because sending the who topomap is too costly in
  754. // simulation
  755. msgPtr->contentPtr_ = &linkStateDatabase_;
  756. bufferedSend(neighborId, msgPtr);
  757. }
  758. void LsRouting::sendBufferedMessages()
  759. {
  760. for (MessageBuffer::iterator itr = messageBuffer_.begin();
  761.      itr != messageBuffer_.end(); itr++) {
  762. ackManager_.messageOut((*itr).peerId_, *((*itr).msgPtr_));
  763. myNodePtr_->sendMessage((*itr).peerId_, 
  764. (*itr).msgPtr_->messageId_,
  765. msgSizes[(*itr).msgPtr_->type_]);
  766. }
  767. messageBuffer_.eraseAll();
  768. }
  769. // private _computeRoutes, called by public computeRoutes
  770. LsPaths* LsRouting::_computeRoutes () 
  771. {
  772. LsPathsTentative* pTentativePaths = new LsPathsTentative();
  773. LsPaths* pPaths = new LsPaths() ; // to be returned; 
  774.  
  775. // step 1. put myself in path
  776. LsPath toSelf(myNodeId_, 0, myNodeId_); // zero cost, nextHop is myself
  777. pPaths->insertPathNoChecking(toSelf);
  778. int newNodeId = myNodeId_;
  779. LsLinkStateList * ptrLSL = linkStateDatabase_.findPtr(newNodeId);
  780. if (ptrLSL == NULL )
  781. // don't have my own linkState
  782. return pPaths;
  783. bool done = false;
  784. // start the loop
  785. while (! done) {
  786. // Step 2. for the new node just put in path
  787. // find the next hop to the new node
  788. LsNodeIdList nhl;
  789. LsNodeIdList *nhlp = &nhl; // nextHopeList pointer
  790.     
  791. if (newNodeId != myNodeId_) {
  792. // if not looking at my own links, find the next hop 
  793. // to new node
  794. nhlp = pPaths->lookupNextHopListPtr(newNodeId);
  795. if (nhlp == NULL)
  796. ls_error("computeRoutes: nhlp == NULL n");
  797. }
  798. // for each of it's links
  799. for (LsLinkStateList::iterator itrLink = ptrLSL->begin();
  800.      itrLink != ptrLSL->end(); itrLink++) {
  801. if ((*itrLink).status_ != LS_STATUS_UP)
  802. // link is not up, skip this link
  803. continue;
  804. int dest = (*itrLink).neighborId_;
  805. int path_cost = (*itrLink).cost_ + 
  806. pPaths->lookupCost(newNodeId);
  807. if (pPaths->lookupCost(dest) < path_cost)
  808. // better path already in paths, 
  809. // move on to next link
  810. continue;
  811. else {
  812. // else we have a new or equally good path, 
  813. // LsPathsTentative::insertPath(...) will 
  814. // take care of checking if the new path is
  815. // a better or equally good one, etc.
  816. LsNodeIdList nextHopList;
  817. if (newNodeId == myNodeId_) {
  818. // destination is directly connected, 
  819. // nextHop is itself
  820. nextHopList.push_back(dest);
  821. nhlp = &nextHopList;
  822. }
  823. pTentativePaths->insertNextHopList(dest, 
  824.    path_cost, *nhlp);
  825. }
  826. }
  827. done = true;
  828. // if tentatives empty, terminate;
  829. while (!pTentativePaths->empty()) {
  830. // else pop shortest path triple from tentatives
  831. LsPath sp = pTentativePaths->popShortestPath();
  832. if (!sp.isValid())
  833. ls_error (" popShortestPath() failedn");
  834. // install the newly found shortest path among 
  835. // tentatives
  836. pPaths->insertPath(sp);
  837. newNodeId = sp.destination;
  838. ptrLSL = linkStateDatabase_.findPtr(newNodeId);
  839. if (ptrLSL != NULL) {
  840. // if we have the link state for the new node
  841. // break out of inner do loop to continue 
  842. // computing routes
  843. done = false;
  844. break;
  845. // else  we don't have linkstate for this new node, 
  846. // we need to keep popping shortest paths
  847. }
  848. } // endof while ( ! done );
  849. delete pTentativePaths;
  850. return pPaths;
  851. }
  852. #endif //HAVE_STL