Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "DatabaseDescriptionHandler.h"
00019 #include "OSPFNeighbor.h"
00020 #include "OSPFInterface.h"
00021 #include "OSPFRouter.h"
00022 #include "OSPFArea.h"
00023
00024 OSPF::DatabaseDescriptionHandler::DatabaseDescriptionHandler(OSPF::Router* containingRouter) :
00025 OSPF::IMessageHandler(containingRouter)
00026 {
00027 }
00028
00029 void OSPF::DatabaseDescriptionHandler::ProcessPacket(OSPFPacket* packet, OSPF::Interface* intf, OSPF::Neighbor* neighbor)
00030 {
00031 router->GetMessageHandler()->PrintEvent("Database Description packet received", intf, neighbor);
00032
00033 OSPFDatabaseDescriptionPacket* ddPacket = check_and_cast<OSPFDatabaseDescriptionPacket*> (packet);
00034
00035 OSPF::Neighbor::NeighborStateType neighborState = neighbor->GetState();
00036
00037 if ((ddPacket->getInterfaceMTU() <= intf->GetMTU()) &&
00038 (neighborState > OSPF::Neighbor::AttemptState))
00039 {
00040 switch (neighborState) {
00041 case OSPF::Neighbor::TwoWayState:
00042 break;
00043 case OSPF::Neighbor::InitState:
00044 neighbor->ProcessEvent(OSPF::Neighbor::TwoWayReceived);
00045 break;
00046 case OSPF::Neighbor::ExchangeStartState:
00047 {
00048 OSPFDDOptions& ddOptions = ddPacket->getDdOptions();
00049
00050 if (ddOptions.I_Init && ddOptions.M_More && ddOptions.MS_MasterSlave &&
00051 (ddPacket->getLsaHeadersArraySize() == 0))
00052 {
00053 if (neighbor->GetNeighborID() > router->GetRouterID()) {
00054 OSPF::Neighbor::DDPacketID packetID;
00055 packetID.ddOptions = ddOptions;
00056 packetID.options = ddPacket->getOptions();
00057 packetID.sequenceNumber = ddPacket->getDdSequenceNumber();
00058
00059 neighbor->SetOptions(packetID.options);
00060 neighbor->SetDatabaseExchangeRelationship(OSPF::Neighbor::Slave);
00061 neighbor->SetDDSequenceNumber(packetID.sequenceNumber);
00062 neighbor->SetLastReceivedDDPacket(packetID);
00063
00064 if (!ProcessDDPacket(ddPacket, intf, neighbor, true)) {
00065 break;
00066 }
00067
00068 neighbor->ProcessEvent(OSPF::Neighbor::NegotiationDone);
00069 if (!neighbor->IsLinkStateRequestListEmpty() &&
00070 !neighbor->IsRequestRetransmissionTimerActive())
00071 {
00072 neighbor->SendLinkStateRequestPacket();
00073 neighbor->ClearRequestRetransmissionTimer();
00074 neighbor->StartRequestRetransmissionTimer();
00075 }
00076 } else {
00077 neighbor->SendDatabaseDescriptionPacket(true);
00078 }
00079 }
00080 if (!ddOptions.I_Init && !ddOptions.MS_MasterSlave &&
00081 (ddPacket->getDdSequenceNumber() == neighbor->GetDDSequenceNumber()) &&
00082 (neighbor->GetNeighborID() < router->GetRouterID()))
00083 {
00084 OSPF::Neighbor::DDPacketID packetID;
00085 packetID.ddOptions = ddOptions;
00086 packetID.options = ddPacket->getOptions();
00087 packetID.sequenceNumber = ddPacket->getDdSequenceNumber();
00088
00089 neighbor->SetOptions(packetID.options);
00090 neighbor->SetDatabaseExchangeRelationship(OSPF::Neighbor::Master);
00091 neighbor->SetLastReceivedDDPacket(packetID);
00092
00093 if (!ProcessDDPacket(ddPacket, intf, neighbor, true)) {
00094 break;
00095 }
00096
00097 neighbor->ProcessEvent(OSPF::Neighbor::NegotiationDone);
00098 if (!neighbor->IsLinkStateRequestListEmpty() &&
00099 !neighbor->IsRequestRetransmissionTimerActive())
00100 {
00101 neighbor->SendLinkStateRequestPacket();
00102 neighbor->ClearRequestRetransmissionTimer();
00103 neighbor->StartRequestRetransmissionTimer();
00104 }
00105 }
00106 }
00107 break;
00108 case OSPF::Neighbor::ExchangeState:
00109 {
00110 OSPF::Neighbor::DDPacketID packetID;
00111 packetID.ddOptions = ddPacket->getDdOptions();
00112 packetID.options = ddPacket->getOptions();
00113 packetID.sequenceNumber = ddPacket->getDdSequenceNumber();
00114
00115 if (packetID != neighbor->GetLastReceivedDDPacket()) {
00116 if ((packetID.ddOptions.MS_MasterSlave &&
00117 (neighbor->GetDatabaseExchangeRelationship() != OSPF::Neighbor::Slave)) ||
00118 (!packetID.ddOptions.MS_MasterSlave &&
00119 (neighbor->GetDatabaseExchangeRelationship() != OSPF::Neighbor::Master)) ||
00120 packetID.ddOptions.I_Init ||
00121 (packetID.options != neighbor->GetLastReceivedDDPacket().options))
00122 {
00123 neighbor->ProcessEvent(OSPF::Neighbor::SequenceNumberMismatch);
00124 } else {
00125 if (((neighbor->GetDatabaseExchangeRelationship() == OSPF::Neighbor::Master) &&
00126 (packetID.sequenceNumber == neighbor->GetDDSequenceNumber())) ||
00127 ((neighbor->GetDatabaseExchangeRelationship() == OSPF::Neighbor::Slave) &&
00128 (packetID.sequenceNumber == (neighbor->GetDDSequenceNumber() + 1))))
00129 {
00130 neighbor->SetLastReceivedDDPacket(packetID);
00131 if (!ProcessDDPacket(ddPacket, intf, neighbor, false)) {
00132 break;
00133 }
00134 if (!neighbor->IsLinkStateRequestListEmpty() &&
00135 !neighbor->IsRequestRetransmissionTimerActive())
00136 {
00137 neighbor->SendLinkStateRequestPacket();
00138 neighbor->ClearRequestRetransmissionTimer();
00139 neighbor->StartRequestRetransmissionTimer();
00140 }
00141 } else {
00142 neighbor->ProcessEvent(OSPF::Neighbor::SequenceNumberMismatch);
00143 }
00144 }
00145 } else {
00146 if (neighbor->GetDatabaseExchangeRelationship() == OSPF::Neighbor::Slave) {
00147 neighbor->RetransmitDatabaseDescriptionPacket();
00148 }
00149 }
00150 }
00151 break;
00152 case OSPF::Neighbor::LoadingState:
00153 case OSPF::Neighbor::FullState:
00154 {
00155 OSPF::Neighbor::DDPacketID packetID;
00156 packetID.ddOptions = ddPacket->getDdOptions();
00157 packetID.options = ddPacket->getOptions();
00158 packetID.sequenceNumber = ddPacket->getDdSequenceNumber();
00159
00160 if ((packetID != neighbor->GetLastReceivedDDPacket()) ||
00161 (packetID.ddOptions.I_Init))
00162 {
00163 neighbor->ProcessEvent(OSPF::Neighbor::SequenceNumberMismatch);
00164 } else {
00165 if (neighbor->GetDatabaseExchangeRelationship() == OSPF::Neighbor::Slave) {
00166 if (!neighbor->RetransmitDatabaseDescriptionPacket()) {
00167 neighbor->ProcessEvent(OSPF::Neighbor::SequenceNumberMismatch);
00168 }
00169 }
00170 }
00171 }
00172 break;
00173 default: break;
00174 }
00175 }
00176 }
00177
00178 bool OSPF::DatabaseDescriptionHandler::ProcessDDPacket(OSPFDatabaseDescriptionPacket* ddPacket, OSPF::Interface* intf, OSPF::Neighbor* neighbor, bool inExchangeStart)
00179 {
00180 EV << " Processing packet contents(ddOptions="
00181 << ((ddPacket->getDdOptions().I_Init) ? "I " : "_ ")
00182 << ((ddPacket->getDdOptions().M_More) ? "M " : "_ ")
00183 << ((ddPacket->getDdOptions().MS_MasterSlave) ? "MS" : "__")
00184 << "; seqNumber="
00185 << ddPacket->getDdSequenceNumber()
00186 << "):\n";
00187
00188 unsigned int headerCount = ddPacket->getLsaHeadersArraySize();
00189
00190 for (unsigned int i = 0; i < headerCount; i++) {
00191 OSPFLSAHeader& currentHeader = ddPacket->getLsaHeaders(i);
00192 LSAType lsaType = static_cast<LSAType> (currentHeader.getLsType());
00193
00194 EV << " ";
00195 PrintLSAHeader(currentHeader, ev.getOStream());
00196
00197 if ((lsaType < RouterLSAType) || (lsaType > ASExternalLSAType) ||
00198 ((lsaType == ASExternalLSAType) && (!intf->GetArea()->GetExternalRoutingCapability())))
00199 {
00200 EV << " Error!\n";
00201 neighbor->ProcessEvent(OSPF::Neighbor::SequenceNumberMismatch);
00202 return false;
00203 } else {
00204 OSPF::LSAKeyType lsaKey;
00205
00206 lsaKey.linkStateID = currentHeader.getLinkStateID();
00207 lsaKey.advertisingRouter = currentHeader.getAdvertisingRouter().getInt();
00208
00209 OSPFLSA* lsaInDatabase = router->FindLSA(lsaType, lsaKey, intf->GetArea()->GetAreaID());
00210
00211
00212 if ((lsaInDatabase == NULL) || (lsaInDatabase->getHeader() < currentHeader)) {
00213 EV << " (newer)";
00214 neighbor->AddToRequestList(¤tHeader);
00215 }
00216 }
00217 EV << "\n";
00218 }
00219
00220 if (neighbor->GetDatabaseExchangeRelationship() == OSPF::Neighbor::Master) {
00221 neighbor->IncrementDDSequenceNumber();
00222 if ((neighbor->GetDatabaseSummaryListCount() == 0) && !ddPacket->getDdOptions().M_More) {
00223 neighbor->ProcessEvent(OSPF::Neighbor::ExchangeDone);
00224 } else {
00225 if (!inExchangeStart) {
00226 neighbor->SendDatabaseDescriptionPacket();
00227 }
00228 }
00229 } else {
00230 neighbor->SetDDSequenceNumber(ddPacket->getDdSequenceNumber());
00231 if (!inExchangeStart) {
00232 neighbor->SendDatabaseDescriptionPacket();
00233 }
00234 if (!ddPacket->getDdOptions().M_More &&
00235 (neighbor->GetDatabaseSummaryListCount() == 0))
00236 {
00237 neighbor->ProcessEvent(OSPF::Neighbor::ExchangeDone);
00238 }
00239 }
00240 return true;
00241 }