#include <DatabaseDescriptionHandler.h>
Inheritance diagram for OSPF::DatabaseDescriptionHandler:
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 | ( | Router * | containingRouter | ) |
bool OSPF::DatabaseDescriptionHandler::ProcessDDPacket | ( | OSPFDatabaseDescriptionPacket * | ddPacket, | |
Interface * | intf, | |||
Neighbor * | neighbor, | |||
bool | inExchangeStart | |||
) | [private] |
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); 00179 00180 if ((lsaType < RouterLSAType) || (lsaType > ASExternalLSAType) || 00181 ((lsaType == ASExternalLSAType) && (!intf->GetArea ()->GetExternalRoutingCapability ()))) 00182 { 00183 EV << " Error!\n"; 00184 neighbor->ProcessEvent (OSPF::Neighbor::SequenceNumberMismatch); 00185 return false; 00186 } else { 00187 OSPF::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 () == OSPF::Neighbor::Master) { 00204 neighbor->IncrementDDSequenceNumber (); 00205 if ((neighbor->GetDatabaseSummaryListCount () == 0) && !ddPacket->getDdOptions ().M_More) { 00206 neighbor->ProcessEvent (OSPF::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 (OSPF::Neighbor::ExchangeDone); // does nothing in ExchangeStart 00221 } 00222 } 00223 return true; 00224 }
void OSPF::DatabaseDescriptionHandler::ProcessPacket | ( | OSPFPacket * | packet, | |
Interface * | intf, | |||
Neighbor * | neighbor | |||
) | [virtual] |
Implements OSPF::IMessageHandler.
00013 { 00014 router->GetMessageHandler ()->PrintEvent ("Database Description packet received", intf, neighbor); 00015 00016 OSPFDatabaseDescriptionPacket* ddPacket = check_and_cast<OSPFDatabaseDescriptionPacket*> (packet); 00017 00018 OSPF::Neighbor::NeighborStateType neighborState = neighbor->GetState (); 00019 00020 if ((ddPacket->getInterfaceMTU () <= intf->GetMTU ()) && 00021 (neighborState > OSPF::Neighbor::AttemptState)) 00022 { 00023 switch (neighborState) { 00024 case OSPF::Neighbor::TwoWayState: 00025 break; 00026 case OSPF::Neighbor::InitState: 00027 neighbor->ProcessEvent (OSPF::Neighbor::TwoWayReceived); 00028 break; 00029 case OSPF::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 OSPF::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 (OSPF::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 (OSPF::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 OSPF::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 (OSPF::Neighbor::Master); 00074 neighbor->SetLastReceivedDDPacket (packetID); 00075 00076 if (!ProcessDDPacket (ddPacket, intf, neighbor, true)) { 00077 break; 00078 } 00079 00080 neighbor->ProcessEvent (OSPF::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 OSPF::Neighbor::ExchangeState: 00092 { 00093 OSPF::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 () != OSPF::Neighbor::Slave)) || 00101 (!packetID.ddOptions.MS_MasterSlave && 00102 (neighbor->GetDatabaseExchangeRelationship () != OSPF::Neighbor::Master)) || 00103 packetID.ddOptions.I_Init || 00104 (packetID.options != neighbor->GetLastReceivedDDPacket ().options)) 00105 { 00106 neighbor->ProcessEvent (OSPF::Neighbor::SequenceNumberMismatch); 00107 } else { 00108 if (((neighbor->GetDatabaseExchangeRelationship () == OSPF::Neighbor::Master) && 00109 (packetID.sequenceNumber == neighbor->GetDDSequenceNumber ())) || 00110 ((neighbor->GetDatabaseExchangeRelationship () == OSPF::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 (OSPF::Neighbor::SequenceNumberMismatch); 00126 } 00127 } 00128 } else { 00129 if (neighbor->GetDatabaseExchangeRelationship () == OSPF::Neighbor::Slave) { 00130 neighbor->RetransmitDatabaseDescriptionPacket (); 00131 } 00132 } 00133 } 00134 break; 00135 case OSPF::Neighbor::LoadingState: 00136 case OSPF::Neighbor::FullState: 00137 { 00138 OSPF::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 (OSPF::Neighbor::SequenceNumberMismatch); 00147 } else { 00148 if (neighbor->GetDatabaseExchangeRelationship () == OSPF::Neighbor::Slave) { 00149 if (!neighbor->RetransmitDatabaseDescriptionPacket ()) { 00150 neighbor->ProcessEvent (OSPF::Neighbor::SequenceNumberMismatch); 00151 } 00152 } 00153 } 00154 } 00155 break; 00156 default: break; 00157 } 00158 } 00159 }