INET Framework for OMNeT++/OMNEST
AnsaOSPFNeighbor.cc
Go to the documentation of this file.
00001 #include "AnsaOSPFNeighbor.h"
00002 #include "AnsaOSPFNeighborState.h"
00003 #include "AnsaOSPFNeighborStateDown.h"
00004 #include "AnsaMessageHandler.h"
00005 #include "AnsaOSPFArea.h"
00006 #include "AnsaOSPFRouter.h"
00007 #include <memory.h>
00008 
00009 // FIXME!!! Should come from a global unique number generator module.
00010 unsigned long AnsaOSPF::Neighbor::ddSequenceNumberInitSeed = 0;
00011 
00012 AnsaOSPF::Neighbor::Neighbor(RouterID neighbor) :
00013     updateRetransmissionTimerActive(false),
00014     requestRetransmissionTimerActive(false),
00015     firstAdjacencyInited(false),
00016     ddSequenceNumber(0),
00017     neighborID(neighbor),
00018     neighborPriority(0),
00019     neighborIPAddress(AnsaOSPF::NullIPv4Address),
00020     neighborsDesignatedRouter(AnsaOSPF::NullDesignatedRouterID),
00021     neighborsBackupDesignatedRouter(AnsaOSPF::NullDesignatedRouterID),
00022     designatedRoutersSetUp(false),
00023     neighborsRouterDeadInterval(40),
00024     lastTransmittedDDPacket(NULL)
00025 {
00026     memset(&lastReceivedDDPacket, 0, sizeof(AnsaOSPF::Neighbor::DDPacketID));
00027     // setting only I and M bits is invalid -> good initializer
00028     lastReceivedDDPacket.ddOptions.I_Init = true;
00029     lastReceivedDDPacket.ddOptions.M_More = true;
00030     inactivityTimer = new OSPFTimer;
00031     inactivityTimer->setTimerKind(NeighborInactivityTimer);
00032     inactivityTimer->setContextPointer(this);
00033     inactivityTimer->setName("AnsaOSPF::Neighbor::NeighborInactivityTimer");
00034     pollTimer = new OSPFTimer;
00035     pollTimer->setTimerKind(NeighborPollTimer);
00036     pollTimer->setContextPointer(this);
00037     pollTimer->setName("AnsaOSPF::Neighbor::NeighborPollTimer");
00038     ddRetransmissionTimer = new OSPFTimer;
00039     ddRetransmissionTimer->setTimerKind(NeighborDDRetransmissionTimer);
00040     ddRetransmissionTimer->setContextPointer(this);
00041     ddRetransmissionTimer->setName("AnsaOSPF::Neighbor::NeighborDDRetransmissionTimer");
00042     updateRetransmissionTimer = new OSPFTimer;
00043     updateRetransmissionTimer->setTimerKind(NeighborUpdateRetransmissionTimer);
00044     updateRetransmissionTimer->setContextPointer(this);
00045     updateRetransmissionTimer->setName("AnsaOSPF::Neighbor::Neighbor::NeighborUpdateRetransmissionTimer");
00046     requestRetransmissionTimer = new OSPFTimer;
00047     requestRetransmissionTimer->setTimerKind(NeighborRequestRetransmissionTimer);
00048     requestRetransmissionTimer->setContextPointer(this);
00049     requestRetransmissionTimer->setName("AnsaOSPF::Neighbor::NeighborRequestRetransmissionTimer");
00050     state = new AnsaOSPF::NeighborStateDown;
00051     previousState = NULL;
00052 }
00053 
00054 AnsaOSPF::Neighbor::~Neighbor(void)
00055 {
00056     Reset();
00057     MessageHandler* messageHandler = parentInterface->GetArea()->GetRouter()->GetMessageHandler();
00058     messageHandler->ClearTimer(inactivityTimer);
00059     messageHandler->ClearTimer(pollTimer);
00060     delete inactivityTimer;
00061     delete pollTimer;
00062     delete ddRetransmissionTimer;
00063     delete updateRetransmissionTimer;
00064     delete requestRetransmissionTimer;
00065     if (previousState != NULL) {
00066         delete previousState;
00067     }
00068     delete state;
00069 }
00070 
00071 void AnsaOSPF::Neighbor::ChangeState(NeighborState* newState, NeighborState* currentState)
00072 {
00073     if (previousState != NULL) {
00074         delete previousState;
00075     }
00076     state = newState;
00077     previousState = currentState;
00078 }
00079 
00080 void AnsaOSPF::Neighbor::ProcessEvent(AnsaOSPF::Neighbor::NeighborEventType event)
00081 {
00082     state->ProcessEvent(this, event);
00083 }
00084 
00085 void AnsaOSPF::Neighbor::Reset(void)
00086 {
00087     for (std::list<OSPFLSA*>::iterator retIt = linkStateRetransmissionList.begin();
00088          retIt != linkStateRetransmissionList.end();
00089          retIt++)
00090     {
00091         delete(*retIt);
00092     }
00093     linkStateRetransmissionList.clear();
00094 
00095     std::list<OSPFLSAHeader*>::iterator it;
00096     for (it = databaseSummaryList.begin(); it != databaseSummaryList.end(); it++) {
00097         delete(*it);
00098     }
00099     databaseSummaryList.clear();
00100     for (it = linkStateRequestList.begin(); it != linkStateRequestList.end(); it++)
00101     {
00102         delete(*it);
00103     }
00104     linkStateRequestList.clear();
00105 
00106     parentInterface->GetArea()->GetRouter()->GetMessageHandler()->ClearTimer(ddRetransmissionTimer);
00107     ClearUpdateRetransmissionTimer();
00108     ClearRequestRetransmissionTimer();
00109 
00110     if (lastTransmittedDDPacket != NULL) {
00111         delete lastTransmittedDDPacket;
00112         lastTransmittedDDPacket = NULL;
00113     }
00114 }
00115 
00116 void AnsaOSPF::Neighbor::InitFirstAdjacency(void)
00117 {
00118     ddSequenceNumber = GetUniqueULong();
00119     firstAdjacencyInited = true;
00120 }
00121 
00122 unsigned long AnsaOSPF::Neighbor::GetUniqueULong(void)
00123 {
00124     // FIXME!!! Should come from a global unique number generator module.
00125     return (ddSequenceNumberInitSeed++);
00126 }
00127 
00128 AnsaOSPF::Neighbor::NeighborStateType AnsaOSPF::Neighbor::GetState(void) const
00129 {
00130     return state->GetState();
00131 }
00132 
00133 const char* AnsaOSPF::Neighbor::GetStateString(AnsaOSPF::Neighbor::NeighborStateType stateType)
00134 {
00135     switch (stateType) {
00136         case DownState:             return "Down";
00137         case AttemptState:          return "Attempt";
00138         case InitState:             return "Init";
00139         case TwoWayState:           return "TwoWay";
00140         case ExchangeStartState:    return "ExchangeStart";
00141         case ExchangeState:         return "Exchange";
00142         case LoadingState:          return "Loading";
00143         case FullState:             return "Full";
00144         default:                    ASSERT(false);
00145     }
00146     return "";
00147 }
00148 
00149 void AnsaOSPF::Neighbor::SendDatabaseDescriptionPacket(bool init)
00150 {
00151     OSPFDatabaseDescriptionPacket* ddPacket = new OSPFDatabaseDescriptionPacket;
00152 
00153     ddPacket->setType(DatabaseDescriptionPacket);
00154     ddPacket->setRouterID(parentInterface->GetArea()->GetRouter()->GetRouterID());
00155     ddPacket->setAreaID(parentInterface->GetArea()->GetAreaID());
00156     ddPacket->setAuthenticationType(parentInterface->GetAuthenticationType());
00157     AnsaOSPF::AuthenticationKeyType authKey = parentInterface->GetAuthenticationKey();
00158     for (int i = 0; i < 8; i++) {
00159         ddPacket->setAuthentication(i, authKey.bytes[i]);
00160     }
00161 
00162     if (parentInterface->GetType() != AnsaOSPF::Interface::Virtual) {
00163         ddPacket->setInterfaceMTU(parentInterface->GetMTU());
00164     } else {
00165         ddPacket->setInterfaceMTU(0);
00166     }
00167 
00168     OSPFOptions options;
00169     memset(&options, 0, sizeof(OSPFOptions));
00170     options.E_ExternalRoutingCapability = parentInterface->GetArea()->GetExternalRoutingCapability();
00171     ddPacket->setOptions(options);
00172 
00173     ddPacket->setDdSequenceNumber(ddSequenceNumber);
00174 
00175     long maxPacketSize = ((IPV4_HEADER_LENGTH + OSPF_HEADER_LENGTH + OSPF_DD_HEADER_LENGTH + OSPF_LSA_HEADER_LENGTH) > parentInterface->GetMTU()) ?
00176                           IPV4_DATAGRAM_LENGTH :
00177                           parentInterface->GetMTU();
00178 
00179     if (init || databaseSummaryList.empty()) {
00180         ddPacket->setLsaHeadersArraySize(0);
00181     } else {
00182         // delete included LSAs from summary list
00183         // (they are still in lastTransmittedDDPacket)
00184         long packetSize = IPV4_HEADER_LENGTH + OSPF_HEADER_LENGTH + OSPF_DD_HEADER_LENGTH;
00185         while ((!databaseSummaryList.empty()) && (packetSize <= (maxPacketSize - OSPF_LSA_HEADER_LENGTH))) {
00186             unsigned long   headerCount = ddPacket->getLsaHeadersArraySize();
00187             OSPFLSAHeader*  lsaHeader   = *(databaseSummaryList.begin());
00188             ddPacket->setLsaHeadersArraySize(headerCount + 1);
00189             ddPacket->setLsaHeaders(headerCount, *lsaHeader);
00190             delete lsaHeader;
00191             databaseSummaryList.pop_front();
00192             packetSize += OSPF_LSA_HEADER_LENGTH;
00193         }
00194     }
00195 
00196     OSPFDDOptions ddOptions;
00197     memset(&ddOptions, 0, sizeof(OSPFDDOptions));
00198     if (init) {
00199         ddOptions.I_Init = true;
00200         ddOptions.M_More = true;
00201         ddOptions.MS_MasterSlave = true;
00202     } else {
00203         ddOptions.I_Init = false;
00204         ddOptions.M_More = (databaseSummaryList.empty()) ? false : true;
00205         ddOptions.MS_MasterSlave = (databaseExchangeRelationship == AnsaOSPF::Neighbor::Master) ? true : false;
00206     }
00207     ddPacket->setDdOptions(ddOptions);
00208 
00209     ddPacket->setPacketLength(0); // TODO: Calculate correct length
00210     ddPacket->setChecksum(0); // TODO: Calculate correct cheksum(16-bit one's complement of the entire packet)
00211 
00212     AnsaOSPF::MessageHandler* messageHandler = parentInterface->GetArea()->GetRouter()->GetMessageHandler();
00213     int ttl = (parentInterface->GetType() == AnsaOSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1;
00214     if (parentInterface->GetType() == AnsaOSPF::Interface::PointToPoint) {
00215         messageHandler->SendPacket(ddPacket, AnsaOSPF::AllSPFRouters, parentInterface->GetIfIndex(), ttl);
00216     } else {
00217         messageHandler->SendPacket(ddPacket, neighborIPAddress, parentInterface->GetIfIndex(), ttl);
00218     }
00219 
00220     if (lastTransmittedDDPacket != NULL) {
00221         delete lastTransmittedDDPacket;
00222     }
00223     lastTransmittedDDPacket = new OSPFDatabaseDescriptionPacket(*ddPacket);
00224 }
00225 
00226 bool AnsaOSPF::Neighbor::RetransmitDatabaseDescriptionPacket(void)
00227 {
00228     if (lastTransmittedDDPacket != NULL) {
00229         OSPFDatabaseDescriptionPacket* ddPacket       = new OSPFDatabaseDescriptionPacket(*lastTransmittedDDPacket);
00230         AnsaOSPF::MessageHandler*          messageHandler = parentInterface->GetArea()->GetRouter()->GetMessageHandler();
00231         int                            ttl            = (parentInterface->GetType() == AnsaOSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1;
00232 
00233         if (parentInterface->GetType() == AnsaOSPF::Interface::PointToPoint) {
00234             messageHandler->SendPacket(ddPacket, AnsaOSPF::AllSPFRouters, parentInterface->GetIfIndex(), ttl);
00235         } else {
00236             messageHandler->SendPacket(ddPacket, neighborIPAddress, parentInterface->GetIfIndex(), ttl);
00237         }
00238 
00239         return true;
00240     } else {
00241         return false;
00242     }
00243 }
00244 
00245 void AnsaOSPF::Neighbor::CreateDatabaseSummary(void)
00246 {
00247     AnsaOSPF::Area*   area           = parentInterface->GetArea();
00248     unsigned long routerLSACount = area->GetRouterLSACount();
00249 
00250     /* Note: OSPF specification says:
00251      * "LSAs whose age is equal to MaxAge are instead added to the neighbor's
00252      *  Link state retransmission list."
00253      * But this task has been already done during the aging of the database. (???)
00254      * So we'll skip this.
00255      */
00256     for (unsigned long i = 0; i < routerLSACount; i++) {
00257         if (area->GetRouterLSA(i)->getHeader().getLsAge() < MAX_AGE) {
00258             OSPFLSAHeader* routerLSA = new OSPFLSAHeader(area->GetRouterLSA(i)->getHeader());
00259             databaseSummaryList.push_back(routerLSA);
00260         }
00261     }
00262 
00263     unsigned long networkLSACount = area->GetNetworkLSACount();
00264     for (unsigned long j = 0; j < networkLSACount; j++) {
00265         if (area->GetNetworkLSA(j)->getHeader().getLsAge() < MAX_AGE) {
00266             OSPFLSAHeader* networkLSA = new OSPFLSAHeader(area->GetNetworkLSA(j)->getHeader());
00267             databaseSummaryList.push_back(networkLSA);
00268         }
00269     }
00270 
00271     unsigned long summaryLSACount = area->GetSummaryLSACount();
00272     for (unsigned long k = 0; k < summaryLSACount; k++) {
00273         if (area->GetSummaryLSA(k)->getHeader().getLsAge() < MAX_AGE) {
00274             OSPFLSAHeader* summaryLSA = new OSPFLSAHeader(area->GetSummaryLSA(k)->getHeader());
00275             databaseSummaryList.push_back(summaryLSA);
00276         }
00277     }
00278 
00279     if ((parentInterface->GetType() != AnsaOSPF::Interface::Virtual) &&
00280         (area->GetExternalRoutingCapability()))
00281     {
00282         AnsaOSPF::Router* router             = area->GetRouter();
00283         unsigned long asExternalLSACount = router->GetASExternalLSACount();
00284 
00285         for (unsigned long m = 0; m < asExternalLSACount; m++) {
00286             if (router->GetASExternalLSA(m)->getHeader().getLsAge() < MAX_AGE) {
00287                 OSPFLSAHeader* asExternalLSA = new OSPFLSAHeader(router->GetASExternalLSA(m)->getHeader());
00288                 databaseSummaryList.push_back(asExternalLSA);
00289             }
00290         }
00291     }
00292 }
00293 
00294 void AnsaOSPF::Neighbor::SendLinkStateRequestPacket(void)
00295 {
00296     OSPFLinkStateRequestPacket* requestPacket = new OSPFLinkStateRequestPacket;
00297 
00298     requestPacket->setType(LinkStateRequestPacket);
00299     requestPacket->setRouterID(parentInterface->GetArea()->GetRouter()->GetRouterID());
00300     requestPacket->setAreaID(parentInterface->GetArea()->GetAreaID());
00301     requestPacket->setAuthenticationType(parentInterface->GetAuthenticationType());
00302     AnsaOSPF::AuthenticationKeyType authKey = parentInterface->GetAuthenticationKey();
00303     for (int i = 0; i < 8; i++) {
00304         requestPacket->setAuthentication(i, authKey.bytes[i]);
00305     }
00306 
00307     long maxPacketSize = ((IPV4_HEADER_LENGTH + OSPF_HEADER_LENGTH + OSPF_REQUEST_LENGTH) > parentInterface->GetMTU()) ?
00308                           IPV4_DATAGRAM_LENGTH :
00309                           parentInterface->GetMTU();
00310 
00311     if (linkStateRequestList.empty()) {
00312         requestPacket->setRequestsArraySize(0);
00313     } else {
00314         long packetSize = IPV4_HEADER_LENGTH + OSPF_HEADER_LENGTH;
00315         std::list<OSPFLSAHeader*>::iterator it = linkStateRequestList.begin();
00316 
00317         while ((it != linkStateRequestList.end()) && (packetSize <= (maxPacketSize - OSPF_REQUEST_LENGTH))) {
00318             unsigned long  requestCount  = requestPacket->getRequestsArraySize();
00319             OSPFLSAHeader* requestHeader = (*it);
00320             LSARequest     request;
00321 
00322             request.lsType = requestHeader->getLsType();
00323             request.linkStateID = requestHeader->getLinkStateID();
00324             request.advertisingRouter = requestHeader->getAdvertisingRouter();
00325 
00326             requestPacket->setRequestsArraySize(requestCount + 1);
00327             requestPacket->setRequests(requestCount, request);
00328 
00329             packetSize += OSPF_REQUEST_LENGTH;
00330             it++;
00331         }
00332     }
00333 
00334     requestPacket->setPacketLength(0); // TODO: Calculate correct length
00335     requestPacket->setChecksum(0); // TODO: Calculate correct cheksum(16-bit one's complement of the entire packet)
00336 
00337     AnsaOSPF::MessageHandler* messageHandler = parentInterface->GetArea()->GetRouter()->GetMessageHandler();
00338     int ttl = (parentInterface->GetType() == AnsaOSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1;
00339     if (parentInterface->GetType() == AnsaOSPF::Interface::PointToPoint) {
00340         messageHandler->SendPacket(requestPacket, AnsaOSPF::AllSPFRouters, parentInterface->GetIfIndex(), ttl);
00341     } else {
00342         messageHandler->SendPacket(requestPacket, neighborIPAddress, parentInterface->GetIfIndex(), ttl);
00343     }
00344 }
00345 
00346 bool AnsaOSPF::Neighbor::NeedAdjacency(void)
00347 {
00348     AnsaOSPF::Interface::OSPFInterfaceType interfaceType = parentInterface->GetType();
00349     AnsaOSPF::RouterID                     routerID      = parentInterface->GetArea()->GetRouter()->GetRouterID();
00350     AnsaOSPF::DesignatedRouterID           dRouter       = parentInterface->GetDesignatedRouter();
00351     AnsaOSPF::DesignatedRouterID           backupDRouter = parentInterface->GetBackupDesignatedRouter();
00352 
00353     if ((interfaceType == AnsaOSPF::Interface::PointToPoint) ||
00354         (interfaceType == AnsaOSPF::Interface::PointToMultiPoint) ||
00355         (interfaceType == AnsaOSPF::Interface::Virtual) ||
00356         (dRouter.routerID == routerID) ||
00357         (backupDRouter.routerID == routerID) ||
00358         ((neighborsDesignatedRouter.routerID == dRouter.routerID) ||
00359          (!designatedRoutersSetUp &&
00360           (neighborsDesignatedRouter.ipInterfaceAddress == dRouter.ipInterfaceAddress))) ||
00361         ((neighborsBackupDesignatedRouter.routerID == backupDRouter.routerID) ||
00362          (!designatedRoutersSetUp &&
00363           (neighborsBackupDesignatedRouter.ipInterfaceAddress == backupDRouter.ipInterfaceAddress))))
00364     {
00365         return true;
00366     } else {
00367         return false;
00368     }
00369 }
00370 
00376 void AnsaOSPF::Neighbor::AddToRetransmissionList(OSPFLSA* lsa)
00377 {
00378     std::list<OSPFLSA*>::iterator it;
00379     for (it = linkStateRetransmissionList.begin(); it != linkStateRetransmissionList.end(); it++) {
00380         if (((*it)->getHeader().getLinkStateID() == lsa->getHeader().getLinkStateID()) &&
00381             ((*it)->getHeader().getAdvertisingRouter().getInt() == lsa->getHeader().getAdvertisingRouter().getInt()))
00382         {
00383             break;
00384         }
00385     }
00386 
00387     OSPFLSA* lsaCopy = NULL;
00388     switch (lsa->getHeader().getLsType()) {
00389         case RouterLSAType:
00390             lsaCopy = new OSPFRouterLSA(*(check_and_cast<OSPFRouterLSA*> (lsa)));
00391             break;
00392         case NetworkLSAType:
00393             lsaCopy = new OSPFNetworkLSA(*(check_and_cast<OSPFNetworkLSA*> (lsa)));
00394             break;
00395         case SummaryLSA_NetworksType:
00396         case SummaryLSA_ASBoundaryRoutersType:
00397             lsaCopy = new OSPFSummaryLSA(*(check_and_cast<OSPFSummaryLSA*> (lsa)));
00398             break;
00399         case ASExternalLSAType:
00400             lsaCopy = new OSPFASExternalLSA(*(check_and_cast<OSPFASExternalLSA*> (lsa)));
00401             break;
00402         default:
00403             ASSERT(false); // error
00404             break;
00405     }
00406 
00407     if (it != linkStateRetransmissionList.end()) {
00408         delete(*it);
00409         *it = static_cast<OSPFLSA*> (lsaCopy);
00410     } else {
00411         linkStateRetransmissionList.push_back(static_cast<OSPFLSA*> (lsaCopy));
00412     }
00413 }
00414 
00415 void AnsaOSPF::Neighbor::RemoveFromRetransmissionList(AnsaOSPF::LSAKeyType lsaKey)
00416 {
00417     std::list<OSPFLSA*>::iterator it = linkStateRetransmissionList.begin();
00418     while (it != linkStateRetransmissionList.end()) {
00419         if (((*it)->getHeader().getLinkStateID() == lsaKey.linkStateID) &&
00420             ((*it)->getHeader().getAdvertisingRouter().getInt() == lsaKey.advertisingRouter))
00421         {
00422             delete(*it);
00423             it = linkStateRetransmissionList.erase(it);
00424         } else {
00425             it++;
00426         }
00427     }
00428 }
00429 
00430 bool AnsaOSPF::Neighbor::IsLSAOnRetransmissionList(AnsaOSPF::LSAKeyType lsaKey) const
00431 {
00432     for (std::list<OSPFLSA*>::const_iterator it = linkStateRetransmissionList.begin(); it != linkStateRetransmissionList.end(); it++) {
00433         const OSPFLSA* lsa = *it;
00434         if ((lsa->getHeader().getLinkStateID() == lsaKey.linkStateID) &&
00435             (lsa->getHeader().getAdvertisingRouter().getInt() == lsaKey.advertisingRouter))
00436         {
00437             return true;
00438         }
00439     }
00440     return false;
00441 }
00442 
00443 OSPFLSA* AnsaOSPF::Neighbor::FindOnRetransmissionList(AnsaOSPF::LSAKeyType lsaKey)
00444 {
00445     for (std::list<OSPFLSA*>::iterator it = linkStateRetransmissionList.begin(); it != linkStateRetransmissionList.end(); it++) {
00446         if (((*it)->getHeader().getLinkStateID() == lsaKey.linkStateID) &&
00447             ((*it)->getHeader().getAdvertisingRouter().getInt() == lsaKey.advertisingRouter))
00448         {
00449             return (*it);
00450         }
00451     }
00452     return NULL;
00453 }
00454 
00455 void AnsaOSPF::Neighbor::StartUpdateRetransmissionTimer(void)
00456 {
00457     MessageHandler* messageHandler = parentInterface->GetArea()->GetRouter()->GetMessageHandler();
00458     messageHandler->StartTimer(updateRetransmissionTimer, parentInterface->GetRetransmissionInterval());
00459     updateRetransmissionTimerActive = true;
00460 }
00461 
00462 void AnsaOSPF::Neighbor::ClearUpdateRetransmissionTimer(void)
00463 {
00464     MessageHandler* messageHandler = parentInterface->GetArea()->GetRouter()->GetMessageHandler();
00465     messageHandler->ClearTimer(updateRetransmissionTimer);
00466     updateRetransmissionTimerActive = false;
00467 }
00468 
00469 void AnsaOSPF::Neighbor::AddToRequestList(OSPFLSAHeader* lsaHeader)
00470 {
00471     linkStateRequestList.push_back(new OSPFLSAHeader(*lsaHeader));
00472 }
00473 
00474 void AnsaOSPF::Neighbor::RemoveFromRequestList(AnsaOSPF::LSAKeyType lsaKey)
00475 {
00476     std::list<OSPFLSAHeader*>::iterator it = linkStateRequestList.begin();
00477     while (it != linkStateRequestList.end()) {
00478         if (((*it)->getLinkStateID() == lsaKey.linkStateID) &&
00479             ((*it)->getAdvertisingRouter().getInt() == lsaKey.advertisingRouter))
00480         {
00481             delete(*it);
00482             it = linkStateRequestList.erase(it);
00483         } else {
00484             it++;
00485         }
00486     }
00487 
00488     if ((GetState() == AnsaOSPF::Neighbor::LoadingState) && (linkStateRequestList.empty())) {
00489         ClearRequestRetransmissionTimer();
00490         ProcessEvent(AnsaOSPF::Neighbor::LoadingDone);
00491     }
00492 }
00493 
00494 bool AnsaOSPF::Neighbor::IsLSAOnRequestList(AnsaOSPF::LSAKeyType lsaKey) const
00495 {
00496     for (std::list<OSPFLSAHeader*>::const_iterator it = linkStateRequestList.begin(); it != linkStateRequestList.end(); it++) {
00497         const OSPFLSAHeader* lsaHeader = *it;
00498         if ((lsaHeader->getLinkStateID() == lsaKey.linkStateID) &&
00499             (lsaHeader->getAdvertisingRouter().getInt() == lsaKey.advertisingRouter))
00500         {
00501             return true;
00502         }
00503     }
00504     return false;
00505 }
00506 
00507 OSPFLSAHeader* AnsaOSPF::Neighbor::FindOnRequestList(AnsaOSPF::LSAKeyType lsaKey)
00508 {
00509     for (std::list<OSPFLSAHeader*>::iterator it = linkStateRequestList.begin(); it != linkStateRequestList.end(); it++) {
00510         if (((*it)->getLinkStateID() == lsaKey.linkStateID) &&
00511             ((*it)->getAdvertisingRouter().getInt() == lsaKey.advertisingRouter))
00512         {
00513             return (*it);
00514         }
00515     }
00516     return NULL;
00517 }
00518 
00519 void AnsaOSPF::Neighbor::StartRequestRetransmissionTimer(void)
00520 {
00521     MessageHandler* messageHandler = parentInterface->GetArea()->GetRouter()->GetMessageHandler();
00522     messageHandler->StartTimer(requestRetransmissionTimer, parentInterface->GetRetransmissionInterval());
00523     requestRetransmissionTimerActive = true;
00524 }
00525 
00526 void AnsaOSPF::Neighbor::ClearRequestRetransmissionTimer(void)
00527 {
00528     MessageHandler* messageHandler = parentInterface->GetArea()->GetRouter()->GetMessageHandler();
00529     messageHandler->ClearTimer(requestRetransmissionTimer);
00530     requestRetransmissionTimerActive = false;
00531 }
00532 
00533 void AnsaOSPF::Neighbor::AddToTransmittedLSAList(AnsaOSPF::LSAKeyType lsaKey)
00534 {
00535     TransmittedLSA transmit;
00536 
00537     transmit.lsaKey = lsaKey;
00538     transmit.age = 0;
00539 
00540     transmittedLSAs.push_back(transmit);
00541 }
00542 
00543 bool AnsaOSPF::Neighbor::IsOnTransmittedLSAList(AnsaOSPF::LSAKeyType lsaKey) const
00544 {
00545     for (std::list<TransmittedLSA>::const_iterator it = transmittedLSAs.begin(); it != transmittedLSAs.end(); it++) {
00546         if ((it->lsaKey.linkStateID == lsaKey.linkStateID) &&
00547             (it->lsaKey.advertisingRouter == lsaKey.advertisingRouter))
00548         {
00549             return true;
00550         }
00551     }
00552     return false;
00553 }
00554 
00555 void AnsaOSPF::Neighbor::AgeTransmittedLSAList(void)
00556 {
00557     std::list<TransmittedLSA>::iterator it = transmittedLSAs.begin();
00558     while ((it != transmittedLSAs.end()) && (it->age == MIN_LS_ARRIVAL)) {
00559         transmittedLSAs.pop_front();
00560         it = transmittedLSAs.begin();
00561     }
00562     for (it = transmittedLSAs.begin(); it != transmittedLSAs.end(); it++) {
00563         it->age++;
00564     }
00565 }
00566 
00567 void AnsaOSPF::Neighbor::RetransmitUpdatePacket(void)
00568 {
00569     OSPFLinkStateUpdatePacket* updatePacket = new OSPFLinkStateUpdatePacket;
00570 
00571     updatePacket->setType(LinkStateUpdatePacket);
00572     updatePacket->setRouterID(parentInterface->GetArea()->GetRouter()->GetRouterID());
00573     updatePacket->setAreaID(parentInterface->GetArea()->GetAreaID());
00574     updatePacket->setAuthenticationType(parentInterface->GetAuthenticationType());
00575     AnsaOSPF::AuthenticationKeyType authKey = parentInterface->GetAuthenticationKey();
00576     for (int i = 0; i < 8; i++) {
00577         updatePacket->setAuthentication(i, authKey.bytes[i]);
00578     }
00579 
00580     bool                          packetFull   = false;
00581     unsigned short                lsaCount     = 0;
00582     unsigned long                 packetLength = IPV4_HEADER_LENGTH + OSPF_LSA_HEADER_LENGTH;
00583     std::list<OSPFLSA*>::iterator it           = linkStateRetransmissionList.begin();
00584 
00585     while (!packetFull && (it != linkStateRetransmissionList.end())) {
00586         LSAType            lsaType       = static_cast<LSAType> ((*it)->getHeader().getLsType());
00587         OSPFRouterLSA*     routerLSA     = (lsaType == RouterLSAType) ? dynamic_cast<OSPFRouterLSA*> (*it) : NULL;
00588         OSPFNetworkLSA*    networkLSA    = (lsaType == NetworkLSAType) ? dynamic_cast<OSPFNetworkLSA*> (*it) : NULL;
00589         OSPFSummaryLSA*    summaryLSA    = ((lsaType == SummaryLSA_NetworksType) ||
00590                                             (lsaType == SummaryLSA_ASBoundaryRoutersType)) ? dynamic_cast<OSPFSummaryLSA*> (*it) : NULL;
00591         OSPFASExternalLSA* asExternalLSA = (lsaType == ASExternalLSAType) ? dynamic_cast<OSPFASExternalLSA*> (*it) : NULL;
00592         long               lsaSize       = 0;
00593         bool               includeLSA    = false;
00594 
00595         switch (lsaType) {
00596             case RouterLSAType:
00597                 if (routerLSA != NULL) {
00598                     lsaSize = CalculateLSASize(routerLSA);
00599                 }
00600                 break;
00601             case NetworkLSAType:
00602                 if (networkLSA != NULL) {
00603                     lsaSize = CalculateLSASize(networkLSA);
00604                 }
00605                 break;
00606             case SummaryLSA_NetworksType:
00607             case SummaryLSA_ASBoundaryRoutersType:
00608                 if (summaryLSA != NULL) {
00609                     lsaSize = CalculateLSASize(summaryLSA);
00610                 }
00611                 break;
00612             case ASExternalLSAType:
00613                 if (asExternalLSA != NULL) {
00614                     lsaSize = CalculateLSASize(asExternalLSA);
00615                 }
00616                 break;
00617             default: break;
00618         }
00619 
00620         if (packetLength + lsaSize < parentInterface->GetMTU()) {
00621             includeLSA = true;
00622             lsaCount++;
00623         } else {
00624             if ((lsaCount == 0) && (packetLength + lsaSize < IPV4_DATAGRAM_LENGTH)) {
00625                 includeLSA = true;
00626                 lsaCount++;
00627                 packetFull = true;
00628             }
00629         }
00630 
00631         if (includeLSA) {
00632             switch (lsaType) {
00633                 case RouterLSAType:
00634                     if (routerLSA != NULL) {
00635                         unsigned int routerLSACount = updatePacket->getRouterLSAsArraySize();
00636 
00637                         updatePacket->setRouterLSAsArraySize(routerLSACount + 1);
00638                         updatePacket->setRouterLSAs(routerLSACount, *routerLSA);
00639 
00640                         unsigned short lsAge = updatePacket->getRouterLSAs(routerLSACount).getHeader().getLsAge();
00641                         if (lsAge < MAX_AGE - parentInterface->GetTransmissionDelay()) {
00642                             updatePacket->getRouterLSAs(routerLSACount).getHeader().setLsAge(lsAge + parentInterface->GetTransmissionDelay());
00643                         } else {
00644                             updatePacket->getRouterLSAs(routerLSACount).getHeader().setLsAge(MAX_AGE);
00645                         }
00646                     }
00647                     break;
00648                 case NetworkLSAType:
00649                     if (networkLSA != NULL) {
00650                         unsigned int networkLSACount = updatePacket->getNetworkLSAsArraySize();
00651 
00652                         updatePacket->setNetworkLSAsArraySize(networkLSACount + 1);
00653                         updatePacket->setNetworkLSAs(networkLSACount, *networkLSA);
00654 
00655                         unsigned short lsAge = updatePacket->getNetworkLSAs(networkLSACount).getHeader().getLsAge();
00656                         if (lsAge < MAX_AGE - parentInterface->GetTransmissionDelay()) {
00657                             updatePacket->getNetworkLSAs(networkLSACount).getHeader().setLsAge(lsAge + parentInterface->GetTransmissionDelay());
00658                         } else {
00659                             updatePacket->getNetworkLSAs(networkLSACount).getHeader().setLsAge(MAX_AGE);
00660                         }
00661                     }
00662                     break;
00663                 case SummaryLSA_NetworksType:
00664                 case SummaryLSA_ASBoundaryRoutersType:
00665                     if (summaryLSA != NULL) {
00666                         unsigned int summaryLSACount = updatePacket->getSummaryLSAsArraySize();
00667 
00668                         updatePacket->setSummaryLSAsArraySize(summaryLSACount + 1);
00669                         updatePacket->setSummaryLSAs(summaryLSACount, *summaryLSA);
00670 
00671                         unsigned short lsAge = updatePacket->getSummaryLSAs(summaryLSACount).getHeader().getLsAge();
00672                         if (lsAge < MAX_AGE - parentInterface->GetTransmissionDelay()) {
00673                             updatePacket->getSummaryLSAs(summaryLSACount).getHeader().setLsAge(lsAge + parentInterface->GetTransmissionDelay());
00674                         } else {
00675                             updatePacket->getSummaryLSAs(summaryLSACount).getHeader().setLsAge(MAX_AGE);
00676                         }
00677                     }
00678                     break;
00679                 case ASExternalLSAType:
00680                     if (asExternalLSA != NULL) {
00681                         unsigned int asExternalLSACount = updatePacket->getAsExternalLSAsArraySize();
00682 
00683                         updatePacket->setAsExternalLSAsArraySize(asExternalLSACount + 1);
00684                         updatePacket->setAsExternalLSAs(asExternalLSACount, *asExternalLSA);
00685 
00686                         unsigned short lsAge = updatePacket->getAsExternalLSAs(asExternalLSACount).getHeader().getLsAge();
00687                         if (lsAge < MAX_AGE - parentInterface->GetTransmissionDelay()) {
00688                             updatePacket->getAsExternalLSAs(asExternalLSACount).getHeader().setLsAge(lsAge + parentInterface->GetTransmissionDelay());
00689                         } else {
00690                             updatePacket->getAsExternalLSAs(asExternalLSACount).getHeader().setLsAge(MAX_AGE);
00691                         }
00692                     }
00693                     break;
00694                 default: break;
00695             }
00696         }
00697 
00698         it++;
00699     }
00700 
00701     updatePacket->setPacketLength(0); // TODO: Calculate correct length
00702     updatePacket->setChecksum(0); // TODO: Calculate correct cheksum(16-bit one's complement of the entire packet)
00703 
00704     AnsaOSPF::MessageHandler* messageHandler = parentInterface->GetArea()->GetRouter()->GetMessageHandler();
00705     int ttl = (parentInterface->GetType() == AnsaOSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1;
00706     messageHandler->SendPacket(updatePacket, neighborIPAddress, parentInterface->GetIfIndex(), ttl);
00707 }
00708 
00709 void AnsaOSPF::Neighbor::DeleteLastSentDDPacket(void)
00710 {
00711     if (lastTransmittedDDPacket != NULL) {
00712         delete lastTransmittedDDPacket;
00713         lastTransmittedDDPacket = NULL;
00714     }
00715 }