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