|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // This program is free software: you can redistribute it and/or modify 00003 // it under the terms of the GNU Lesser General Public License as published by 00004 // the Free Software Foundation, either version 3 of the License, or 00005 // (at your option) any later version. 00006 // 00007 // This program is distributed in the hope that it will be useful, 00008 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 // GNU Lesser General Public License for more details. 00011 // 00012 // You should have received a copy of the GNU Lesser General Public License 00013 // along with this program. If not, see http://www.gnu.org/licenses/. 00014 // 00015 00016 #include "ansaOspfArea6.h" 00017 #include "ansaOspfInterface6.h" 00018 #include "ansaLsa6.h" 00019 #include "ansaOspfNeighbor6.h" 00020 #include "ansaOspfRouter6.h" 00021 00022 #include "ansaDatabaseDescriptionHandler6.h" 00023 00024 AnsaOspf6::DatabaseDescriptionHandler::DatabaseDescriptionHandler(AnsaOspf6::Router* containingRouter) : 00025 AnsaOspf6::IMessageHandler(containingRouter) { 00026 } 00027 00028 void AnsaOspf6::DatabaseDescriptionHandler::ProcessPacket(OspfPacket6* packet, AnsaOspf6::Interface* intf, AnsaOspf6::Neighbor* neighbor) { 00029 00030 router->GetMessageHandler()->PrintEvent("Database Description packet received", intf, neighbor); 00031 00032 OspfDatabaseDescriptionPacket6* ddPacket = check_and_cast<OspfDatabaseDescriptionPacket6*> (packet); 00033 00034 AnsaOspf6::Neighbor::NeighborStateType neighborState = neighbor->GetState(); 00035 00036 if ((ddPacket->getInterfaceMtu() <= intf->GetMtu()) && (neighborState > AnsaOspf6::Neighbor::AttemptState)){ 00037 00038 switch (neighborState){ 00039 00040 case AnsaOspf6::Neighbor::TwoWayState: 00041 break; 00042 00043 case AnsaOspf6::Neighbor::InitState: 00044 neighbor->ProcessEvent(AnsaOspf6::Neighbor::TwoWayReceived); 00045 break; 00046 00047 case AnsaOspf6::Neighbor::ExchangeStartState: { 00048 OspfDdOptions6& ddOptions = ddPacket->getDdOptions(); 00049 00050 if ( ddOptions.I_Init 00051 && ddOptions.M_More 00052 && ddOptions.MS_MasterSlave 00053 && (ddPacket->getLsaHeadersArraySize() == 0)){ 00054 00055 if (neighbor->GetNeighborID() > router->GetRouterID()){ 00056 AnsaOspf6::Neighbor::DDPacketID packetID; 00057 packetID.ddOptions = ddOptions; 00058 packetID.options = ddPacket->getOptions(); 00059 packetID.sequenceNumber = ddPacket->getDdSequenceNumber(); 00060 00061 neighbor->SetOptions(packetID.options); 00062 neighbor->SetDatabaseExchangeRelationship(AnsaOspf6::Neighbor::Slave); 00063 neighbor->SetDDSequenceNumber(packetID.sequenceNumber); 00064 neighbor->SetLastReceivedDDPacket(packetID); 00065 00066 if (!ProcessDDPacket(ddPacket, intf, neighbor, true)){ 00067 break; 00068 } 00069 00070 neighbor->ProcessEvent(AnsaOspf6::Neighbor::NegotiationDone); 00071 if (!neighbor->IsLinkStateRequestListEmpty() 00072 && !neighbor->IsRequestRetransmissionTimerActive()){ 00073 neighbor->SendLinkStateRequestPacket(); 00074 neighbor->ClearRequestRetransmissionTimer(); 00075 neighbor->StartRequestRetransmissionTimer(); 00076 } 00077 }else{ 00078 neighbor->SendDatabaseDescriptionPacket(true); 00079 } 00080 } 00081 if ( !ddOptions.I_Init 00082 && !ddOptions.MS_MasterSlave 00083 && (ddPacket->getDdSequenceNumber() == neighbor->GetDDSequenceNumber()) 00084 && (neighbor->GetNeighborID() < router->GetRouterID())){ 00085 00086 AnsaOspf6::Neighbor::DDPacketID packetID; 00087 packetID.ddOptions = ddOptions; 00088 packetID.options = ddPacket->getOptions(); 00089 packetID.sequenceNumber = ddPacket->getDdSequenceNumber(); 00090 00091 neighbor->SetOptions(packetID.options); 00092 neighbor->SetDatabaseExchangeRelationship(AnsaOspf6::Neighbor::Master); 00093 neighbor->SetLastReceivedDDPacket(packetID); 00094 00095 if (!ProcessDDPacket(ddPacket, intf, neighbor, true)){ 00096 break; 00097 } 00098 00099 neighbor->ProcessEvent(AnsaOspf6::Neighbor::NegotiationDone); 00100 if ( !neighbor->IsLinkStateRequestListEmpty() 00101 && !neighbor->IsRequestRetransmissionTimerActive()){ 00102 00103 neighbor->SendLinkStateRequestPacket(); 00104 neighbor->ClearRequestRetransmissionTimer(); 00105 neighbor->StartRequestRetransmissionTimer(); 00106 } 00107 }} 00108 break; 00109 00110 case AnsaOspf6::Neighbor::ExchangeState: { 00111 AnsaOspf6::Neighbor::DDPacketID packetID; 00112 packetID.ddOptions = ddPacket->getDdOptions(); 00113 packetID.options = ddPacket->getOptions(); 00114 packetID.sequenceNumber = ddPacket->getDdSequenceNumber(); 00115 00116 if (packetID != neighbor->GetLastReceivedDDPacket()){ 00117 if ( (packetID.ddOptions.MS_MasterSlave 00118 && (neighbor->GetDatabaseExchangeRelationship() != AnsaOspf6::Neighbor::Slave)) 00119 || (!packetID.ddOptions.MS_MasterSlave 00120 && (neighbor->GetDatabaseExchangeRelationship() != AnsaOspf6::Neighbor::Master)) 00121 || packetID.ddOptions.I_Init 00122 || (packetID.options != neighbor->GetLastReceivedDDPacket().options)){ 00123 00124 neighbor->ProcessEvent(AnsaOspf6::Neighbor::SequenceNumberMismatch); 00125 00126 }else{ 00127 if ( ((neighbor->GetDatabaseExchangeRelationship() == AnsaOspf6::Neighbor::Master) 00128 && (packetID.sequenceNumber == neighbor->GetDDSequenceNumber())) 00129 || ((neighbor->GetDatabaseExchangeRelationship() == AnsaOspf6::Neighbor::Slave) 00130 && (packetID.sequenceNumber == (neighbor->GetDDSequenceNumber() + 1)))){ 00131 00132 neighbor->SetLastReceivedDDPacket(packetID); 00133 00134 if (!ProcessDDPacket(ddPacket, intf, neighbor, false)){ 00135 break; 00136 } 00137 00138 if ( !neighbor->IsLinkStateRequestListEmpty() 00139 && !neighbor->IsRequestRetransmissionTimerActive()){ 00140 00141 neighbor->SendLinkStateRequestPacket(); 00142 neighbor->ClearRequestRetransmissionTimer(); 00143 neighbor->StartRequestRetransmissionTimer(); 00144 } 00145 00146 }else{ 00147 neighbor->ProcessEvent(AnsaOspf6::Neighbor::SequenceNumberMismatch); 00148 } 00149 } 00150 }else{ 00151 if (neighbor->GetDatabaseExchangeRelationship() == AnsaOspf6::Neighbor::Slave){ 00152 neighbor->RetransmitDatabaseDescriptionPacket(); 00153 } 00154 }} 00155 break; 00156 00157 00158 case AnsaOspf6::Neighbor::LoadingState: 00159 case AnsaOspf6::Neighbor::FullState: { 00160 AnsaOspf6::Neighbor::DDPacketID packetID; 00161 packetID.ddOptions = ddPacket->getDdOptions(); 00162 packetID.options = ddPacket->getOptions(); 00163 packetID.sequenceNumber = ddPacket->getDdSequenceNumber(); 00164 00165 if ( (packetID != neighbor->GetLastReceivedDDPacket()) 00166 || (packetID.ddOptions.I_Init)){ 00167 neighbor->ProcessEvent(AnsaOspf6::Neighbor::SequenceNumberMismatch); 00168 }else{ 00169 if (neighbor->GetDatabaseExchangeRelationship() == AnsaOspf6::Neighbor::Slave){ 00170 if (!neighbor->RetransmitDatabaseDescriptionPacket()){ 00171 neighbor->ProcessEvent(AnsaOspf6::Neighbor::SequenceNumberMismatch); 00172 } 00173 } 00174 }} 00175 break; 00176 default: 00177 break; 00178 } 00179 } 00180 } 00181 00182 bool AnsaOspf6::DatabaseDescriptionHandler::ProcessDDPacket( 00183 OspfDatabaseDescriptionPacket6* ddPacket, 00184 AnsaOspf6::Interface* intf, 00185 AnsaOspf6::Neighbor* neighbor, 00186 bool inExchangeStart) { 00187 00188 EV << " Processing packet contents(ddOptions=" 00189 << ((ddPacket->getDdOptions().I_Init) ? "I " : "_ ") 00190 << ((ddPacket->getDdOptions().M_More) ? "M " : "_ ") 00191 << ((ddPacket->getDdOptions().MS_MasterSlave) ? "MS" : "__") 00192 << "; seqNumber=" 00193 << ddPacket->getDdSequenceNumber() 00194 << "):\n"; 00195 00196 unsigned int headerCount = ddPacket->getLsaHeadersArraySize(); 00197 00198 for (unsigned int i = 0; i < headerCount; i++){ 00199 OspfLsaHeader6& currentHeader = ddPacket->getLsaHeaders(i); 00200 LsaType6 lsaType = static_cast<LsaType6> (currentHeader.getLsType()); 00201 00202 EV << " "; 00203 PrintLsaHeader6(currentHeader, ev.getOStream()); 00204 00205 if ((lsaType < RouterLsaType) || (lsaType > AsExternalLsaType) 00206 || ((lsaType == AsExternalLsaType) && (!intf->GetArea()->GetExternalRoutingCapability()))){ 00207 00208 EV << " Error!\n"; 00209 neighbor->ProcessEvent(AnsaOspf6::Neighbor::SequenceNumberMismatch); 00210 return false; 00211 }else{ 00212 AnsaOspf6::LsaKeyType6 lsaKey; 00213 00214 lsaKey.linkStateID = currentHeader.getLinkStateID(); 00215 lsaKey.advertisingRouter = currentHeader.getAdvertisingRouter(); 00216 00217 OspfLsa6* lsaInDatabase = router->FindLSA(lsaType, lsaKey, intf->GetArea()->GetAreaID()); 00218 00219 // operator< and operator== on OSPFLSAHeaders determines which one is newer(less means older) 00220 if ((lsaInDatabase == NULL) || (lsaInDatabase->getHeader() < currentHeader)){ 00221 EV << " (newer)"; 00222 neighbor->AddToRequestList(¤tHeader); 00223 } 00224 } 00225 EV << "\n"; 00226 } 00227 00228 if (neighbor->GetDatabaseExchangeRelationship() == AnsaOspf6::Neighbor::Master){ 00229 neighbor->IncrementDDSequenceNumber(); 00230 if ((neighbor->GetDatabaseSummaryListCount() == 0) && !ddPacket->getDdOptions().M_More){ 00231 neighbor->ProcessEvent(AnsaOspf6::Neighbor::ExchangeDone); // does nothing in ExchangeStart 00232 }else{ 00233 if (!inExchangeStart){ 00234 neighbor->SendDatabaseDescriptionPacket(); 00235 } 00236 } 00237 }else{ 00238 neighbor->SetDDSequenceNumber(ddPacket->getDdSequenceNumber()); 00239 if (!inExchangeStart) { 00240 neighbor->SendDatabaseDescriptionPacket(); 00241 } 00242 if (!ddPacket->getDdOptions().M_More && (neighbor->GetDatabaseSummaryListCount() == 0)){ 00243 neighbor->ProcessEvent(AnsaOspf6::Neighbor::ExchangeDone); // does nothing in ExchangeStart 00244 } 00245 } 00246 return true; 00247 }