INET Framework for OMNeT++/OMNEST
AnsaLinkStateRequestHandler.cc
Go to the documentation of this file.
00001 #include "AnsaLinkStateRequestHandler.h"
00002 #include "AnsaOSPFNeighbor.h"
00003 #include "AnsaOSPFRouter.h"
00004 #include <vector>
00005 
00006 AnsaOSPF::LinkStateRequestHandler::LinkStateRequestHandler(AnsaOSPF::Router* containingRouter) :
00007     AnsaOSPF::IMessageHandler(containingRouter)
00008 {
00009 }
00010 
00011 void AnsaOSPF::LinkStateRequestHandler::ProcessPacket(OSPFPacket* packet, AnsaOSPF::Interface* intf, AnsaOSPF::Neighbor* neighbor)
00012 {
00013     router->GetMessageHandler()->PrintEvent("Link State Request packet received", intf, neighbor);
00014 
00015     AnsaOSPF::Neighbor::NeighborStateType neighborState = neighbor->GetState();
00016 
00017     if ((neighborState == AnsaOSPF::Neighbor::ExchangeState) ||
00018         (neighborState == AnsaOSPF::Neighbor::LoadingState) ||
00019         (neighborState == AnsaOSPF::Neighbor::FullState))
00020     {
00021         OSPFLinkStateRequestPacket* lsRequestPacket = check_and_cast<OSPFLinkStateRequestPacket*> (packet);
00022 
00023         unsigned long         requestCount = lsRequestPacket->getRequestsArraySize();
00024         bool                  error        = false;
00025         std::vector<OSPFLSA*> lsas;
00026 
00027         EV << "  Processing packet contents:\n";
00028 
00029         for (unsigned long i = 0; i < requestCount; i++) {
00030             LSARequest&      request = lsRequestPacket->getRequests(i);
00031             AnsaOSPF::LSAKeyType lsaKey;
00032             char             addressString[16];
00033 
00034             EV << "    LSARequest: type="
00035                << request.lsType
00036                << ", LSID="
00037                << AddressStringFromULong(addressString, sizeof(addressString), request.linkStateID)
00038                << ", advertisingRouter="
00039                << AddressStringFromULong(addressString, sizeof(addressString), request.advertisingRouter.getInt())
00040                << "\n";
00041 
00042             lsaKey.linkStateID = request.linkStateID;
00043             lsaKey.advertisingRouter = request.advertisingRouter.getInt();
00044 
00045             OSPFLSA* lsaInDatabase = router->FindLSA(static_cast<LSAType> (request.lsType), lsaKey, intf->GetArea()->GetAreaID());
00046 
00047             if (lsaInDatabase != NULL) {
00048                 lsas.push_back(lsaInDatabase);
00049             } else {
00050                 error = true;
00051                 neighbor->ProcessEvent(AnsaOSPF::Neighbor::BadLinkStateRequest);
00052                 break;
00053             }
00054         }
00055 
00056         if (!error) {
00057             int                   updatesCount   = lsas.size();
00058             int                   ttl            = (intf->GetType() == AnsaOSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1;
00059             AnsaOSPF::MessageHandler* messageHandler = router->GetMessageHandler();
00060 
00061             for (int j = 0; j < updatesCount; j++) {
00062                 OSPFLinkStateUpdatePacket* updatePacket = intf->CreateUpdatePacket(lsas[j]);
00063                 if (updatePacket != NULL) {
00064                     if (intf->GetType() == AnsaOSPF::Interface::Broadcast) {
00065                         if ((intf->GetState() == AnsaOSPF::Interface::DesignatedRouterState) ||
00066                             (intf->GetState() == AnsaOSPF::Interface::BackupState) ||
00067                             (intf->GetDesignatedRouter() == AnsaOSPF::NullDesignatedRouterID))
00068                         {
00069                             messageHandler->SendPacket(updatePacket, AnsaOSPF::AllSPFRouters, intf->GetIfIndex(), ttl);
00070                         } else {
00071                             messageHandler->SendPacket(updatePacket, AnsaOSPF::AllDRouters, intf->GetIfIndex(), ttl);
00072                         }
00073                     } else {
00074                         if (intf->GetType() == AnsaOSPF::Interface::PointToPoint) {
00075                             messageHandler->SendPacket(updatePacket, AnsaOSPF::AllSPFRouters, intf->GetIfIndex(), ttl);
00076                         } else {
00077                             messageHandler->SendPacket(updatePacket, neighbor->GetAddress(), intf->GetIfIndex(), ttl);
00078                         }
00079                     }
00080 
00081                 }
00082             }
00083             // These update packets should not be placed on retransmission lists
00084         }
00085     }
00086 }