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