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