#include <DatabaseDescriptionHandler.h>
List of all members.
Constructor & Destructor Documentation
OSPF::DatabaseDescriptionHandler::DatabaseDescriptionHandler |
( |
OSPF::Router * |
containingRouter | ) |
|
Member Function Documentation
bool OSPF::DatabaseDescriptionHandler::ProcessDDPacket |
( |
OSPFDatabaseDescriptionPacket * |
ddPacket, |
|
|
OSPF::Interface * |
intf, |
|
|
OSPF::Neighbor * |
neighbor, |
|
|
bool |
inExchangeStart |
|
) |
| [private] |
Implements OSPF::IMessageHandler.
{
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;
}
}
}
The documentation for this class was generated from the following files: