OSPFNeighbor.cc

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