Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSPF::DatabaseDescriptionHandler Class Reference

#include <DatabaseDescriptionHandler.h>

Inheritance diagram for OSPF::DatabaseDescriptionHandler:

OSPF::IMessageHandler List of all members.

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)

Constructor & Destructor Documentation

OSPF::DatabaseDescriptionHandler::DatabaseDescriptionHandler Router containingRouter  ) 
 

00007                                                                                         :
00008     OSPF::IMessageHandler (containingRouter)
00009 {
00010 }


Member Function Documentation

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 (&currentHeader);
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
 

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 }


The documentation for this class was generated from the following files:
Generated on Sat Apr 1 20:52:25 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.1