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
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #include "config.h"
00065 #ifdef HAVE_STL
00066
00067 #include "hdr-ls.h"
00068 #include "rtProtoLS.h"
00069 #include "agent.h"
00070 #include "string.h"
00071
00072
00073 class LsTokenList : public LsList<char *> {
00074 public:
00075 LsTokenList (char * str, const char * delim )
00076 : LsList<char*> () {
00077 for ( char * token = strtok (str, delim);
00078 token != NULL; token = strtok(NULL, delim) ) {
00079 push_back (token);
00080 }
00081 }
00082 };
00083
00084 class LsIntList : public LsList<int> {
00085 public:
00086 LsIntList (const char * str, const char * delim)
00087 : LsList<int> () {
00088 for ( char * token = strtok ((char *)str, delim);
00089 token != NULL; token = strtok(NULL, delim) ) {
00090 push_back ( atoi(token) );
00091 }
00092 }
00093 };
00094
00095 static class rtProtoLSclass : public TclClass {
00096 public:
00097 rtProtoLSclass() : TclClass("Agent/rtProto/LS") {}
00098 TclObject* create(int, const char*const*) {
00099 return (new rtProtoLS);
00100 }
00101 } class_rtProtoLS;
00102
00103
00104 int rtProtoLS::command(int argc, const char*const* argv)
00105 {
00106 if (strcmp(argv[1], "send-update") == 0) {
00107 ns_addr_t dst;
00108 dst.addr_ = atoi(argv[2]);
00109 dst.port_ = atoi(argv[3]);
00110 u_int32_t mtvar = atoi(argv[4]);
00111 u_int32_t size = atoi(argv[5]);
00112 sendpkt(dst, mtvar, size);
00113 return TCL_OK;
00114 }
00115
00116 if (strcmp(argv[1], "lookup") == 0) {
00117 if (argc == 3) {
00118 int dst = atoi(argv[2]);
00119 lookup (dst);
00120
00121 return TCL_OK;
00122 }
00123 }
00124 if (strcmp(argv[1], "initialize") == 0) {
00125 initialize ();
00126 return TCL_OK;
00127 }
00128 if (strcmp(argv[1], "setDelay" ) == 0 ) {
00129 if ( argc == 4) {
00130 int nbrId = atoi(argv[2]);
00131 double delay = strtod ( argv[3], NULL);
00132 setDelay(nbrId, delay);
00133 return TCL_OK;
00134 }
00135 }
00136 if (strcmp(argv[1], "setNodeNumber" ) == 0 ) {
00137 if ( argc == 3 ) {
00138 int number_of_nodes = atoi(argv[2]);
00139 LsMessageCenter::instance().setNodeNumber(number_of_nodes);
00140 }
00141 return TCL_OK;
00142 }
00143 if (strcmp(argv[1], "computeRoutes") == 0) {
00144 computeRoutes();
00145 return TCL_OK;
00146 }
00147 if (strcmp(argv[1], "intfChanged") == 0) {
00148 intfChanged();
00149 return TCL_OK;
00150 }
00151 if (strcmp (argv[1], "send-buffered-messages") == 0) {
00152 sendBufferedMessages();
00153 return TCL_OK;
00154 }
00155 if (strcmp(argv[1], "sendUpdates") == 0) {
00156 sendUpdates ();
00157 return TCL_OK;
00158 }
00159 return Agent::command(argc, argv);
00160 }
00161
00162 void rtProtoLS::sendpkt(ns_addr_t dst, u_int32_t mtvar, u_int32_t size)
00163 {
00164 dst_ = dst;
00165 size_ = size;
00166
00167 Packet* p = Agent::allocpkt();
00168 hdr_LS *rh = hdr_LS::access(p);
00169 rh->metricsVar() = mtvar;
00170
00171 target_->recv(p);
00172 }
00173
00174 void rtProtoLS::recv(Packet* p, Handler*)
00175 {
00176 hdr_LS* rh = hdr_LS::access(p);
00177 hdr_ip* ih = hdr_ip::access(p);
00178
00179 if (LS_ready_ || (rh->metricsVar() == LS_BIG_NUMBER))
00180 receiveMessage(findPeerNodeId(ih->src()), rh->msgId());
00181 else
00182 Tcl::instance().evalf("%s recv-update %d %d", name(),
00183 ih->saddr(), rh->metricsVar());
00184 Packet::free(p);
00185 }
00186
00187
00188
00189
00190
00191 int rtProtoLS::findPeerNodeId (ns_addr_t agentAddr)
00192 {
00193
00194 for (PeerAddrMap::iterator itr = peerAddrMap_.begin();
00195 itr != peerAddrMap_.end(); itr++) {
00196 if ((*itr).second.isEqual (agentAddr)) {
00197 return (*itr).first;
00198 }
00199 }
00200 return LS_INVALID_NODE_ID;
00201 }
00202
00203 void rtProtoLS::initialize()
00204 {
00205 Tcl & tcl = Tcl::instance();
00206
00207 tcl.evalf("%s get-node-id", name());
00208 const char * resultString = tcl.result();
00209 nodeId_ = atoi(resultString);
00210
00211
00212 tcl.evalf("%s get-peers", name());
00213 resultString = tcl.result();
00214
00215 int nodeId, neighborId;
00216 ns_addr_t peer;
00217 ls_status_t status;
00218 int cost;
00219
00220
00221 for ( LsIntList intList(resultString, " \t\n");
00222 !intList.empty(); ) {
00223 nodeId = intList.front();
00224 intList.pop_front();
00225
00226 peer.addr_ = intList.front();
00227 intList.pop_front();
00228 peer.port_ = intList.front();
00229 intList.pop_front();
00230 peerAddrMap_.insert(nodeId, peer);
00231 peerIdList_.push_back(nodeId);
00232 }
00233
00234
00235 tcl.evalf("%s get-links-status", name());
00236 resultString = tcl.result();
00237
00238
00239 for ( LsIntList intList2(resultString, " \t\n");
00240 !intList2.empty(); ) {
00241 neighborId = intList2.front();
00242 intList2.pop_front();
00243 status = (ls_status_t) intList2.front();
00244 intList2.pop_front();
00245 cost = (int) intList2.front();
00246 intList2.pop_front();
00247 linkStateList_.push_back(LsLinkState(neighborId,status,cost));
00248 }
00249
00250
00251 tcl.evalf ("%s get-delay-estimates", name());
00252
00253
00254 routing_.init(this);
00255 routing_.computeRoutes();
00256
00257 tcl.evalf("%s set LS_ready", name());
00258 const char* token = strtok((char *)tcl.result(), " \t\n");
00259 if (token == NULL)
00260 LS_ready_ = 0;
00261 else
00262 LS_ready_ = atoi(token);
00263 }
00264
00265 void rtProtoLS::intfChanged ()
00266 {
00267
00268 Tcl & tcl = Tcl::instance();
00269
00270 tcl.evalf("%s get-links-status", name());
00271 const char * resultString = tcl.result();
00272
00273
00274 linkStateList_.eraseAll();
00275
00276
00277 for (LsIntList intList2(resultString, " \t\n");
00278 !intList2.empty(); ) {
00279 int neighborId = intList2.front();
00280 intList2.pop_front();
00281 ls_status_t status = ( ls_status_t ) intList2.front();
00282 intList2.pop_front();
00283 int cost = (int) intList2.front();
00284 intList2.pop_front();
00285
00286
00287 linkStateList_.push_back(LsLinkState(neighborId,status,cost));
00288 }
00289
00290
00291 routing_.linkStateChanged();
00292 }
00293
00294 void rtProtoLS::lookup(int destId)
00295 {
00296
00297 LsEqualPaths* EPptr = routing_.lookup(destId);
00298
00299
00300 if (EPptr == NULL) {
00301 Tcl::instance().resultf( "%s", "");
00302 return;
00303 }
00304 char resultBuf[64];
00305 sprintf(resultBuf, "%d" , EPptr->cost);
00306 char tmpBuf[16];
00307
00308 for (LsNodeIdList::iterator itr = (EPptr->nextHopList).begin();
00309 itr != (EPptr->nextHopList).end(); itr++) {
00310 sprintf(tmpBuf, " %d", (*itr) );
00311 strcat (resultBuf, tmpBuf);
00312 }
00313
00314 Tcl::instance().resultf("%s", resultBuf);
00315 }
00316
00317 void rtProtoLS::receiveMessage(int sender, u_int32_t msgId)
00318 {
00319 if (routing_.receiveMessage(sender, msgId))
00320 installRoutes();
00321 }
00322
00323
00324 bool rtProtoLS::sendMessage(int destId, u_int32_t messageId, int size)
00325 {
00326 ns_addr_t* agentAddrPtr = peerAddrMap_.findPtr(destId);
00327 if (agentAddrPtr == NULL)
00328 return false;
00329 dst_ = *agentAddrPtr;
00330 size_ = size;
00331
00332 Packet* p = Agent::allocpkt();
00333 hdr_LS *rh = hdr_LS::access(p);
00334 rh->msgId() = messageId;
00335 rh->metricsVar() = LS_BIG_NUMBER;
00336 target_->recv(p);
00337
00338 return true;
00339 }
00340
00341 #endif // HAVE_STL