OSPFInterface.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 "OSPFInterface.h"
00019 #include "OSPFInterfaceStateDown.h"
00020 #include "InterfaceTableAccess.h"
00021 #include "IPv4InterfaceData.h"
00022 #include "MessageHandler.h"
00023 #include "OSPFArea.h"
00024 #include "OSPFRouter.h"
00025 #include <vector>
00026 #include <memory.h>
00027 
00028 OSPF::Interface::Interface(OSPF::Interface::OSPFInterfaceType ifType) :
00029     interfaceType(ifType),
00030     ifIndex(0),
00031     mtu(0),
00032     interfaceAddressRange(OSPF::NullIPv4AddressRange),
00033     areaID(OSPF::BackboneAreaID),
00034     transitAreaID(OSPF::BackboneAreaID),
00035     helloInterval(10),
00036     pollInterval(120),
00037     routerDeadInterval(40),
00038     interfaceTransmissionDelay(1),
00039     routerPriority(0),
00040     designatedRouter(OSPF::NullDesignatedRouterID),
00041     backupDesignatedRouter(OSPF::NullDesignatedRouterID),
00042     interfaceOutputCost(1),
00043     retransmissionInterval(5),
00044     acknowledgementDelay(1),
00045     authenticationType(OSPF::NullType),
00046     parentArea(NULL)
00047 {
00048     state = new OSPF::InterfaceStateDown;
00049     previousState = NULL;
00050     helloTimer = new OSPFTimer;
00051     helloTimer->setTimerKind(InterfaceHelloTimer);
00052     helloTimer->setContextPointer(this);
00053     helloTimer->setName("OSPF::Interface::InterfaceHelloTimer");
00054     waitTimer = new OSPFTimer;
00055     waitTimer->setTimerKind(InterfaceWaitTimer);
00056     waitTimer->setContextPointer(this);
00057     waitTimer->setName("OSPF::Interface::InterfaceWaitTimer");
00058     acknowledgementTimer = new OSPFTimer;
00059     acknowledgementTimer->setTimerKind(InterfaceAcknowledgementTimer);
00060     acknowledgementTimer->setContextPointer(this);
00061     acknowledgementTimer->setName("OSPF::Interface::InterfaceAcknowledgementTimer");
00062     memset(authenticationKey.bytes, 0, 8 * sizeof(char));
00063 }
00064 
00065 OSPF::Interface::~Interface(void)
00066 {
00067     MessageHandler* messageHandler = parentArea->GetRouter()->GetMessageHandler();
00068     messageHandler->ClearTimer(helloTimer);
00069     delete helloTimer;
00070     messageHandler->ClearTimer(waitTimer);
00071     delete waitTimer;
00072     messageHandler->ClearTimer(acknowledgementTimer);
00073     delete acknowledgementTimer;
00074     if (previousState != NULL) {
00075         delete previousState;
00076     }
00077     delete state;
00078     long neighborCount = neighboringRouters.size();
00079     for (long i = 0; i < neighborCount; i++) {
00080         delete neighboringRouters[i];
00081     }
00082 }
00083 
00084 void OSPF::Interface::SetIfIndex(unsigned char index)
00085 {
00086     ifIndex = index;
00087     if (interfaceType == OSPF::Interface::UnknownType) {
00088         InterfaceEntry* routingInterface = InterfaceTableAccess().get()->getInterfaceById(ifIndex);
00089         interfaceAddressRange.address = IPv4AddressFromAddressString(routingInterface->ipv4Data()->getIPAddress().str().c_str());
00090         interfaceAddressRange.mask = IPv4AddressFromAddressString(routingInterface->ipv4Data()->getNetmask().str().c_str());
00091         mtu = routingInterface->getMTU();
00092     }
00093 }
00094 
00095 void OSPF::Interface::ChangeState(OSPF::InterfaceState* newState, OSPF::InterfaceState* currentState)
00096 {
00097     if (previousState != NULL) {
00098         delete previousState;
00099     }
00100     state = newState;
00101     previousState = currentState;
00102 }
00103 
00104 void OSPF::Interface::ProcessEvent(OSPF::Interface::InterfaceEventType event)
00105 {
00106     state->ProcessEvent(this, event);
00107 }
00108 
00109 void OSPF::Interface::Reset(void)
00110 {
00111     MessageHandler* messageHandler = parentArea->GetRouter()->GetMessageHandler();
00112     messageHandler->ClearTimer(helloTimer);
00113     messageHandler->ClearTimer(waitTimer);
00114     messageHandler->ClearTimer(acknowledgementTimer);
00115     designatedRouter = NullDesignatedRouterID;
00116     backupDesignatedRouter = NullDesignatedRouterID;
00117     long neighborCount = neighboringRouters.size();
00118     for (long i = 0; i < neighborCount; i++) {
00119         neighboringRouters[i]->ProcessEvent(OSPF::Neighbor::KillNeighbor);
00120     }
00121 }
00122 
00123 void OSPF::Interface::SendHelloPacket(OSPF::IPv4Address destination, short ttl)
00124 {
00125     OSPFOptions options;
00126     OSPFHelloPacket* helloPacket = new OSPFHelloPacket;
00127     std::vector<OSPF::IPv4Address> neighbors;
00128 
00129     helloPacket->setRouterID(parentArea->GetRouter()->GetRouterID());
00130     helloPacket->setAreaID(parentArea->GetAreaID());
00131     helloPacket->setAuthenticationType(authenticationType);
00132     for (int i = 0; i < 8; i++) {
00133         helloPacket->setAuthentication(i, authenticationKey.bytes[i]);
00134     }
00135 
00136     if (((interfaceType == PointToPoint) &&
00137          (interfaceAddressRange.address == OSPF::NullIPv4Address)) ||
00138         (interfaceType == Virtual))
00139     {
00140         helloPacket->setNetworkMask(ULongFromIPv4Address(OSPF::NullIPv4Address));
00141     } else {
00142         helloPacket->setNetworkMask(ULongFromIPv4Address(interfaceAddressRange.mask));
00143     }
00144     memset(&options, 0, sizeof(OSPFOptions));
00145     options.E_ExternalRoutingCapability = parentArea->GetExternalRoutingCapability();
00146     helloPacket->setOptions(options);
00147     helloPacket->setHelloInterval(helloInterval);
00148     helloPacket->setRouterPriority(routerPriority);
00149     helloPacket->setRouterDeadInterval(routerDeadInterval);
00150     helloPacket->setDesignatedRouter(ULongFromIPv4Address(designatedRouter.ipInterfaceAddress));
00151     helloPacket->setBackupDesignatedRouter(ULongFromIPv4Address(backupDesignatedRouter.ipInterfaceAddress));
00152     long neighborCount = neighboringRouters.size();
00153     for (long j = 0; j < neighborCount; j++) {
00154         if (neighboringRouters[j]->GetState() >= OSPF::Neighbor::InitState) {
00155             neighbors.push_back(neighboringRouters[j]->GetAddress());
00156         }
00157     }
00158     unsigned int initedNeighborCount = neighbors.size();
00159     helloPacket->setNeighborArraySize(initedNeighborCount);
00160     for (unsigned int k = 0; k < initedNeighborCount; k++) {
00161         helloPacket->setNeighbor(k, ULongFromIPv4Address(neighbors[k]));
00162     }
00163 
00164     helloPacket->setPacketLength(0); // TODO: Calculate correct length
00165     helloPacket->setChecksum(0); // TODO: Calculate correct cheksum(16-bit one's complement of the entire packet)
00166 
00167     parentArea->GetRouter()->GetMessageHandler()->SendPacket(helloPacket, destination, ifIndex, ttl);
00168 }
00169 
00170 void OSPF::Interface::SendLSAcknowledgement(OSPFLSAHeader* lsaHeader, IPv4Address destination)
00171 {
00172     OSPFOptions                         options;
00173     OSPFLinkStateAcknowledgementPacket* lsAckPacket = new OSPFLinkStateAcknowledgementPacket;
00174 
00175     lsAckPacket->setType(LinkStateAcknowledgementPacket);
00176     lsAckPacket->setRouterID(parentArea->GetRouter()->GetRouterID());
00177     lsAckPacket->setAreaID(parentArea->GetAreaID());
00178     lsAckPacket->setAuthenticationType(authenticationType);
00179     for (int i = 0; i < 8; i++) {
00180         lsAckPacket->setAuthentication(i, authenticationKey.bytes[i]);
00181     }
00182 
00183     lsAckPacket->setLsaHeadersArraySize(1);
00184     lsAckPacket->setLsaHeaders(0, *lsaHeader);
00185 
00186     lsAckPacket->setPacketLength(0); // TODO: Calculate correct length
00187     lsAckPacket->setChecksum(0); // TODO: Calculate correct cheksum(16-bit one's complement of the entire packet)
00188 
00189     int ttl = (interfaceType == OSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1;
00190     parentArea->GetRouter()->GetMessageHandler()->SendPacket(lsAckPacket, destination, ifIndex, ttl);
00191 }
00192 
00193 
00194 OSPF::Neighbor* OSPF::Interface::GetNeighborByID(OSPF::RouterID neighborID)
00195 {
00196     std::map<OSPF::RouterID, OSPF::Neighbor*>::iterator neighborIt = neighboringRoutersByID.find(neighborID);
00197     if (neighborIt != neighboringRoutersByID.end()) {
00198         return (neighborIt->second);
00199     }
00200     else {
00201         return NULL;
00202     }
00203 }
00204 
00205 OSPF::Neighbor* OSPF::Interface::GetNeighborByAddress(OSPF::IPv4Address address)
00206 {
00207     std::map<OSPF::IPv4Address, OSPF::Neighbor*, OSPF::IPv4Address_Less>::iterator neighborIt = neighboringRoutersByAddress.find(address);
00208     if (neighborIt != neighboringRoutersByAddress.end()) {
00209         return (neighborIt->second);
00210     }
00211     else {
00212         return NULL;
00213     }
00214 }
00215 
00216 void OSPF::Interface::AddNeighbor(OSPF::Neighbor* neighbor)
00217 {
00218     neighboringRoutersByID[neighbor->GetNeighborID()] = neighbor;
00219     neighboringRoutersByAddress[neighbor->GetAddress()] = neighbor;
00220     neighbor->SetInterface(this);
00221     neighboringRouters.push_back(neighbor);
00222 }
00223 
00224 OSPF::Interface::InterfaceStateType OSPF::Interface::GetState(void) const
00225 {
00226     return state->GetState();
00227 }
00228 
00229 const char* OSPF::Interface::GetStateString(OSPF::Interface::InterfaceStateType stateType)
00230 {
00231     switch (stateType) {
00232         case DownState:                 return "Down";
00233         case LoopbackState:             return "Loopback";
00234         case WaitingState:              return "Waiting";
00235         case PointToPointState:         return "PointToPoint";
00236         case NotDesignatedRouterState:  return "NotDesignatedRouter";
00237         case BackupState:               return "Backup";
00238         case DesignatedRouterState:     return "DesignatedRouter";
00239         default:                        ASSERT(false);
00240     }
00241     return "";
00242 }
00243 
00244 bool OSPF::Interface::HasAnyNeighborInStates(int states) const
00245 {
00246     long neighborCount = neighboringRouters.size();
00247     for (long i = 0; i < neighborCount; i++) {
00248         OSPF::Neighbor::NeighborStateType neighborState = neighboringRouters[i]->GetState();
00249         if (neighborState & states) {
00250             return true;
00251         }
00252     }
00253     return false;
00254 }
00255 
00256 void OSPF::Interface::RemoveFromAllRetransmissionLists(OSPF::LSAKeyType lsaKey)
00257 {
00258     long neighborCount = neighboringRouters.size();
00259     for (long i = 0; i < neighborCount; i++) {
00260         neighboringRouters[i]->RemoveFromRetransmissionList(lsaKey);
00261     }
00262 }
00263 
00264 bool OSPF::Interface::IsOnAnyRetransmissionList(OSPF::LSAKeyType lsaKey) const
00265 {
00266     long neighborCount = neighboringRouters.size();
00267     for (long i = 0; i < neighborCount; i++) {
00268         if (neighboringRouters[i]->IsLSAOnRetransmissionList(lsaKey)) {
00269             return true;
00270         }
00271     }
00272     return false;
00273 }
00274 
00278 bool OSPF::Interface::FloodLSA(OSPFLSA* lsa, OSPF::Interface* intf, OSPF::Neighbor* neighbor)
00279 {
00280     bool floodedBackOut = false;
00281 
00282     if (
00283         (
00284          (lsa->getHeader().getLsType() == ASExternalLSAType) &&
00285          (interfaceType != OSPF::Interface::Virtual) &&
00286          (parentArea->GetExternalRoutingCapability())
00287         ) ||
00288         (
00289          (lsa->getHeader().getLsType() != ASExternalLSAType) &&
00290          (
00291           (
00292            (areaID != OSPF::BackboneAreaID) &&
00293            (interfaceType != OSPF::Interface::Virtual)
00294           ) ||
00295           (areaID == OSPF::BackboneAreaID)
00296          )
00297         )
00298        )
00299     {
00300         long              neighborCount                = neighboringRouters.size();
00301         bool              lsaAddedToRetransmissionList = false;
00302         OSPF::LinkStateID linkStateID                  = lsa->getHeader().getLinkStateID();
00303         OSPF::LSAKeyType  lsaKey;
00304 
00305         lsaKey.linkStateID = linkStateID;
00306         lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();
00307 
00308         for (long i = 0; i < neighborCount; i++) {  // (1)
00309             if (neighboringRouters[i]->GetState() < OSPF::Neighbor::ExchangeState) {   // (1) (a)
00310                 continue;
00311             }
00312             if (neighboringRouters[i]->GetState() < OSPF::Neighbor::FullState) {   // (1) (b)
00313                 OSPFLSAHeader* requestLSAHeader = neighboringRouters[i]->FindOnRequestList(lsaKey);
00314                 if (requestLSAHeader != NULL) {
00315                     // operator< and operator== on OSPFLSAHeaders determines which one is newer(less means older)
00316                     if (lsa->getHeader() < (*requestLSAHeader)) {
00317                         continue;
00318                     }
00319                     if (operator== (lsa->getHeader(), (*requestLSAHeader))) {
00320                         neighboringRouters[i]->RemoveFromRequestList(lsaKey);
00321                         continue;
00322                     }
00323                     neighboringRouters[i]->RemoveFromRequestList(lsaKey);
00324                 }
00325             }
00326             if (neighbor == neighboringRouters[i]) {     // (1) (c)
00327                 continue;
00328             }
00329             neighboringRouters[i]->AddToRetransmissionList(lsa);   // (1) (d)
00330             lsaAddedToRetransmissionList = true;
00331         }
00332         if (lsaAddedToRetransmissionList) {     // (2)
00333             if ((intf != this) ||
00334                 ((neighbor != NULL) &&
00335                  (neighbor->GetNeighborID() != designatedRouter.routerID) &&
00336                  (neighbor->GetNeighborID() != backupDesignatedRouter.routerID)))  // (3)
00337             {
00338                 if ((intf != this) || (GetState() != OSPF::Interface::BackupState)) {  // (4)
00339                     OSPFLinkStateUpdatePacket* updatePacket = CreateUpdatePacket(lsa);    // (5)
00340 
00341                     if (updatePacket != NULL) {
00342                         int                   ttl            = (interfaceType == OSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1;
00343                         OSPF::MessageHandler* messageHandler = parentArea->GetRouter()->GetMessageHandler();
00344 
00345                         if (interfaceType == OSPF::Interface::Broadcast) {
00346                             if ((GetState() == OSPF::Interface::DesignatedRouterState) ||
00347                                 (GetState() == OSPF::Interface::BackupState) ||
00348                                 (designatedRouter == OSPF::NullDesignatedRouterID))
00349                             {
00350                                 messageHandler->SendPacket(updatePacket, OSPF::AllSPFRouters, ifIndex, ttl);
00351                                 for (long k = 0; k < neighborCount; k++) {
00352                                     neighboringRouters[k]->AddToTransmittedLSAList(lsaKey);
00353                                     if (!neighboringRouters[k]->IsUpdateRetransmissionTimerActive()) {
00354                                         neighboringRouters[k]->StartUpdateRetransmissionTimer();
00355                                     }
00356                                 }
00357                             } else {
00358                                 messageHandler->SendPacket(updatePacket, OSPF::AllDRouters, ifIndex, ttl);
00359                                 OSPF::Neighbor* dRouter = GetNeighborByID(designatedRouter.routerID);
00360                                 OSPF::Neighbor* backupDRouter = GetNeighborByID(backupDesignatedRouter.routerID);
00361                                 if (dRouter != NULL) {
00362                                     dRouter->AddToTransmittedLSAList(lsaKey);
00363                                     if (!dRouter->IsUpdateRetransmissionTimerActive()) {
00364                                         dRouter->StartUpdateRetransmissionTimer();
00365                                     }
00366                                 }
00367                                 if (backupDRouter != NULL) {
00368                                     backupDRouter->AddToTransmittedLSAList(lsaKey);
00369                                     if (!backupDRouter->IsUpdateRetransmissionTimerActive()) {
00370                                         backupDRouter->StartUpdateRetransmissionTimer();
00371                                     }
00372                                 }
00373                             }
00374                         } else {
00375                             if (interfaceType == OSPF::Interface::PointToPoint) {
00376                                 messageHandler->SendPacket(updatePacket, OSPF::AllSPFRouters, ifIndex, ttl);
00377                                 if (neighborCount > 0) {
00378                                     neighboringRouters[0]->AddToTransmittedLSAList(lsaKey);
00379                                     if (!neighboringRouters[0]->IsUpdateRetransmissionTimerActive()) {
00380                                         neighboringRouters[0]->StartUpdateRetransmissionTimer();
00381                                     }
00382                                 }
00383                             } else {
00384                                 for (long m = 0; m < neighborCount; m++) {
00385                                     if (neighboringRouters[m]->GetState() >= OSPF::Neighbor::ExchangeState) {
00386                                         messageHandler->SendPacket(updatePacket, neighboringRouters[m]->GetAddress(), ifIndex, ttl);
00387                                         neighboringRouters[m]->AddToTransmittedLSAList(lsaKey);
00388                                         if (!neighboringRouters[m]->IsUpdateRetransmissionTimerActive()) {
00389                                             neighboringRouters[m]->StartUpdateRetransmissionTimer();
00390                                         }
00391                                     }
00392                                 }
00393                             }
00394                         }
00395 
00396                         if (intf == this) {
00397                             floodedBackOut = true;
00398                         }
00399                     }
00400                 }
00401             }
00402         }
00403     }
00404 
00405     return floodedBackOut;
00406 }
00407 
00408 OSPFLinkStateUpdatePacket* OSPF::Interface::CreateUpdatePacket(OSPFLSA* lsa)
00409 {
00410     LSAType lsaType                  = static_cast<LSAType> (lsa->getHeader().getLsType());
00411     OSPFRouterLSA* routerLSA         = (lsaType == RouterLSAType) ? dynamic_cast<OSPFRouterLSA*> (lsa) : NULL;
00412     OSPFNetworkLSA* networkLSA       = (lsaType == NetworkLSAType) ? dynamic_cast<OSPFNetworkLSA*> (lsa) : NULL;
00413     OSPFSummaryLSA* summaryLSA       = ((lsaType == SummaryLSA_NetworksType) ||
00414                                         (lsaType == SummaryLSA_ASBoundaryRoutersType)) ? dynamic_cast<OSPFSummaryLSA*> (lsa) : NULL;
00415     OSPFASExternalLSA* asExternalLSA = (lsaType == ASExternalLSAType) ? dynamic_cast<OSPFASExternalLSA*> (lsa) : NULL;
00416 
00417     if (((lsaType == RouterLSAType) && (routerLSA != NULL)) ||
00418         ((lsaType == NetworkLSAType) && (networkLSA != NULL)) ||
00419         (((lsaType == SummaryLSA_NetworksType) || (lsaType == SummaryLSA_ASBoundaryRoutersType)) && (summaryLSA != NULL)) ||
00420         ((lsaType == ASExternalLSAType) && (asExternalLSA != NULL)))
00421     {
00422         OSPFLinkStateUpdatePacket* updatePacket = new OSPFLinkStateUpdatePacket;
00423 
00424         updatePacket->setType(LinkStateUpdatePacket);
00425         updatePacket->setRouterID(parentArea->GetRouter()->GetRouterID());
00426         updatePacket->setAreaID(areaID);
00427         updatePacket->setAuthenticationType(authenticationType);
00428         for (int j = 0; j < 8; j++) {
00429             updatePacket->setAuthentication(j, authenticationKey.bytes[j]);
00430         }
00431 
00432         updatePacket->setNumberOfLSAs(1);
00433 
00434         switch (lsaType) {
00435             case RouterLSAType:
00436                 {
00437                     updatePacket->setRouterLSAsArraySize(1);
00438                     updatePacket->setRouterLSAs(0, *routerLSA);
00439                     unsigned short lsAge = updatePacket->getRouterLSAs(0).getHeader().getLsAge();
00440                     if (lsAge < MAX_AGE - interfaceTransmissionDelay) {
00441                         updatePacket->getRouterLSAs(0).getHeader().setLsAge(lsAge + interfaceTransmissionDelay);
00442                     } else {
00443                         updatePacket->getRouterLSAs(0).getHeader().setLsAge(MAX_AGE);
00444                     }
00445                 }
00446                 break;
00447             case NetworkLSAType:
00448                 {
00449                     updatePacket->setNetworkLSAsArraySize(1);
00450                     updatePacket->setNetworkLSAs(0, *networkLSA);
00451                     unsigned short lsAge = updatePacket->getNetworkLSAs(0).getHeader().getLsAge();
00452                     if (lsAge < MAX_AGE - interfaceTransmissionDelay) {
00453                         updatePacket->getNetworkLSAs(0).getHeader().setLsAge(lsAge + interfaceTransmissionDelay);
00454                     } else {
00455                         updatePacket->getNetworkLSAs(0).getHeader().setLsAge(MAX_AGE);
00456                     }
00457                 }
00458                 break;
00459             case SummaryLSA_NetworksType:
00460             case SummaryLSA_ASBoundaryRoutersType:
00461                 {
00462                     updatePacket->setSummaryLSAsArraySize(1);
00463                     updatePacket->setSummaryLSAs(0, *summaryLSA);
00464                     unsigned short lsAge = updatePacket->getSummaryLSAs(0).getHeader().getLsAge();
00465                     if (lsAge < MAX_AGE - interfaceTransmissionDelay) {
00466                         updatePacket->getSummaryLSAs(0).getHeader().setLsAge(lsAge + interfaceTransmissionDelay);
00467                     } else {
00468                         updatePacket->getSummaryLSAs(0).getHeader().setLsAge(MAX_AGE);
00469                     }
00470                 }
00471                 break;
00472             case ASExternalLSAType:
00473                 {
00474                     updatePacket->setAsExternalLSAsArraySize(1);
00475                     updatePacket->setAsExternalLSAs(0, *asExternalLSA);
00476                     unsigned short lsAge = updatePacket->getAsExternalLSAs(0).getHeader().getLsAge();
00477                     if (lsAge < MAX_AGE - interfaceTransmissionDelay) {
00478                         updatePacket->getAsExternalLSAs(0).getHeader().setLsAge(lsAge + interfaceTransmissionDelay);
00479                     } else {
00480                         updatePacket->getAsExternalLSAs(0).getHeader().setLsAge(MAX_AGE);
00481                     }
00482                 }
00483                 break;
00484             default: break;
00485         }
00486 
00487         updatePacket->setPacketLength(0); // TODO: Calculate correct length
00488         updatePacket->setChecksum(0); // TODO: Calculate correct cheksum(16-bit one's complement of the entire packet)
00489 
00490         return updatePacket;
00491     }
00492     return NULL;
00493 }
00494 
00495 void OSPF::Interface::AddDelayedAcknowledgement(OSPFLSAHeader& lsaHeader)
00496 {
00497     if (interfaceType == OSPF::Interface::Broadcast) {
00498         if ((GetState() == OSPF::Interface::DesignatedRouterState) ||
00499             (GetState() == OSPF::Interface::BackupState) ||
00500             (designatedRouter == OSPF::NullDesignatedRouterID))
00501         {
00502             delayedAcknowledgements[OSPF::AllSPFRouters].push_back(lsaHeader);
00503         } else {
00504             delayedAcknowledgements[OSPF::AllDRouters].push_back(lsaHeader);
00505         }
00506     } else {
00507         long neighborCount = neighboringRouters.size();
00508         for (long i = 0; i < neighborCount; i++) {
00509             if (neighboringRouters[i]->GetState() >= OSPF::Neighbor::ExchangeState) {
00510                 delayedAcknowledgements[neighboringRouters[i]->GetAddress()].push_back(lsaHeader);
00511             }
00512         }
00513     }
00514 }
00515 
00516 void OSPF::Interface::SendDelayedAcknowledgements(void)
00517 {
00518     OSPF::MessageHandler* messageHandler = parentArea->GetRouter()->GetMessageHandler();
00519     long                  maxPacketSize  = ((IPV4_HEADER_LENGTH + OSPF_HEADER_LENGTH + OSPF_LSA_HEADER_LENGTH) > mtu) ? IPV4_DATAGRAM_LENGTH : mtu;
00520 
00521     for (std::map<IPv4Address, std::list<OSPFLSAHeader>, OSPF::IPv4Address_Less>::iterator delayIt = delayedAcknowledgements.begin();
00522          delayIt != delayedAcknowledgements.end();
00523          delayIt++)
00524     {
00525         int ackCount = delayIt->second.size();
00526         if (ackCount > 0) {
00527             while (!(delayIt->second.empty())) {
00528                 OSPFLinkStateAcknowledgementPacket* ackPacket  = new OSPFLinkStateAcknowledgementPacket;
00529                 long                                packetSize = IPV4_HEADER_LENGTH + OSPF_HEADER_LENGTH;
00530 
00531                 ackPacket->setType(LinkStateAcknowledgementPacket);
00532                 ackPacket->setRouterID(parentArea->GetRouter()->GetRouterID());
00533                 ackPacket->setAreaID(areaID);
00534                 ackPacket->setAuthenticationType(authenticationType);
00535                 for (int i = 0; i < 8; i++) {
00536                     ackPacket->setAuthentication(i, authenticationKey.bytes[i]);
00537                 }
00538 
00539                 while ((!(delayIt->second.empty())) && (packetSize <= (maxPacketSize - OSPF_LSA_HEADER_LENGTH))) {
00540                     unsigned long   headerCount = ackPacket->getLsaHeadersArraySize();
00541                     ackPacket->setLsaHeadersArraySize(headerCount + 1);
00542                     ackPacket->setLsaHeaders(headerCount, *(delayIt->second.begin()));
00543                     delayIt->second.pop_front();
00544                     packetSize += OSPF_LSA_HEADER_LENGTH;
00545                 }
00546 
00547                 ackPacket->setPacketLength(0); // TODO: Calculate correct length
00548                 ackPacket->setChecksum(0); // TODO: Calculate correct cheksum(16-bit one's complement of the entire packet)
00549 
00550                 int ttl = (interfaceType == OSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1;
00551 
00552                 if (interfaceType == OSPF::Interface::Broadcast) {
00553                     if ((GetState() == OSPF::Interface::DesignatedRouterState) ||
00554                         (GetState() == OSPF::Interface::BackupState) ||
00555                         (designatedRouter == OSPF::NullDesignatedRouterID))
00556                     {
00557                         messageHandler->SendPacket(ackPacket, OSPF::AllSPFRouters, ifIndex, ttl);
00558                     } else {
00559                         messageHandler->SendPacket(ackPacket, OSPF::AllDRouters, ifIndex, ttl);
00560                     }
00561                 } else {
00562                     if (interfaceType == OSPF::Interface::PointToPoint) {
00563                         messageHandler->SendPacket(ackPacket, OSPF::AllSPFRouters, ifIndex, ttl);
00564                     } else {
00565                         messageHandler->SendPacket(ackPacket, delayIt->first, ifIndex, ttl);
00566                     }
00567                 }
00568             }
00569         }
00570     }
00571     messageHandler->StartTimer(acknowledgementTimer, acknowledgementDelay);
00572 }
00573 
00574 void OSPF::Interface::AgeTransmittedLSALists(void)
00575 {
00576     long neighborCount = neighboringRouters.size();
00577     for (long i = 0; i < neighborCount; i++) {
00578         neighboringRouters[i]->AgeTransmittedLSAList();
00579     }
00580 }