#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) |
Definition at line 25 of file DatabaseDescriptionHandler.h.
OSPF::DatabaseDescriptionHandler::DatabaseDescriptionHandler | ( | OSPF::Router * | containingRouter | ) |
Definition at line 24 of file DatabaseDescriptionHandler.cc.
: OSPF::IMessageHandler(containingRouter) { }
bool OSPF::DatabaseDescriptionHandler::ProcessDDPacket | ( | OSPFDatabaseDescriptionPacket * | ddPacket, | |
OSPF::Interface * | intf, | |||
OSPF::Neighbor * | neighbor, | |||
bool | inExchangeStart | |||
) | [private] |
Definition at line 178 of file DatabaseDescriptionHandler.cc.
Referenced by ProcessPacket().
{ EV << " Processing packet contents(ddOptions=" << ((ddPacket->getDdOptions().I_Init) ? "I " : "_ ") << ((ddPacket->getDdOptions().M_More) ? "M " : "_ ") << ((ddPacket->getDdOptions().MS_MasterSlave) ? "MS" : "__") << "; seqNumber=" << ddPacket->getDdSequenceNumber() << "):\n"; unsigned int headerCount = ddPacket->getLsaHeadersArraySize(); for (unsigned int i = 0; i < headerCount; i++) { OSPFLSAHeader& currentHeader = ddPacket->getLsaHeaders(i); LSAType lsaType = static_cast<LSAType> (currentHeader.getLsType()); EV << " "; PrintLSAHeader(currentHeader, ev.getOStream()); if ((lsaType < RouterLSAType) || (lsaType > ASExternalLSAType) || ((lsaType == ASExternalLSAType) && (!intf->GetArea()->GetExternalRoutingCapability()))) { EV << " Error!\n"; neighbor->ProcessEvent(OSPF::Neighbor::SequenceNumberMismatch); return false; } else { OSPF::LSAKeyType lsaKey; lsaKey.linkStateID = currentHeader.getLinkStateID(); lsaKey.advertisingRouter = currentHeader.getAdvertisingRouter().getInt(); OSPFLSA* lsaInDatabase = router->FindLSA(lsaType, lsaKey, intf->GetArea()->GetAreaID()); // operator< and operator== on OSPFLSAHeaders determines which one is newer(less means older) if ((lsaInDatabase == NULL) || (lsaInDatabase->getHeader() < currentHeader)) { EV << " (newer)"; neighbor->AddToRequestList(¤tHeader); } } EV << "\n"; } if (neighbor->GetDatabaseExchangeRelationship() == OSPF::Neighbor::Master) { neighbor->IncrementDDSequenceNumber(); if ((neighbor->GetDatabaseSummaryListCount() == 0) && !ddPacket->getDdOptions().M_More) { neighbor->ProcessEvent(OSPF::Neighbor::ExchangeDone); // does nothing in ExchangeStart } else { if (!inExchangeStart) { neighbor->SendDatabaseDescriptionPacket(); } } } else { neighbor->SetDDSequenceNumber(ddPacket->getDdSequenceNumber()); if (!inExchangeStart) { neighbor->SendDatabaseDescriptionPacket(); } if (!ddPacket->getDdOptions().M_More && (neighbor->GetDatabaseSummaryListCount() == 0)) { neighbor->ProcessEvent(OSPF::Neighbor::ExchangeDone); // does nothing in ExchangeStart } } return true; }
void OSPF::DatabaseDescriptionHandler::ProcessPacket | ( | OSPFPacket * | packet, | |
OSPF::Interface * | intf, | |||
OSPF::Neighbor * | neighbor | |||
) | [virtual] |
Implements OSPF::IMessageHandler.
Definition at line 29 of file DatabaseDescriptionHandler.cc.
Referenced by OSPF::MessageHandler::ProcessPacket().
{ router->GetMessageHandler()->PrintEvent("Database Description packet received", intf, neighbor); OSPFDatabaseDescriptionPacket* ddPacket = check_and_cast<OSPFDatabaseDescriptionPacket*> (packet); OSPF::Neighbor::NeighborStateType neighborState = neighbor->GetState(); if ((ddPacket->getInterfaceMTU() <= intf->GetMTU()) && (neighborState > OSPF::Neighbor::AttemptState)) { switch (neighborState) { case OSPF::Neighbor::TwoWayState: break; case OSPF::Neighbor::InitState: neighbor->ProcessEvent(OSPF::Neighbor::TwoWayReceived); break; case OSPF::Neighbor::ExchangeStartState: { OSPFDDOptions& ddOptions = ddPacket->getDdOptions(); if (ddOptions.I_Init && ddOptions.M_More && ddOptions.MS_MasterSlave && (ddPacket->getLsaHeadersArraySize() == 0)) { if (neighbor->GetNeighborID() > router->GetRouterID()) { OSPF::Neighbor::DDPacketID packetID; packetID.ddOptions = ddOptions; packetID.options = ddPacket->getOptions(); packetID.sequenceNumber = ddPacket->getDdSequenceNumber(); neighbor->SetOptions(packetID.options); neighbor->SetDatabaseExchangeRelationship(OSPF::Neighbor::Slave); neighbor->SetDDSequenceNumber(packetID.sequenceNumber); neighbor->SetLastReceivedDDPacket(packetID); if (!ProcessDDPacket(ddPacket, intf, neighbor, true)) { break; } neighbor->ProcessEvent(OSPF::Neighbor::NegotiationDone); if (!neighbor->IsLinkStateRequestListEmpty() && !neighbor->IsRequestRetransmissionTimerActive()) { neighbor->SendLinkStateRequestPacket(); neighbor->ClearRequestRetransmissionTimer(); neighbor->StartRequestRetransmissionTimer(); } } else { neighbor->SendDatabaseDescriptionPacket(true); } } if (!ddOptions.I_Init && !ddOptions.MS_MasterSlave && (ddPacket->getDdSequenceNumber() == neighbor->GetDDSequenceNumber()) && (neighbor->GetNeighborID() < router->GetRouterID())) { OSPF::Neighbor::DDPacketID packetID; packetID.ddOptions = ddOptions; packetID.options = ddPacket->getOptions(); packetID.sequenceNumber = ddPacket->getDdSequenceNumber(); neighbor->SetOptions(packetID.options); neighbor->SetDatabaseExchangeRelationship(OSPF::Neighbor::Master); neighbor->SetLastReceivedDDPacket(packetID); if (!ProcessDDPacket(ddPacket, intf, neighbor, true)) { break; } neighbor->ProcessEvent(OSPF::Neighbor::NegotiationDone); if (!neighbor->IsLinkStateRequestListEmpty() && !neighbor->IsRequestRetransmissionTimerActive()) { neighbor->SendLinkStateRequestPacket(); neighbor->ClearRequestRetransmissionTimer(); neighbor->StartRequestRetransmissionTimer(); } } } break; case OSPF::Neighbor::ExchangeState: { OSPF::Neighbor::DDPacketID packetID; packetID.ddOptions = ddPacket->getDdOptions(); packetID.options = ddPacket->getOptions(); packetID.sequenceNumber = ddPacket->getDdSequenceNumber(); if (packetID != neighbor->GetLastReceivedDDPacket()) { if ((packetID.ddOptions.MS_MasterSlave && (neighbor->GetDatabaseExchangeRelationship() != OSPF::Neighbor::Slave)) || (!packetID.ddOptions.MS_MasterSlave && (neighbor->GetDatabaseExchangeRelationship() != OSPF::Neighbor::Master)) || packetID.ddOptions.I_Init || (packetID.options != neighbor->GetLastReceivedDDPacket().options)) { neighbor->ProcessEvent(OSPF::Neighbor::SequenceNumberMismatch); } else { if (((neighbor->GetDatabaseExchangeRelationship() == OSPF::Neighbor::Master) && (packetID.sequenceNumber == neighbor->GetDDSequenceNumber())) || ((neighbor->GetDatabaseExchangeRelationship() == OSPF::Neighbor::Slave) && (packetID.sequenceNumber == (neighbor->GetDDSequenceNumber() + 1)))) { neighbor->SetLastReceivedDDPacket(packetID); if (!ProcessDDPacket(ddPacket, intf, neighbor, false)) { break; } if (!neighbor->IsLinkStateRequestListEmpty() && !neighbor->IsRequestRetransmissionTimerActive()) { neighbor->SendLinkStateRequestPacket(); neighbor->ClearRequestRetransmissionTimer(); neighbor->StartRequestRetransmissionTimer(); } } else { neighbor->ProcessEvent(OSPF::Neighbor::SequenceNumberMismatch); } } } else { if (neighbor->GetDatabaseExchangeRelationship() == OSPF::Neighbor::Slave) { neighbor->RetransmitDatabaseDescriptionPacket(); } } } break; case OSPF::Neighbor::LoadingState: case OSPF::Neighbor::FullState: { OSPF::Neighbor::DDPacketID packetID; packetID.ddOptions = ddPacket->getDdOptions(); packetID.options = ddPacket->getOptions(); packetID.sequenceNumber = ddPacket->getDdSequenceNumber(); if ((packetID != neighbor->GetLastReceivedDDPacket()) || (packetID.ddOptions.I_Init)) { neighbor->ProcessEvent(OSPF::Neighbor::SequenceNumberMismatch); } else { if (neighbor->GetDatabaseExchangeRelationship() == OSPF::Neighbor::Slave) { if (!neighbor->RetransmitDatabaseDescriptionPacket()) { neighbor->ProcessEvent(OSPF::Neighbor::SequenceNumberMismatch); } } } } break; default: break; } } }