00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef ns_ls_h
00040 #define ns_ls_h
00041
00042 #include <sys/types.h>
00043 #include <list>
00044 #include <map>
00045 #include <utility>
00046
00047 #include "timer-handler.h"
00048
00049 const int LS_INVALID_COUNT = -1;
00050 const int LS_INIT_ACCESS_COUNT = 3;
00051 const int LS_INVALID_NODE_ID = 65535;
00052 const int LS_INVALID_COST = 65535;
00053 const int LS_MIN_COST = 0;
00054 const int LS_MAX_COST = 65534;
00055 const int LS_MESSAGE_CENTER_SIZE_FACTOR = 4;
00056 const int LS_DEFAULT_MESSAGE_SIZE = 100;
00057 const int LS_LSA_MESSAGE_SIZE = 100;
00058 const double LS_RTX_TIMEOUT = 0.002;
00059 const int LS_TIMEOUT_FACTOR = 3;
00060
00061 const int LS_TOPO_MESSAGE_SIZE = 200;
00062 const int LS_ACK_MESSAGE_SIZE = 20;
00063 const unsigned int LS_INVALID_MESSAGE_ID = 0;
00064 const unsigned int LS_BIG_NUMBER = 1048576;
00065 const unsigned int LS_WRAPAROUND_THRESHOLD = 1073741824;
00066 const unsigned int LS_MESSAGE_TYPES = 6;
00067
00068 enum ls_status_t {
00069 LS_STATUS_DOWN = 0,
00070 LS_STATUS_UP = 1
00071 };
00072
00073 enum ls_message_type_t {
00074 LS_MSG_INVALID = 0,
00075 LS_MSG_LSA = 1,
00076 LS_MSG_TPM = 2,
00077 LS_MSG_LSAACK = 3,
00078 LS_MSG_TPMACK = 4,
00079 LS_MSG_LSM = 5,
00080 };
00081
00082 template <class _Tp>
00083 class LsList : public list<_Tp> {
00084 public:
00085 typedef list<_Tp> baseList;
00086 LsList() : baseList() {}
00087 LsList(const _Tp& x) : baseList(1, x) {}
00088 void eraseAll() {
00089 baseList::erase(begin(), end());
00090 }
00091 LsList<_Tp>& operator= (const LsList<_Tp> & x) {
00092 return (LsList<_Tp> &)baseList::operator= (x);
00093 }
00094 };
00095
00096 template<class Key, class T>
00097 class LsMap : public map<Key, T, less<Key> > {
00098 public:
00099 typedef less<Key> less_key;
00100 typedef map<Key, T, less_key> baseMap;
00101 LsMap() : baseMap() {}
00102
00103
00104 typedef typename map<Key, T, less<Key> >::iterator iterator;
00105 typedef pair<iterator, bool> pair_iterator_bool;
00106 iterator insert(const Key & key, const T & item) {
00107 typename baseMap::value_type v(key, item);
00108 pair_iterator_bool ib = baseMap::insert(v);
00109 return ib.second ? ib.first : baseMap::end();
00110 }
00111
00112 void eraseAll() { erase(begin(), end()); }
00113 T* findPtr(Key key) {
00114 iterator it = baseMap::find(key);
00115 return (it == baseMap::end()) ? (T *)NULL : &((*it).second);
00116 }
00117 };
00118
00119
00120
00121
00122 class LsNodeIdList : public LsList<int> {
00123 public:
00124 int appendUnique (const LsNodeIdList& x);
00125 };
00126
00127
00128
00129
00130
00131 struct LsLinkState {
00132
00133 int neighborId_;
00134 ls_status_t status_;
00135 int cost_;
00136 u_int32_t sequenceNumber_;
00137
00138
00139 LsLinkState() : neighborId_(LS_INVALID_NODE_ID),
00140 status_(LS_STATUS_DOWN), cost_(LS_INVALID_COST) {}
00141 LsLinkState(int id, ls_status_t s, int c) : neighborId_(id),
00142 status_(s), cost_(c) {}
00143
00144 void init (int nbId, ls_status_t s, int c){
00145 neighborId_ = nbId;
00146 status_ = s;
00147 cost_ =c;
00148 }
00149 } ;
00150
00151
00152
00153
00154 typedef LsList<LsLinkState> LsLinkStateList;
00155
00156
00157
00158
00159
00160
00161
00162 typedef LsMap<int, LsLinkStateList> LsLinkStateListMap;
00163
00164 class LsTopoMap : public LsLinkStateListMap {
00165 public:
00166
00167
00168 LsTopoMap() : LsLinkStateListMap() {}
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 LsLinkStateList* insertLinkState(int nodeId,
00180 const LsLinkState& linkState);
00181
00182 bool update(int nodeId, const LsLinkStateList& linkStateList);
00183
00184 void setNodeId(int id) { myNodeId_ = id ;}
00185 private:
00186 int myNodeId_;
00187 };
00188
00189 typedef LsTopoMap LsTopology;
00190 typedef LsTopoMap* LsTopoMapPtr;
00191
00192
00193
00194
00195 struct LsPath {
00196 LsPath() : destination (LS_INVALID_NODE_ID) {}
00197 LsPath(int dest, int c, int nh)
00198 : destination (dest), cost(c), nextHop(nh) {}
00199
00200 bool isValid() {
00201 return ((destination != LS_INVALID_NODE_ID) &&
00202 (cost != LS_INVALID_COST) &&
00203 (nextHop != LS_INVALID_COST));
00204 }
00205
00206
00207 int destination;
00208 int cost;
00209 int nextHop;
00210 };
00211
00212
00213
00214
00215
00216 struct LsEqualPaths {
00217 public:
00218 int cost;
00219 LsNodeIdList nextHopList;
00220
00221
00222 LsEqualPaths() : cost(LS_INVALID_COST) {}
00223 LsEqualPaths(int c, int nh) : cost(c), nextHopList() {
00224 nextHopList.push_back(nh);
00225 }
00226 LsEqualPaths(const LsPath & path) : cost (path.cost), nextHopList() {
00227 nextHopList.push_back(path.nextHop);
00228 }
00229 LsEqualPaths(int c, const LsNodeIdList & nhList)
00230 : cost(c), nextHopList(nhList) {}
00231
00232 LsEqualPaths& operator = (const LsEqualPaths & x ) {
00233 cost = x.cost;
00234 nextHopList = x.nextHopList;
00235 return *this;
00236 }
00237
00238
00239 LsEqualPaths& copy(const LsEqualPaths & x) { return operator = (x) ;}
00240
00241
00242 int appendNextHopList(const LsNodeIdList & nhl) {
00243 return nextHopList.appendUnique (nhl);
00244 }
00245 };
00246
00247
00248
00249
00250 typedef LsMap< int, LsEqualPaths > LsEqualPathsMap;
00251
00252
00253
00254
00255 class LsPaths : public LsEqualPathsMap {
00256 public:
00257 LsPaths(): LsEqualPathsMap() {}
00258
00259
00260 iterator begin() { return LsEqualPathsMap::begin();}
00261 iterator end() { return LsEqualPathsMap::end();}
00262
00263
00264
00265 int lookupCost(int destId) {
00266 LsEqualPaths * pEP = findPtr (destId);
00267 if ( pEP == NULL ) return LS_MAX_COST + 1;
00268
00269 return pEP->cost;
00270 }
00271
00272
00273 LsNodeIdList* lookupNextHopListPtr(int destId) {
00274 LsEqualPaths* pEP = findPtr(destId);
00275 if (pEP == NULL )
00276 return (LsNodeIdList *) NULL;
00277
00278 return &(pEP->nextHopList);
00279 }
00280
00281
00282 iterator insertPathNoChecking(int destId, int cost, int nextHop) {
00283 LsEqualPaths ep(cost, nextHop);
00284 iterator itr = insert(destId, ep);
00285 return itr;
00286 }
00287
00288
00289 iterator insertPathNoChecking (const LsPath & path) {
00290 return insertPathNoChecking(path.destination, path.cost,
00291 path.nextHop);
00292 }
00293
00294 iterator insertPath(int destId, int cost, int nextHop);
00295 iterator insertPath(const LsPath& path) {
00296 return insertPath(path.destination, path.cost, path.nextHop);
00297 }
00298
00299 iterator insertNextHopList(int destId, int cost,
00300 const LsNodeIdList& nextHopList);
00301 };
00302
00303
00304
00305
00306 class LsPathsTentative : public LsPaths {
00307 public:
00308 LsPathsTentative() : LsPaths(), minCost(LS_MAX_COST+1) {
00309 minCostIterator = end();
00310 }
00311
00312
00313 LsPath popShortestPath();
00314
00315 private:
00316 int minCost;
00317 iterator minCostIterator;
00318 iterator findMinEqualPaths();
00319 };
00320
00321
00322
00323
00324 struct LsMessage {
00325 LsMessage() : type_(LS_MSG_INVALID), contentPtr_(NULL) {}
00326 LsMessage(u_int32_t id, int nodeId, ls_message_type_t t) :
00327 type_(t), messageId_(id),
00328 sequenceNumber_(id), originNodeId_(nodeId),
00329 contentPtr_(NULL) {}
00330 ~LsMessage() {
00331 if ((type_ == LS_MSG_LSM) && (lslPtr_ != NULL)) {
00332 delete lslPtr_;
00333 lslPtr_ = NULL;
00334 }
00335 }
00336 ls_message_type_t type_;
00337 u_int32_t messageId_;
00338 u_int32_t sequenceNumber_;
00339 int originNodeId_;
00340 union {
00341 LsLinkStateList* lslPtr_;
00342 const LsTopoMap* topoPtr_;
00343 void* contentPtr_;
00344 };
00345 };
00346
00347
00348
00349
00350
00351 struct LsMessageInfo
00352 {
00353 ls_message_type_t type_;
00354 int destId_;
00355 u_int32_t msgId_;
00356 u_int32_t sequenceNumber_;
00357 union {
00358
00359 int originNodeId_;
00360
00361 int originNodeIdAck_;
00362 };
00363
00364 LsMessageInfo() {}
00365 LsMessageInfo(int d, const LsMessage& msg ) :
00366 type_(msg.type_), destId_(d), msgId_(msg.messageId_),
00367 sequenceNumber_(msg.sequenceNumber_),
00368 originNodeId_(msg.originNodeId_) {}
00369 LsMessageInfo(int d , ls_message_type_t t, int o,
00370 u_int32_t seq, u_int32_t mId) :
00371 type_(t), destId_(d), msgId_(mId), sequenceNumber_(seq),
00372 originNodeId_(o) {}
00373 };
00374
00375
00376
00377
00378 class LsMessageCenter {
00379 public:
00380 typedef LsMap <u_int32_t, LsMessage> baseMap;
00381
00382 LsMessageCenter ()
00383 : current_lsa_id(LS_INVALID_MESSAGE_ID + 1),
00384 current_other_id(LS_INVALID_MESSAGE_ID + 2),
00385 max_size(0), lsa_messages(), other_messages() {}
00386
00387 void setNodeNumber (int number_of_nodes) {
00388 max_size = number_of_nodes * LS_MESSAGE_CENTER_SIZE_FACTOR;
00389 }
00390 LsMessage* newMessage (int senderNodeId, ls_message_type_t type);
00391 u_int32_t duplicateMessage( u_int32_t msgId) {
00392 return msgId;
00393 }
00394 u_int32_t duplicateMessage(const LsMessage& msg) {
00395 return duplicateMessage(msg.messageId_);
00396 }
00397 bool deleteMessage(u_int32_t msgId) ;
00398 bool deleteMessage (const LsMessage& msg) {
00399 return deleteMessage(msg.messageId_);
00400 }
00401 LsMessage* retrieveMessagePtr(u_int32_t msgId){
00402 if (isLSA(msgId)) {
00403 return lsa_messages.findPtr(msgId);
00404 } else {
00405 return other_messages.findPtr(msgId);
00406 }
00407 }
00408 static LsMessageCenter& instance() {
00409 return msgctr_;
00410 }
00411
00412 private:
00413 static LsMessageCenter msgctr_;
00414
00415 u_int32_t current_lsa_id ;
00416 u_int32_t current_other_id;
00417 unsigned int max_size;
00418 typedef LsMap <u_int32_t, LsMessage > message_storage;
00419 message_storage lsa_messages;
00420 message_storage other_messages;
00421 void init();
00422 int isLSA (u_int32_t msgId) {
00423
00424
00425 return (0x1 & (msgId ^ LS_INVALID_MESSAGE_ID));
00426 }
00427 };
00428
00429
00430
00431
00432 typedef LsList<u_int32_t> LsMessageIdList;
00433 typedef less<int> less_node_id;
00434 class LsMessageHistory : public LsMap<int, u_int32_t> {
00435 public:
00436
00437 bool isNewMessage ( const LsMessage & msg );
00438 };
00439
00440 class LsRetransmissionManager;
00441 class LsRetransTimer : public TimerHandler {
00442 public:
00443 LsRetransTimer() {}
00444 LsRetransTimer (LsRetransmissionManager *amp , int nbrId)
00445 : ackManagerPtr_(amp), neighborId_(nbrId) {}
00446 virtual void expire(Event *e);
00447 protected:
00448 LsRetransmissionManager* ackManagerPtr_;
00449 int neighborId_;
00450 };
00451
00452 struct LsIdSeq {
00453 u_int32_t msgId_;
00454 u_int32_t seq_;
00455 LsIdSeq() {}
00456 LsIdSeq(u_int32_t id, u_int32_t s) : msgId_(id), seq_(s) {}
00457 };
00458
00459
00460
00461
00462
00463 struct LsUnackPeer {
00464 double rtxTimeout_;
00465 LsRetransTimer timer_;
00466 u_int32_t tpmSeq_;
00467
00468 LsMap<int, LsIdSeq> lsaMap_;
00469
00470
00471 LsUnackPeer() : tpmSeq_(LS_INVALID_MESSAGE_ID) {}
00472 LsUnackPeer(LsRetransmissionManager* amp, int nbrId,
00473 double timeout = LS_RTX_TIMEOUT) :
00474 rtxTimeout_(timeout), timer_(amp, nbrId),
00475 tpmSeq_(LS_INVALID_MESSAGE_ID) {}
00476 };
00477
00478
00479
00480
00481
00482 typedef LsMap< int, double > LsDelayMap;
00483
00484
00485
00486
00487 class LsRouting;
00488 class LsRetransmissionManager : public LsMap<int, LsUnackPeer> {
00489 public:
00490 LsRetransmissionManager(LsRouting& lsr) : lsRouting_(lsr) {}
00491
00492 void initTimeout(LsDelayMap* delayMapPtr);
00493 void cancelTimer(int neighborId);
00494
00495
00496 int messageOut(int peerId, const LsMessage& msg);
00497
00498
00499 int ackIn(int peerId, const LsMessage& ack);
00500
00501
00502 int resendMessages(int peerId);
00503
00504 private:
00505
00506 LsRouting& lsRouting_;
00507 };
00508
00509 inline void LsRetransTimer::expire(Event *e)
00510 {
00511 ackManagerPtr_->resendMessages(neighborId_);
00512 }
00513
00514
00515
00516
00517
00518
00519
00520 class LsNode {
00521 public:
00522 virtual bool sendMessage(int destId, u_int32_t msgId,
00523 int msgsz = LS_DEFAULT_MESSAGE_SIZE) = 0;
00524 virtual void receiveMessage(int sender, u_int32_t msgId) = 0;
00525
00526
00527
00528
00529 virtual int getNodeId() = 0;
00530 virtual LsLinkStateList* getLinkStateListPtr()= 0;
00531 virtual LsNodeIdList* getPeerIdListPtr() = 0;
00532 virtual LsDelayMap* getDelayMapPtr() = 0;
00533 };
00534
00535
00536
00537
00538 class LsRouting {
00539 public:
00540 static int msgSizes[ LS_MESSAGE_TYPES ];
00541 friend class LsRetransmissionManager;
00542
00543
00544 LsRouting() : myNodePtr_(NULL), myNodeId_(LS_INVALID_NODE_ID),
00545 peerIdListPtr_(NULL), linkStateListPtr_(NULL),
00546 routingTablePtr_(NULL),
00547 linkStateDatabase_(), lsaHistory_(), ackManager_(*this) {}
00548 ~LsRouting() {
00549
00550 if (routingTablePtr_ != NULL)
00551 delete routingTablePtr_;
00552 }
00553
00554 bool init(LsNode* nodePtr);
00555 void computeRoutes() {
00556 if (routingTablePtr_ != NULL)
00557 delete routingTablePtr_;
00558 routingTablePtr_ = _computeRoutes();
00559 }
00560 LsEqualPaths* lookup(int destId) {
00561 return (routingTablePtr_ == NULL) ?
00562 (LsEqualPaths *)NULL :
00563 routingTablePtr_->findPtr(destId);
00564 }
00565
00566
00567 bool sendLinkStates(bool buffer = false);
00568 void linkStateChanged();
00569 void sendBufferedMessages() ;
00570
00571
00572 bool receiveMessage(int senderId , u_int32_t msgId);
00573
00574 private:
00575
00576
00577 LsNode * myNodePtr_;
00578 int myNodeId_;
00579 LsNodeIdList* peerIdListPtr_;
00580 LsLinkStateList* linkStateListPtr_;
00581 LsMessageCenter* messageCenterPtr_;
00582 LsPaths* routingTablePtr_;
00583 LsTopoMap linkStateDatabase_;
00584 LsMessageHistory lsaHistory_;
00585 LsMessageHistory tpmHistory_;
00586 LsRetransmissionManager ackManager_;
00587
00588 struct IdMsgPtr {
00589 int peerId_;
00590 const LsMessage* msgPtr_;
00591 IdMsgPtr() {};
00592 IdMsgPtr(int id, const LsMessage* p) :
00593 peerId_(id), msgPtr_(p) {}
00594 };
00595 typedef LsList<IdMsgPtr> MessageBuffer;
00596 MessageBuffer messageBuffer_;
00597
00598 private:
00599 LsMessageCenter& msgctr() { return LsMessageCenter::instance(); }
00600 LsPaths* _computeRoutes();
00601 bool isUp(int neighborId);
00602
00603 bool receiveAck (int neighborId, LsMessage* msgPtr) {
00604 ackManager_.ackIn(neighborId, *msgPtr);
00605 return true;
00606 }
00607 bool receiveLSA (int neighborId, LsMessage* msgPtr);
00608 bool receiveTopo(int neighborId, LsMessage* msgPtr);
00609
00610
00611
00612
00613 void sendTopo(int neighborId);
00614 void regenAndSend(int exception, int origin,
00615 const LsLinkStateList& lsl);
00616 bool sendAck(int nbrId, ls_message_type_t type,
00617 int originNodeIdAcked, u_int32_t originMsgIdAcked);
00618 void resendMessage(int neighborId, u_int32_t msgId,
00619 ls_message_type_t type) {
00620 myNodePtr_->sendMessage(neighborId, msgId, msgSizes[type]);
00621 }
00622
00623
00624 void bufferedSend (int peerId, const LsMessage* mp) {
00625 messageBuffer_.push_back(IdMsgPtr(peerId, mp));
00626 }
00627 };
00628
00629 #endif // ns_ls_h