INET Framework for OMNeT++/OMNEST
ansaOspfInterface6.cc
Go to the documentation of this file.
00001 //
00002 // This program is free software: you can redistribute it and/or modify
00003 // it under the terms of the GNU Lesser General Public License as published by
00004 // the Free Software Foundation, either version 3 of the License, or
00005 // (at your option) any later version.
00006 // 
00007 // This program is distributed in the hope that it will be useful,
00008 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00009 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010 // GNU Lesser General Public License for more details.
00011 // 
00012 // You should have received a copy of the GNU Lesser General Public License
00013 // along with this program.  If not, see http://www.gnu.org/licenses/.
00014 // 
00015 
00016 #include "ansaMessageHandler6.h"
00017 #include "ansaOspfArea6.h"
00018 #include "ansaOspfInterface6.h"
00019 #include "ansaOspfInterfaceStateDown6.h"
00020 #include "ansaOspfRouter6.h"
00021 
00022 #include "InterfaceTableAccess.h"
00023 #include "IPv6InterfaceData.h"
00024 
00025 AnsaOspf6::Interface::Interface(AnsaOspf6::Interface::OspfInterfaceType ifType) :
00026       interfaceType(ifType),
00027       ifIndex(0),
00028       instanceID(0),
00029       mtu(0),
00030       areaID(AnsaOspf6::BackboneAreaID),
00031       transitAreaID(AnsaOspf6::BackboneAreaID),
00032       helloInterval(10),
00033       pollInterval(120),
00034       routerDeadInterval(40),
00035       interfaceTransmissionDelay(1),
00036       routerPriority(1),
00037       designatedRouter(AnsaOspf6::NullDesignatedRouterID),
00038       backupDesignatedRouter(AnsaOspf6::NullDesignatedRouterID),
00039       interfaceOutputCost(10),
00040       retransmissionInterval(5),
00041       acknowledgementDelay(1),
00042       parentArea(NULL),
00043       isGoingDown(false){
00044 
00045    state = new AnsaOspf6::InterfaceStateDown;
00046    previousState = NULL;
00047    helloTimer = new OspfTimer6;
00048    helloTimer->setTimerKind(InterfaceHelloTimer);
00049    helloTimer->setContextPointer(this);
00050    helloTimer->setName("AnsaOspf6::Interface::InterfaceHelloTimer");
00051    waitTimer = new OspfTimer6;
00052    waitTimer->setTimerKind(InterfaceWaitTimer);
00053    waitTimer->setContextPointer(this);
00054    waitTimer->setName("AnsaOspf6::Interface::InterfaceWaitTimer");
00055    /*
00056    acknowledgementTimer = new OspfTimer6;
00057    acknowledgementTimer->setTimerKind(InterfaceAcknowledgementTimer);
00058    acknowledgementTimer->setContextPointer(this);
00059    acknowledgementTimer->setName("AnsaOspf6::Interface::InterfaceAcknowledgementTimer");
00060    */
00061 }
00062 
00063 
00064 AnsaOspf6::Interface::~Interface(void){
00065    MessageHandler* messageHandler = parentArea->GetRouter()->GetMessageHandler();
00066 
00067    if (helloTimer != NULL){
00068       messageHandler->ClearTimer(helloTimer);
00069       delete helloTimer;
00070    }
00071 
00072    if (waitTimer != NULL){
00073       messageHandler->ClearTimer(waitTimer);
00074       delete waitTimer;
00075    }
00076    /* TODO
00077    messageHandler->ClearTimer(acknowledgementTimer);
00078    delete acknowledgementTimer;
00079    */
00080    if (previousState != NULL){
00081       delete previousState;
00082    }
00083    delete state;
00084 
00085    long neighborCount = neighboringRouters.size();
00086    for (long i = 0; i < neighborCount; i++){
00087       delete neighboringRouters[i];
00088    }
00089 }
00090 
00091 
00092 void AnsaOspf6::Interface::SetIfIndex(IfaceID id){
00093    ifIndex = id;
00094    if (interfaceType == AnsaOspf6::Interface::UnknownType) {
00095       InterfaceEntry* routingInterface = InterfaceTableAccess().get()->getInterfaceById(ifIndex);
00096       interfaceAddress = routingInterface->ipv6Data()->getLinkLocalAddress();
00097       mtu = routingInterface->getMTU();
00098    }
00099 }
00100 
00101 
00102 void AnsaOspf6::Interface::ChangeState(AnsaOspf6::InterfaceState* newState, AnsaOspf6::InterfaceState* currentState){
00103    if (previousState != NULL) {
00104       delete previousState;
00105    }
00106    state = newState;
00107    previousState = currentState;
00108 }
00109 
00110 
00111 void AnsaOspf6::Interface::ProcessEvent(AnsaOspf6::Interface::InterfaceEventType event){
00112    state->ProcessEvent(this, event);
00113 }
00114 
00115 
00116 void AnsaOspf6::Interface::Reset(void){
00117    MessageHandler* messageHandler = parentArea->GetRouter()->GetMessageHandler();
00118 
00119    messageHandler->ClearTimer(helloTimer);
00120    messageHandler->ClearTimer(waitTimer);
00121    messageHandler->ClearTimer(acknowledgementTimer);
00122 
00123    designatedRouter = NullDesignatedRouterID;
00124    backupDesignatedRouter = NullDesignatedRouterID;
00125    long neighborCount = neighboringRouters.size();
00126    for (long i = 0; i < neighborCount; i++) {
00127       neighboringRouters[i]->ProcessEvent(AnsaOspf6::Neighbor::KillNeighbor);
00128    }
00129 }
00130 
00131 // http://tools.ietf.org/html/rfc5340#section-4.2.1.1
00132 void AnsaOspf6::Interface::SendHelloPacket(IPv6Address destination, short ttl){
00133 
00134    OspfOptions6 options;
00135    OspfHelloPacket6* helloPacket = new OspfHelloPacket6;
00136    std::vector<RouterID> neighbors;
00137 
00138    helloPacket->setType(HelloPacket);
00139    helloPacket->setRouterID(parentArea->GetRouter()->GetRouterID());
00140    helloPacket->setAreaID(parentArea->GetAreaID());
00141 
00142    helloPacket->setInterfaceID(ifIndex);
00143    helloPacket->setInstanceID(instanceID);
00144    helloPacket->setRtrPriority(routerPriority);
00145 
00146    memset(&options, 0, sizeof(OspfOptions6));
00147    options.E_ExternalRoutingCapability = parentArea->GetExternalRoutingCapability();
00148    helloPacket->setOptions(options);
00149 
00150    helloPacket->setHelloInterval(helloInterval);
00151    helloPacket->setRouterDeadInterval(routerDeadInterval);
00152    helloPacket->setDesignatedRouterID(designatedRouter);
00153    helloPacket->setBackupDesignatedRouterID(backupDesignatedRouter);
00154 
00155    long neighborCount = neighboringRouters.size();
00156    for (long j = 0; j < neighborCount; j++) {
00157       if (neighboringRouters[j]->GetState() >= AnsaOspf6::Neighbor::InitState) {
00158          neighbors.push_back(neighboringRouters[j]->GetNeighborID());
00159       }
00160    }
00161 
00162    unsigned int initedNeighborCount = neighbors.size();
00163    helloPacket->setNeighborIDArraySize(initedNeighborCount);
00164    for (unsigned int k = 0; k < initedNeighborCount; k++){
00165       helloPacket->setNeighborID(k, neighbors[k]);
00166    }
00167 
00168    parentArea->GetRouter()->GetMessageHandler()->SendPacket(helloPacket, destination, ifIndex, ttl);
00169 }
00170 
00171 void AnsaOspf6::Interface::SendLSAcknowledgement(OspfLsaHeader6* lsaHeader, IPv6Address destination) {
00172    OspfOptions6 options;
00173    OspfLinkStateAcknowledgementPacket6* lsAckPacket = new OspfLinkStateAcknowledgementPacket6;
00174 
00175    lsAckPacket->setType(LinkStateAcknowledgementPacket);
00176    lsAckPacket->setRouterID(parentArea->GetRouter()->GetRouterID());
00177    lsAckPacket->setAreaID(parentArea->GetAreaID());
00178    lsAckPacket->setInstanceID(instanceID);
00179 
00180    lsAckPacket->setLsaHeadersArraySize(1);
00181    lsAckPacket->setLsaHeaders(0, *lsaHeader);
00182 
00183    int ttl = (interfaceType == AnsaOspf6::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1;
00184    parentArea->GetRouter()->GetMessageHandler()->SendPacket(lsAckPacket, destination, ifIndex, ttl);
00185 }
00186 
00187 AnsaOspf6::Neighbor* AnsaOspf6::Interface::GetNeighborByID(AnsaOspf6::RouterID neighborID) {
00188    std::map<AnsaOspf6::RouterID, AnsaOspf6::Neighbor*>::iterator neighborIt =
00189          neighboringRoutersByID.find(neighborID);
00190    if (neighborIt != neighboringRoutersByID.end()){
00191       return (neighborIt->second);
00192    }else{
00193       return NULL;
00194    }
00195 }
00196 
00197 AnsaOspf6::Neighbor* AnsaOspf6::Interface::GetNeighborByAddress(IPv6Address address) {
00198    std::map<IPv6Address, AnsaOspf6::Neighbor*, AnsaOspf6::IPv6Address_Less>::iterator neighborIt = neighboringRoutersByAddress.find(address);
00199    if (neighborIt != neighboringRoutersByAddress.end()){
00200       return (neighborIt->second);
00201    }else{
00202       return NULL;
00203    }
00204 }
00205 
00206 void AnsaOspf6::Interface::AddNeighbor(AnsaOspf6::Neighbor* neighbor) {
00207    neighboringRoutersByID[neighbor->GetNeighborID()] = neighbor;
00208    neighboringRoutersByAddress[neighbor->GetAddress()] = neighbor;
00209    neighbor->SetInterface(this);
00210    neighboringRouters.push_back(neighbor);
00211 }
00212 
00213 AnsaOspf6::Interface::InterfaceStateType AnsaOspf6::Interface::GetState(void) const {
00214    return state->GetState();
00215 }
00216 
00217 const char* AnsaOspf6::Interface::GetStateString(AnsaOspf6::Interface::InterfaceStateType stateType) {
00218    switch (stateType){
00219       case DownState:
00220          return "Down";
00221       case LoopbackState:
00222          return "Loopback";
00223       case WaitingState:
00224          return "Waiting";
00225       case PointToPointState:
00226          return "PointToPoint";
00227       case NotDesignatedRouterState:
00228          return "NotDesignatedRouter";
00229       case BackupState:
00230          return "Backup";
00231       case DesignatedRouterState:
00232          return "DesignatedRouter";
00233       default:
00234          ASSERT(false);
00235    }
00236    return "";
00237 }
00238 
00239 const char* AnsaOspf6::Interface::GetTypeString (OspfInterfaceType type){
00240    switch (type){
00241       case UnknownType:
00242          return "Unknown";
00243       case PointToPoint:
00244          return "Point-to-Point";
00245       case Broadcast:
00246          return "Broadcast";
00247       case NBMA:
00248          return "NBMA";
00249       case PointToMultiPoint:
00250          return "Point-to-Multipoint";
00251       case Virtual:
00252          return "Virtual";
00253       default:
00254          ASSERT(false);
00255    }
00256    return "";
00257 }
00258 
00259 bool AnsaOspf6::Interface::HasAnyNeighborInStates(int states) const {
00260    long neighborCount = neighboringRouters.size();
00261    for (long i = 0; i < neighborCount; i++){
00262       AnsaOspf6::Neighbor::NeighborStateType neighborState = neighboringRouters[i]->GetState();
00263       if (neighborState & states){
00264          return true;
00265       }
00266    }
00267    return false;
00268 }
00269 
00270 void AnsaOspf6::Interface::RemoveFromAllRetransmissionLists(AnsaOspf6::LsaKeyType6 lsaKey) {
00271    long neighborCount = neighboringRouters.size();
00272    for (long i = 0; i < neighborCount; i++){
00273       neighboringRouters[i]->RemoveFromRetransmissionList(lsaKey);
00274    }
00275 }
00276 
00277 bool AnsaOspf6::Interface::IsOnAnyRetransmissionList(AnsaOspf6::LsaKeyType6 lsaKey) const {
00278    long neighborCount = neighboringRouters.size();
00279    for (long i = 0; i < neighborCount; i++){
00280       if (neighboringRouters[i]->IsLSAOnRetransmissionList(lsaKey)){
00281          return true;
00282       }
00283    }
00284    return false;
00285 }
00286 
00287 bool AnsaOspf6::Interface::FloodLSA(OspfLsa6* lsa, AnsaOspf6::Interface* intf, AnsaOspf6::Neighbor* neighbor){
00288    bool floodedBackOut = false;
00289 
00290    if (  (  (lsa->getHeader().getLsType() == AsExternalLsaType)
00291          && (interfaceType != AnsaOspf6::Interface::Virtual)
00292          && (parentArea->GetExternalRoutingCapability()))
00293       || (  (lsa->getHeader().getLsType() != AsExternalLsaType)
00294          && (  (  (areaID != AnsaOspf6::BackboneAreaID)
00295                && (interfaceType != AnsaOspf6::Interface::Virtual))
00296          || (areaID == AnsaOspf6::BackboneAreaID)))){
00297 
00298       long neighborCount = neighboringRouters.size();
00299       bool lsaAddedToRetransmissionList = false;
00300       AnsaOspf6::LinkStateID linkStateID = lsa->getHeader().getLinkStateID();
00301       AnsaOspf6::LsaKeyType6 lsaKey;
00302 
00303       lsaKey.linkStateID = linkStateID;
00304       lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter();
00305 
00306       for (long i = 0; i < neighborCount; i++){ // (1)
00307 
00308          if (neighboringRouters[i]->GetState() < AnsaOspf6::Neighbor::ExchangeState){ // (1) (a)
00309             continue;
00310          }
00311 
00312          if (neighboringRouters[i]->GetState() < AnsaOspf6::Neighbor::FullState){ // (1) (b)
00313             OspfLsaHeader6* 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 
00327          if (neighbor == neighboringRouters[i]){ // (1) (c)
00328             continue;
00329          }
00330 
00331          neighboringRouters[i]->AddToRetransmissionList(lsa); // (1) (d)
00332          lsaAddedToRetransmissionList = true;
00333       }
00334 
00335 
00336       if (lsaAddedToRetransmissionList){ // (2)
00337          if (  (intf != this)
00338             || (  (neighbor != NULL)
00339                && (neighbor->GetNeighborID() != designatedRouter)
00340                && (neighbor->GetNeighborID() != backupDesignatedRouter))){ // (3)
00341 
00342             if ((intf != this) || (GetState() != AnsaOspf6::Interface::BackupState)){ // (4)
00343                OspfLinkStateUpdatePacket6* updatePacket = CreateUpdatePacket(lsa); // (5)
00344 
00345                if (updatePacket != NULL){
00346                   int ttl = (interfaceType == AnsaOspf6::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1;
00347                   AnsaOspf6::MessageHandler* messageHandler = parentArea->GetRouter()->GetMessageHandler();
00348 
00349                   if (interfaceType == AnsaOspf6::Interface::Broadcast){
00350                      if (  (GetState() == AnsaOspf6::Interface::DesignatedRouterState)
00351                         || (GetState() == AnsaOspf6::Interface::BackupState)
00352                         || (designatedRouter == AnsaOspf6::NullDesignatedRouterID)){
00353                         messageHandler->SendPacket(updatePacket, AnsaOspf6::AllSPFRouters, ifIndex, ttl);
00354                         for (long k = 0; k < neighborCount; k++){
00355                            neighboringRouters[k]->AddToTransmittedLSAList(lsaKey);
00356                            if (!neighboringRouters[k]->IsUpdateRetransmissionTimerActive()){
00357                               neighboringRouters[k]->StartUpdateRetransmissionTimer();
00358                            }
00359                         }
00360                      }else{
00361                         messageHandler->SendPacket(updatePacket, AnsaOspf6::AllDRouters, ifIndex, ttl);
00362                         AnsaOspf6::Neighbor* dRouter = GetNeighborByID(designatedRouter);
00363                         AnsaOspf6::Neighbor* backupDRouter = GetNeighborByID(backupDesignatedRouter);
00364                         if (dRouter != NULL){
00365                            dRouter->AddToTransmittedLSAList(lsaKey);
00366                            if (!dRouter->IsUpdateRetransmissionTimerActive()){
00367                               dRouter->StartUpdateRetransmissionTimer();
00368                            }
00369                         }
00370                         if (backupDRouter != NULL){
00371                            backupDRouter->AddToTransmittedLSAList(lsaKey);
00372                            if (!backupDRouter->IsUpdateRetransmissionTimerActive()){
00373                               backupDRouter->StartUpdateRetransmissionTimer();
00374                            }
00375                         }
00376                      }
00377 
00378                   }else{
00379                      if (interfaceType == AnsaOspf6::Interface::PointToPoint){
00380                         messageHandler->SendPacket(updatePacket, AnsaOspf6::AllSPFRouters, ifIndex, ttl);
00381                         if (neighborCount > 0){
00382                            neighboringRouters[0]->AddToTransmittedLSAList(lsaKey);
00383                            if (!neighboringRouters[0]->IsUpdateRetransmissionTimerActive()){
00384                               neighboringRouters[0]->StartUpdateRetransmissionTimer();
00385                            }
00386                         }
00387                      }else{
00388                         for (long m = 0; m < neighborCount; m++){
00389                            if (neighboringRouters[m]->GetState() >= AnsaOspf6::Neighbor::ExchangeState){
00390                               messageHandler->SendPacket(updatePacket, neighboringRouters[m]->GetAddress(), ifIndex, ttl);
00391                               neighboringRouters[m]->AddToTransmittedLSAList(lsaKey);
00392                               if (!neighboringRouters[m]->IsUpdateRetransmissionTimerActive()){
00393                                  neighboringRouters[m]->StartUpdateRetransmissionTimer();
00394                               }
00395                            }
00396                         }
00397                      }
00398                   }
00399 
00400                   if (intf == this){
00401                      floodedBackOut = true;
00402                   }
00403                }
00404             }
00405          }
00406       }
00407    }
00408 
00409    return floodedBackOut;
00410 }
00411 
00412 OspfLinkStateUpdatePacket6* AnsaOspf6::Interface::CreateUpdatePacket(OspfLsa6* lsa){
00413    LsaType6 lsaType = static_cast<LsaType6> (lsa->getHeader().getLsType());
00414    OspfRouterLsa6* routerLSA = (lsaType == RouterLsaType) ? dynamic_cast<OspfRouterLsa6*> (lsa) : NULL;
00415    OspfNetworkLsa6* networkLSA = (lsaType == NetworkLsaType) ? dynamic_cast<OspfNetworkLsa6*> (lsa) : NULL;
00416    OspfInterAreaPrefixLsa6* interAreaPrefixLSA = (lsaType = InterAreaPrefixLsaType) ? dynamic_cast<OspfInterAreaPrefixLsa6*> (lsa) : NULL;
00417    OspfInterAreaRouterLsa6* interAreaRouterLSA = (lsaType = InterAreaRouterLsaType) ? dynamic_cast<OspfInterAreaRouterLsa6*> (lsa) : NULL;
00418    OspfAsExternalLsa6* asExternalLSA = (lsaType == AsExternalLsaType) ? dynamic_cast<OspfAsExternalLsa6*> (lsa) : NULL;
00419    OspfLinkLsa6* linkLSA = (lsaType == LinkLsaType) ?  dynamic_cast<OspfLinkLsa6*> (lsa) : NULL;
00420    OspfIntraAreaPrefixLsa6* intraAreaPrefixLSA = (lsaType = IntraAreaPrefixLsaType) ?  dynamic_cast<OspfIntraAreaPrefixLsa6*> (lsa) : NULL;
00421 
00422    if (  ((lsaType == RouterLsaType) && (routerLSA != NULL))
00423       || ((lsaType == NetworkLsaType) && (networkLSA != NULL))
00424       || ((lsaType == InterAreaPrefixLsaType) && (interAreaPrefixLSA != NULL))
00425       || ((lsaType == InterAreaRouterLsaType) && (interAreaRouterLSA != NULL))
00426       || ((lsaType == AsExternalLsaType) && (asExternalLSA != NULL))
00427       || ((lsaType == LinkLsaType) && (linkLSA != NULL))
00428       || ((lsaType == IntraAreaPrefixLsaType) && (intraAreaPrefixLSA != NULL))){
00429 
00430       OspfLinkStateUpdatePacket6* updatePacket = new OspfLinkStateUpdatePacket6;
00431 
00432       updatePacket->setType(LinkStateUpdatePacket);
00433       updatePacket->setRouterID(parentArea->GetRouter()->GetRouterID());
00434       updatePacket->setAreaID(areaID);
00435       updatePacket->setNumberOfLsas(1);
00436 
00437       switch (lsaType){
00438          case RouterLsaType: {
00439             updatePacket->setRouterLsasArraySize(1);
00440             updatePacket->setRouterLsas(0, *routerLSA);
00441             unsigned short lsAge = updatePacket->getRouterLsas(0).getHeader().getLsAge();
00442             if (lsAge < MAX_AGE - interfaceTransmissionDelay){
00443                updatePacket->getRouterLsas(0).getHeader().setLsAge(lsAge + interfaceTransmissionDelay);
00444             }else{
00445                updatePacket->getRouterLsas(0).getHeader().setLsAge(MAX_AGE);
00446             }}
00447             break;
00448          case NetworkLsaType: {
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             break;
00458          case InterAreaPrefixLsaType: {
00459             updatePacket->setInterAreaPrefixLsasArraySize(1);
00460             updatePacket->setInterAreaPrefixLsas(0, *interAreaPrefixLSA);
00461             unsigned short lsAge = updatePacket->getInterAreaPrefixLsas(0).getHeader().getLsAge();
00462             if (lsAge < MAX_AGE - interfaceTransmissionDelay){
00463                updatePacket->getInterAreaPrefixLsas(0).getHeader().setLsAge(lsAge + interfaceTransmissionDelay);
00464             }else{
00465                updatePacket->getInterAreaPrefixLsas(0).getHeader().setLsAge(MAX_AGE);
00466             }}
00467             break;
00468          case InterAreaRouterLsaType: {
00469             updatePacket->setInterAreaRouterLsasArraySize(1);
00470             updatePacket->setInterAreaRouterLsas(0, *interAreaRouterLSA);
00471             unsigned short lsAge = updatePacket->getInterAreaRouterLsas(0).getHeader().getLsAge();
00472             if (lsAge < MAX_AGE - interfaceTransmissionDelay){
00473                updatePacket->getInterAreaRouterLsas(0).getHeader().setLsAge(lsAge + interfaceTransmissionDelay);
00474             }else{
00475                updatePacket->getInterAreaRouterLsas(0).getHeader().setLsAge(MAX_AGE);
00476             }}
00477             break;
00478          case AsExternalLsaType: {
00479             updatePacket->setAsExternalLsasArraySize(1);
00480             updatePacket->setAsExternalLsas(0, *asExternalLSA);
00481             unsigned short lsAge = updatePacket->getAsExternalLsas(0).getHeader().getLsAge();
00482             if (lsAge < MAX_AGE - interfaceTransmissionDelay){
00483                updatePacket->getAsExternalLsas(0).getHeader().setLsAge(lsAge + interfaceTransmissionDelay);
00484             }else{
00485                updatePacket->getAsExternalLsas(0).getHeader().setLsAge(MAX_AGE);
00486             }}
00487             break;
00488          case LinkLsaType: {
00489             updatePacket->setLinkLsasArraySize(1);
00490             updatePacket->setLinkLsas(0, *linkLSA);
00491             unsigned short lsAge = updatePacket->getLinkLsas(0).getHeader().getLsAge();
00492             if (lsAge < MAX_AGE - interfaceTransmissionDelay){
00493                updatePacket->getLinkLsas(0).getHeader().setLsAge(lsAge + interfaceTransmissionDelay);
00494             }else{
00495                updatePacket->getLinkLsas(0).getHeader().setLsAge(MAX_AGE);
00496             }}
00497             break;
00498          case IntraAreaPrefixLsaType: {
00499             updatePacket->setIntraAreaPrefixLsasArraySize(1);
00500             updatePacket->setIntraAreaPrefixLsas(0, *intraAreaPrefixLSA);
00501             unsigned short lsAge = updatePacket->getIntraAreaPrefixLsas(0).getHeader().getLsAge();
00502             if (lsAge < MAX_AGE - interfaceTransmissionDelay){
00503                updatePacket->getIntraAreaPrefixLsas(0).getHeader().setLsAge(lsAge + interfaceTransmissionDelay);
00504             }else{
00505                updatePacket->getIntraAreaPrefixLsas(0).getHeader().setLsAge(MAX_AGE);
00506             }}
00507             break;
00508          default:
00509             break;
00510       }
00511       return updatePacket;
00512    }
00513    return NULL;
00514 }
00515 
00516 void AnsaOspf6::Interface::AddDelayedAcknowledgement(OspfLsaHeader6& lsaHeader){
00517    if (interfaceType == AnsaOspf6::Interface::Broadcast){
00518       if (  (GetState() == AnsaOspf6::Interface::DesignatedRouterState)
00519          || (GetState() == AnsaOspf6::Interface::BackupState)
00520          || (designatedRouter == AnsaOspf6::NullDesignatedRouterID)){
00521          delayedAcknowledgements[AnsaOspf6::AllSPFRouters].push_back(lsaHeader);
00522       }else{
00523          delayedAcknowledgements[AnsaOspf6::AllDRouters].push_back(lsaHeader);
00524       }
00525    }else{
00526       long neighborCount = neighboringRouters.size();
00527       for (long i = 0; i < neighborCount; i++){
00528          if (neighboringRouters[i]->GetState() >= AnsaOspf6::Neighbor::ExchangeState){
00529             delayedAcknowledgements[neighboringRouters[i]->GetAddress()].push_back(lsaHeader);
00530          }
00531       }
00532    }
00533 }
00534 
00535 void AnsaOspf6::Interface::SendDelayedAcknowledgements(void){
00536    AnsaOspf6::MessageHandler* messageHandler = parentArea->GetRouter()->GetMessageHandler();
00537    std::map<IPv6Address, std::list<OspfLsaHeader6>, AnsaOspf6::IPv6Address_Less>::iterator delayIt;
00538    for (delayIt = delayedAcknowledgements.begin(); delayIt != delayedAcknowledgements.end(); delayIt++){
00539       int ackCount = delayIt->second.size();
00540       if (ackCount > 0){
00541          while (!(delayIt->second.empty())){
00542             OspfLinkStateAcknowledgementPacket6* ackPacket = new OspfLinkStateAcknowledgementPacket6;
00543 
00544             ackPacket->setType(LinkStateAcknowledgementPacket);
00545             ackPacket->setRouterID(parentArea->GetRouter()->GetRouterID());
00546             ackPacket->setAreaID(areaID);
00547 
00548             while (!(delayIt->second.empty())){
00549                unsigned long headerCount = ackPacket->getLsaHeadersArraySize();
00550                ackPacket->setLsaHeadersArraySize(headerCount + 1);
00551                ackPacket->setLsaHeaders(headerCount, *(delayIt->second.begin()));
00552                delayIt->second.pop_front();
00553             }
00554 
00555             int ttl = (interfaceType == AnsaOspf6::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1;
00556 
00557             if (interfaceType == AnsaOspf6::Interface::Broadcast){
00558                if (  (GetState() == AnsaOspf6::Interface::DesignatedRouterState)
00559                   || (GetState() == AnsaOspf6::Interface::BackupState)
00560                   || (designatedRouter == AnsaOspf6::NullDesignatedRouterID)){
00561                   messageHandler->SendPacket(ackPacket, AnsaOspf6::AllSPFRouters, ifIndex, ttl);
00562                }else{
00563                   messageHandler->SendPacket(ackPacket, AnsaOspf6::AllDRouters, ifIndex, ttl);
00564                }
00565             }else{
00566                if (interfaceType == AnsaOspf6::Interface::PointToPoint){
00567                   messageHandler->SendPacket(ackPacket, AnsaOspf6::AllSPFRouters, ifIndex, ttl);
00568                }else{
00569                   messageHandler->SendPacket(ackPacket, delayIt->first, ifIndex, ttl);
00570                }
00571             }
00572          }
00573       }
00574    }
00575    messageHandler->StartTimer(acknowledgementTimer, acknowledgementDelay);
00576 }
00577 
00578 void AnsaOspf6::Interface::AgeTransmittedLSALists(void) {
00579    long neighborCount = neighboringRouters.size();
00580    for (long i = 0; i < neighborCount; i++){
00581       neighboringRouters[i]->AgeTransmittedLSAList();
00582    }
00583 }