#include <DatabaseDescriptionHandler.h>
Public Member Functions | |
DatabaseDescriptionHandler (Router *containingRouter) | |
void | ProcessPacket (OSPFPacket *packet, Interface *intf, Neighbor *neighbor) |
Private Member Functions | |
bool | ProcessDDPacket (OSPFDatabaseDescriptionPacket *ddPacket, Interface *intf, Neighbor *neighbor, bool inExchangeStart) |
OSPF::DatabaseDescriptionHandler::DatabaseDescriptionHandler | ( | OSPF::Router * | containingRouter | ) |
bool OSPF::DatabaseDescriptionHandler::ProcessDDPacket | ( | OSPFDatabaseDescriptionPacket * | ddPacket, | |
OSPF::Interface * | intf, | |||
OSPF::Neighbor * | neighbor, | |||
bool | inExchangeStart | |||
) | [private] |
Referenced by ProcessPacket().
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 // operator< and operator== on OSPFLSAHeaders determines which one is newer(less means older) 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); // does nothing in ExchangeStart 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); // does nothing in ExchangeStart 00238 } 00239 } 00240 return true; 00241 }
void OSPF::DatabaseDescriptionHandler::ProcessPacket | ( | OSPFPacket * | packet, | |
OSPF::Interface * | intf, | |||
OSPF::Neighbor * | neighbor | |||
) | [virtual] |
Implements OSPF::IMessageHandler.
Referenced by OSPF::MessageHandler::ProcessPacket().
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 }