Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <omnetpp.h>
00016 #include <algorithm>
00017
00018 #include "LinkStateRouting.h"
00019 #include "IPControlInfo.h"
00020 #include "IPv4InterfaceData.h"
00021 #include "NotifierConsts.h"
00022 #include "RoutingTableAccess.h"
00023 #include "InterfaceTableAccess.h"
00024 #include "NotificationBoard.h"
00025 #include "TED.h"
00026 #include "TEDAccess.h"
00027
00028 Define_Module(LinkStateRouting);
00029
00030 LinkStateRouting::LinkStateRouting()
00031 {
00032 announceMsg = NULL;
00033 }
00034
00035 LinkStateRouting::~LinkStateRouting()
00036 {
00037 cancelAndDelete(announceMsg);
00038 }
00039
00040 void LinkStateRouting::initialize(int stage)
00041 {
00042
00043 if (stage==4)
00044 {
00045 tedmod = TEDAccess().get();
00046
00047 IRoutingTable *rt = RoutingTableAccess().get();
00048 routerId = rt->getRouterId();
00049
00050
00051 NotificationBoard *nb = NotificationBoardAccess().get();
00052 nb->subscribe(this, NF_TED_CHANGED);
00053
00054
00055
00056 cStringTokenizer tokenizer(par("peers"));
00057 IInterfaceTable *ift = InterfaceTableAccess().get();
00058 const char *token;
00059 while ((token = tokenizer.nextToken())!=NULL)
00060 {
00061 ASSERT(ift->getInterfaceByName(token));
00062 peerIfAddrs.push_back(ift->getInterfaceByName(token)->ipv4Data()->getIPAddress());
00063 }
00064
00065
00066 announceMsg = new cMessage("announce");
00067 scheduleAt(simTime() + exponential(0.01), announceMsg);
00068 }
00069 }
00070
00071 void LinkStateRouting::handleMessage(cMessage * msg)
00072 {
00073 if (msg == announceMsg)
00074 {
00075 delete announceMsg;
00076 announceMsg = NULL;
00077 sendToPeers(tedmod->ted, true, IPAddress());
00078 }
00079 else if (!strcmp(msg->getArrivalGate()->getName(), "ipIn"))
00080 {
00081 EV << "Processing message from IP: " << msg << endl;
00082 IPControlInfo *controlInfo = check_and_cast<IPControlInfo *>(msg->getControlInfo());
00083 IPAddress sender = controlInfo->getSrcAddr();
00084 processLINK_STATE_MESSAGE(check_and_cast<LinkStateMsg*>(msg), sender);
00085 }
00086 else
00087 ASSERT(false);
00088 }
00089
00090 void LinkStateRouting::receiveChangeNotification(int category, const cPolymorphic *details)
00091 {
00092 Enter_Method_Silent();
00093 printNotificationBanner(category, details);
00094
00095 ASSERT(category == NF_TED_CHANGED);
00096
00097 EV << "TED changed\n";
00098
00099 TEDChangeInfo *d = check_and_cast<TEDChangeInfo *>(details);
00100
00101 unsigned int k = d->getTedLinkIndicesArraySize();
00102
00103 ASSERT(k > 0);
00104
00105
00106 std::vector<TELinkStateInfo> links;
00107 for (unsigned int i = 0; i < k; i++)
00108 {
00109 unsigned int index = d->getTedLinkIndices(i);
00110
00111 tedmod->updateTimestamp(&tedmod->ted[index]);
00112 links.push_back(tedmod->ted[index]);
00113 }
00114
00115 sendToPeers(links, false, IPAddress());
00116 }
00117
00118 void LinkStateRouting::processLINK_STATE_MESSAGE(LinkStateMsg* msg, IPAddress sender)
00119 {
00120 EV << "received LINK_STATE message from " << sender << endl;
00121
00122 TELinkStateInfoVector forward;
00123
00124 unsigned int n = msg->getLinkInfoArraySize();
00125
00126 bool change = false;
00127
00128
00129 for (unsigned int i = 0; i < n; i++)
00130 {
00131 const TELinkStateInfo& link = msg->getLinkInfo(i);
00132
00133 TELinkStateInfo *match;
00134
00135
00136 if(tedmod->checkLinkValidity(link, match))
00137 {
00138 ASSERT(link.sourceId == link.advrouter.getInt());
00139
00140 EV << "new information found" << endl;
00141
00142 if(!match)
00143 {
00144
00145 tedmod->ted.push_back(link);
00146 change = true;
00147 }
00148 else
00149 {
00150
00151 if(match->state != link.state)
00152 {
00153 match->state = link.state;
00154 change = true;
00155 }
00156 match->messageId = link.messageId;
00157 match->sourceId = link.sourceId;
00158 match->timestamp = link.timestamp;
00159 for(int i = 0; i < 8; i++)
00160 match->UnResvBandwidth[i] = link.UnResvBandwidth[i];
00161 match->MaxBandwidth = link.MaxBandwidth;
00162 match->metric = link.metric;
00163 }
00164
00165 forward.push_back(link);
00166 }
00167 }
00168
00169 if(change)
00170 tedmod->rebuildRoutingTable();
00171
00172 if(msg->getRequest())
00173 {
00174 sendToPeer(sender, tedmod->ted, false);
00175 }
00176
00177 if(forward.size() > 0)
00178 {
00179 sendToPeers(forward, false, sender);
00180 }
00181
00182 delete msg;
00183 }
00184
00185 void LinkStateRouting::sendToPeers(const std::vector<TELinkStateInfo>& list, bool req, IPAddress exceptPeer)
00186 {
00187 EV << "sending LINK_STATE message to peers" << endl;
00188
00189
00190 for (unsigned int i = 0; i < tedmod->ted.size(); i++)
00191 {
00192 if(tedmod->ted[i].advrouter != routerId)
00193 continue;
00194
00195 if(tedmod->ted[i].linkid == exceptPeer)
00196 continue;
00197
00198 if(!tedmod->ted[i].state)
00199 continue;
00200
00201 if(find(peerIfAddrs.begin(), peerIfAddrs.end(), tedmod->ted[i].local) == peerIfAddrs.end())
00202 continue;
00203
00204
00205 sendToPeer(tedmod->ted[i].linkid, list, req);
00206 }
00207 }
00208
00209 void LinkStateRouting::sendToPeer(IPAddress peer, const std::vector<TELinkStateInfo> & list, bool req)
00210 {
00211 EV << "sending LINK_STATE message to " << peer << endl;
00212
00213 LinkStateMsg *out = new LinkStateMsg("link state");
00214
00215 out->setLinkInfoArraySize(list.size());
00216 for (unsigned int j = 0; j < list.size(); j++)
00217 out->setLinkInfo(j, list[j]);
00218
00219 out->setRequest(req);
00220
00221 sendToIP(out, peer);
00222 }
00223
00224 void LinkStateRouting::sendToIP(LinkStateMsg *msg, IPAddress destAddr)
00225 {
00226
00227 IPControlInfo *controlInfo = new IPControlInfo();
00228 controlInfo->setDestAddr(destAddr);
00229 controlInfo->setSrcAddr(routerId);
00230 controlInfo->setProtocol(IP_PROT_OSPF);
00231 msg->setControlInfo(controlInfo);
00232
00233 int length = msg->getLinkInfoArraySize() * 72;
00234 msg->setByteLength(length);
00235
00236 msg->addPar("color") = TED_TRAFFIC;
00237
00238 send(msg, "ipOut");
00239 }
00240