00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "SCTP.h"
00021 #include "SCTPAssociation.h"
00022 #include "SCTPCommand_m.h"
00023 #include "IPControlInfo.h"
00024 #include "IPv6ControlInfo.h"
00025 #include "IPDatagram.h"
00026
00027
00028 Define_Module(SCTP);
00029
00030
00031 bool SCTP::testing;
00032 bool SCTP::logverbose;
00033
00034 int32 SCTP::nextConnId = 0;
00035
00036
00037 void SCTP::printInfoConnMap()
00038 {
00039 SCTPAssociation* assoc;
00040 SockPair key;
00041 sctpEV3<<"Number of Assocs: "<<sizeConnMap<<"\n";
00042 if (sizeConnMap>0)
00043 {
00044 for (SctpConnMap::iterator i = sctpConnMap.begin(); i!=sctpConnMap.end(); ++i)
00045 {
00046 assoc = i->second;
00047 key = i->first;
00048
00049 sctpEV3<<"assocId: "<<assoc->assocId<<" assoc: "<<assoc<<" src: "<<IPvXAddress(key.localAddr)<<" dst: "<<IPvXAddress(key.remoteAddr)<<" lPort: "<<key.localPort<<" rPort: "<<key.remotePort<<"\n";
00050
00051 }
00052
00053 sctpEV3<<"\n";
00054 }
00055
00056 }
00057
00058 void SCTP::printVTagMap()
00059 {
00060 int32 assocId;
00061 VTagPair key;
00062 sctpEV3<<"Number of Assocs: "<<sctpVTagMap.size()<<"\n";
00063 if (sctpVTagMap.size()>0)
00064 {
00065 for (SctpVTagMap::iterator i = sctpVTagMap.begin(); i!=sctpVTagMap.end(); ++i)
00066 {
00067 assocId = i->first;
00068 key = i->second;
00069
00070 sctpEV3<<"assocId: "<<assocId<<" peerVTag: "<<key.peerVTag<<
00071 " localVTag: "<<key.localVTag<<
00072 " localPort: "<<key.localPort<<" rPort: "<<key.remotePort<<"\n";
00073 }
00074
00075 sctpEV3<<"\n";
00076 }
00077 }
00078
00079 void SCTP::bindPortForUDP()
00080 {
00081 EV << "Binding to UDP port " << 9899 << endl;
00082
00083 cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND);
00084 UDPControlInfo *ctrl = new UDPControlInfo();
00085 ctrl->setSrcPort(9899);
00086 ctrl->setSockId(UDPSocket::generateSocketId());
00087 msg->setControlInfo(ctrl);
00088 send(msg, "to_ip");
00089 }
00090
00091 void SCTP::initialize()
00092 {
00093 nextEphemeralPort = (uint16)(intrand(10000) + 30000);
00094
00095
00096
00097 cModule *netw = simulation.getSystemModule();
00098
00099 testing = netw->hasPar("testing") && netw->par("testing").boolValue();
00100 if(testing) {
00101 }
00102 if (netw->hasPar("testTimeout"))
00103 {
00104 testTimeout = (simtime_t)netw->par("testTimeout");
00105 }
00106 numPacketsReceived = 0;
00107 numPacketsDropped = 0;
00108 sizeConnMap = 0;
00109 if ((bool)par("udpEncapsEnabled"))
00110 bindPortForUDP();
00111 }
00112
00113
00114 SCTP::~SCTP()
00115 {
00116 sctpEV3<<"delete SCTPMain\n";
00117 if (!(sctpAppConnMap.empty()))
00118 {
00119 sctpEV3<<"clear appConnMap ptr="<<&sctpAppConnMap<<"\n";
00120 sctpAppConnMap.clear();
00121 }
00122 if (!(assocStatMap.empty()))
00123 {
00124 sctpEV3<<"clear assocStatMap ptr="<<&assocStatMap<<"\n";
00125 assocStatMap.clear();
00126 }
00127 if (!(sctpVTagMap.empty()))
00128 {
00129 sctpVTagMap.clear();
00130 }
00131 sctpEV3<<"after clearing maps\n";
00132 }
00133
00134
00135 void SCTP::handleMessage(cMessage *msg)
00136 {
00137 IPvXAddress destAddr;
00138 IPvXAddress srcAddr;
00139 IPControlInfo *controlInfo =NULL;
00140 IPv6ControlInfo *controlInfoV6 =NULL;
00141 bool findListen = false;
00142 bool bitError = false;
00143
00144 sctpEV3<<"\n\nSCTPMain handleMessage at "<<getFullPath()<<"\n";
00145
00146 if (msg->isSelfMessage())
00147 {
00148
00149 sctpEV3<<"selfMessage\n";
00150
00151 SCTPAssociation *assoc = (SCTPAssociation *) msg->getContextPointer();
00152 bool ret = assoc->processTimer(msg);
00153
00154 if (!ret)
00155 removeAssociation(assoc);
00156 }
00157 else if (msg->arrivedOn("from_ip") || msg->arrivedOn("from_ipv6"))
00158 {
00159 sctpEV3<<"Message from IP\n";
00160 printInfoConnMap();
00161 if (!dynamic_cast<SCTPMessage *>(msg))
00162 {
00163 sctpEV3<<"no sctp message, delete it\n";
00164 delete msg;
00165 return;
00166 }
00167 SCTPMessage *sctpmsg = check_and_cast<SCTPMessage *>(msg);
00168
00169 numPacketsReceived++;
00170
00171 if ((sctpmsg->hasBitError() || !(sctpmsg->getChecksumOk()))) {
00172 sctpEV3<<"Packet has bit-error. delete it\n";
00173
00174 bitError = true;
00175 numPacketsDropped++;
00176 delete msg;
00177 return;
00178 }
00179 if (msg->arrivedOn("from_ip"))
00180 {
00181 if (par("udpEncapsEnabled"))
00182 {
00183 std::cout<<"Laenge SCTPMSG="<<sctpmsg->getByteLength()<<"\n";
00184 UDPControlInfo *ctrl = check_and_cast<UDPControlInfo *>(msg->removeControlInfo());
00185 srcAddr = ctrl->getSrcAddr();
00186 destAddr = ctrl->getDestAddr();
00187 std::cout<<"controlInfo srcAddr="<<srcAddr<<" destAddr="<<destAddr<<"\n";
00188 std::cout<<"VTag="<<sctpmsg->getTag()<<"\n";
00189 }
00190 else
00191 {
00192 controlInfo = check_and_cast<IPControlInfo *>(msg->removeControlInfo());
00193 IPDatagram *datagram = controlInfo->removeOrigDatagram();
00194 delete datagram;
00195 sctpEV3<<"controlInfo srcAddr="<<controlInfo->getSrcAddr()<<" destAddr="<<controlInfo->getDestAddr()<<"\n";
00196 srcAddr = controlInfo->getSrcAddr();
00197 destAddr = controlInfo->getDestAddr();
00198 }
00199 }
00200 else
00201 {
00202 controlInfoV6 = check_and_cast<IPv6ControlInfo *>(msg->removeControlInfo());
00203 srcAddr = controlInfoV6->getSrcAddr();
00204 destAddr = controlInfoV6->getDestAddr();
00205 }
00206
00207
00208 sctpEV3<<"srcAddr="<<srcAddr<<" destAddr="<<destAddr<<"\n";
00209 if (sctpmsg->getBitLength()>(SCTP_COMMON_HEADER*8))
00210 {
00211 if (((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()==INIT || ((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()==INIT_ACK )
00212 findListen = true;
00213
00214 SCTPAssociation *assoc = findAssocForMessage(srcAddr, destAddr, sctpmsg->getSrcPort(),sctpmsg->getDestPort(), findListen);
00215 if (!assoc && sctpConnMap.size()>0)
00216 assoc = findAssocWithVTag(sctpmsg->getTag(),sctpmsg->getSrcPort(), sctpmsg->getDestPort());
00217 if (!assoc)
00218 {
00219 sctpEV3<<"no assoc found msg="<<sctpmsg->getName()<<"\n";
00220 if (bitError)
00221 {
00222 delete sctpmsg;
00223 return;
00224 }
00225 if (((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()==SHUTDOWN_ACK)
00226 sendShutdownCompleteFromMain(sctpmsg, destAddr, srcAddr);
00227 else if (((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()!=ABORT &&
00228 ((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()!=SHUTDOWN_COMPLETE)
00229 {
00230 sendAbortFromMain(sctpmsg, destAddr, srcAddr);
00231 }
00232 delete sctpmsg;
00233 }
00234 else
00235 {
00236 bool ret = assoc->processSCTPMessage(sctpmsg, srcAddr, destAddr);
00237 if (!ret)
00238 {
00239 sctpEV3<<"SCTPMain:: removeAssociation \n";
00240 removeAssociation(assoc);
00241 delete sctpmsg;
00242 }
00243 else
00244 {
00245 delete sctpmsg;
00246 }
00247 }
00248 }
00249 else
00250 {
00251 delete sctpmsg;
00252 }
00253 }
00254 else
00255 {
00256 sctpEV3<<"must be from app\n";
00257 SCTPCommand *controlInfo = check_and_cast<SCTPCommand *>(msg->getControlInfo());
00258
00259 int32 appGateIndex;
00260 if (controlInfo->getGate()!=-1)
00261 appGateIndex = controlInfo->getGate();
00262 else
00263 appGateIndex = msg->getArrivalGate()->getIndex();
00264 int32 assocId = controlInfo->getAssocId();
00265 sctpEV3<<"msg arrived from app for assoc "<<assocId<<"\n";
00266 SCTPAssociation *assoc = findAssocForApp(appGateIndex, assocId);
00267
00268 if (!assoc)
00269 {
00270 sctpEV3 << "no assoc found. msg="<<msg->getName()<<" number of assocs = "<<assocList.size()<<"\n";
00271
00272 if (strcmp(msg->getName(),"PassiveOPEN")==0 || strcmp(msg->getName(),"Associate")==0)
00273 {
00274 if (assocList.size()>0)
00275 {
00276 assoc = NULL;
00277 SCTPOpenCommand* open = check_and_cast<SCTPOpenCommand*>(controlInfo);
00278 sctpEV3<<"Looking for assoc with remoteAddr="<<open->getRemoteAddr()<<", remotePort="<<open->getRemotePort()<<", localPort="<<open->getLocalPort()<<"\n";
00279 for (std::list<SCTPAssociation*>::iterator iter=assocList.begin(); iter!=assocList.end(); iter++)
00280 {
00281 sctpEV3<<"remoteAddr="<<(*iter)->remoteAddr<<", remotePort="<<(*iter)->remotePort<<", localPort="<<(*iter)->localPort<<"\n";
00282 if ((*iter)->remoteAddr == open->getRemoteAddr() && (*iter)->localPort==open->getLocalPort() && (*iter)->remotePort==open->getRemotePort())
00283 {
00284 assoc = (*iter);
00285 break;
00286 }
00287 }
00288 }
00289 if (assoc==NULL)
00290 {
00291 assoc = new SCTPAssociation(this,appGateIndex,assocId);
00292
00293 AppConnKey key;
00294 key.appGateIndex = appGateIndex;
00295 key.assocId = assocId;
00296 sctpAppConnMap[key] = assoc;
00297 sctpEV3 << "SCTP association created for appGateIndex " << appGateIndex << " and assoc "<<assocId<<"\n";
00298 bool ret = assoc->processAppCommand(PK(msg));
00299 if (!ret)
00300 {
00301 removeAssociation(assoc);
00302 }
00303 }
00304 }
00305 }
00306 else
00307 {
00308 sctpEV3<<"assoc found\n";
00309 bool ret = assoc->processAppCommand(PK(msg));
00310
00311 if (!ret)
00312 removeAssociation(assoc);
00313 }
00314 delete msg;
00315 }
00316 if (ev.isGUI())
00317 updateDisplayString();
00318 }
00319
00320 void SCTP::sendAbortFromMain(SCTPMessage* sctpmsg, IPvXAddress srcAddr, IPvXAddress destAddr)
00321 {
00322 SCTPMessage *msg = new SCTPMessage();
00323
00324 sctpEV3<<"\n\nSCTPMain:sendABORT \n";
00325
00326 msg->setSrcPort(sctpmsg->getDestPort());
00327 msg->setDestPort(sctpmsg->getSrcPort());
00328 msg->setBitLength(SCTP_COMMON_HEADER*8);
00329 msg->setChecksumOk(true);
00330
00331 SCTPAbortChunk* abortChunk = new SCTPAbortChunk("ABORT");
00332 abortChunk->setChunkType(ABORT);
00333 if (sctpmsg->getChunksArraySize()>0 && ((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()==INIT)
00334 {
00335
00336 SCTPInitChunk* initChunk = check_and_cast<SCTPInitChunk *>(sctpmsg->getChunks(0));
00337 abortChunk->setT_Bit(0);
00338 msg->setTag(initChunk->getInitTag());
00339 }
00340 else
00341 {
00342 abortChunk->setT_Bit(1);
00343 msg->setTag(sctpmsg->getTag());
00344 }
00345 abortChunk->setBitLength(SCTP_ABORT_CHUNK_LENGTH*8);
00346 msg->addChunk(abortChunk);
00347 if ((bool)par("udpEncapsEnabled"))
00348 {
00349 msg->setKind(UDP_C_DATA);
00350 std::cout<<"VTag="<<msg->getTag()<<"\n";
00351 UDPControlInfo *ctrl = new UDPControlInfo();
00352 ctrl->setSrcPort(9899);
00353 ctrl->setDestAddr(destAddr.get4());
00354 ctrl->setDestPort(9899);
00355 msg->setControlInfo(ctrl);
00356 }
00357 else
00358 {
00359 IPControlInfo *controlInfo = new IPControlInfo();
00360 controlInfo->setProtocol(IP_PROT_SCTP);
00361 controlInfo->setSrcAddr(srcAddr.get4());
00362 controlInfo->setDestAddr(destAddr.get4());
00363 msg->setControlInfo(controlInfo);
00364 }
00365 send(msg,"to_ip");
00366 }
00367
00368 void SCTP::sendShutdownCompleteFromMain(SCTPMessage* sctpmsg, IPvXAddress srcAddr, IPvXAddress destAddr)
00369 {
00370 SCTPMessage *msg = new SCTPMessage();
00371
00372 sctpEV3<<"\n\nSCTP:sendABORT \n";
00373
00374 msg->setSrcPort(sctpmsg->getDestPort());
00375 msg->setDestPort(sctpmsg->getSrcPort());
00376 msg->setBitLength(SCTP_COMMON_HEADER*8);
00377 msg->setChecksumOk(true);
00378
00379 SCTPShutdownCompleteChunk* scChunk = new SCTPShutdownCompleteChunk("SHUTDOWN_COMPLETE");
00380 scChunk->setChunkType(SHUTDOWN_COMPLETE);
00381 scChunk->setTBit(1);
00382 msg->setTag(sctpmsg->getTag());
00383
00384 scChunk->setBitLength(SCTP_SHUTDOWN_ACK_LENGTH*8);
00385 msg->addChunk(scChunk);
00386 IPControlInfo *controlInfo = new IPControlInfo();
00387 controlInfo->setProtocol(IP_PROT_SCTP);
00388 controlInfo->setSrcAddr(srcAddr.get4());
00389 controlInfo->setDestAddr(destAddr.get4());
00390 msg->setControlInfo(controlInfo);
00391 send(msg,"to_ip");
00392 }
00393
00394
00395 void SCTP::updateDisplayString()
00396 {
00397 if (ev.disable_tracing)
00398 {
00399
00400
00401 getDisplayString().setTagArg("t",0,"");
00402 return;
00403 }
00404
00405 }
00406
00407 SCTPAssociation *SCTP::findAssocWithVTag(uint32 peerVTag, uint32 remotePort, uint32 localPort)
00408 {
00409
00410 printVTagMap();
00411 sctpEV3<<"findAssocWithVTag: peerVTag="<<peerVTag<<" srcPort="<<remotePort<<" destPort="<<localPort<<"\n";
00412 printInfoConnMap();
00413
00414
00415 for (SctpVTagMap::iterator i=sctpVTagMap.begin(); i!=sctpVTagMap.end();i++)
00416 {
00417 if ((i->second.peerVTag==peerVTag && i->second.localPort==localPort
00418 && i->second.remotePort==remotePort)
00419 || (i->second.localVTag==peerVTag && i->second.localPort==localPort
00420 && i->second.remotePort==remotePort))
00421 return getAssoc(i->first);
00422 }
00423 return NULL;
00424 }
00425
00426 SCTPAssociation *SCTP::findAssocForMessage(IPvXAddress srcAddr, IPvXAddress destAddr, uint32 srcPort, uint32 destPort, bool findListen)
00427 {
00428 SockPair key;
00429
00430 key.localAddr = destAddr;
00431 key.remoteAddr = srcAddr;
00432 key.localPort = destPort;
00433 key.remotePort = srcPort;
00434 SockPair save = key;
00435 sctpEV3<<"findAssocForMessage: srcAddr="<<destAddr<<" destAddr="<<srcAddr<<" srcPort="<<destPort<<" destPort="<<srcPort<<"\n";
00436 printInfoConnMap();
00437
00438
00439 SctpConnMap::iterator i;
00440 i = sctpConnMap.find(key);
00441 if (i!=sctpConnMap.end())
00442 return i->second;
00443
00444
00445
00446 key.localAddr.set("0.0.0.0");
00447
00448 i = sctpConnMap.find(key);
00449 if (i!=sctpConnMap.end())
00450 {
00451
00452
00453
00454 return i->second;
00455 }
00456
00457 if (findListen==true)
00458 {
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 key = save;
00471 key.remoteAddr.set("0.0.0.0");
00472 key.remotePort = 0;
00473 i = sctpConnMap.find(key);
00474 if (i!=sctpConnMap.end())
00475 {
00476
00477
00478
00479 return i->second;
00480 }
00481
00482
00483
00484 key.localAddr.set("0.0.0.0");
00485 i = sctpConnMap.find(key);
00486 if (i!=sctpConnMap.end())
00487 {
00488
00489
00490
00491 return i->second;
00492 }
00493 }
00494
00495
00496 sctpEV3<<"giving up on trying to find assoc for localAddr="<<srcAddr<<" remoteAddr="<<destAddr<<" localPort="<<srcPort<<" remotePort="<<destPort<<"\n";
00497 return NULL;
00498 }
00499
00500 SCTPAssociation *SCTP::findAssocForApp(int32 appGateIndex, int32 assocId)
00501 {
00502 AppConnKey key;
00503 key.appGateIndex = appGateIndex;
00504 key.assocId = assocId;
00505 sctpEV3<<"findAssoc for appGateIndex "<<appGateIndex<<" and assoc "<<assocId<<"\n";
00506 SctpAppConnMap::iterator i = sctpAppConnMap.find(key);
00507 return i==sctpAppConnMap.end() ? NULL : i->second;
00508 }
00509
00510 uint16 SCTP::getEphemeralPort()
00511 {
00512 if (nextEphemeralPort==5000)
00513 error("Ephemeral port range 1024..4999 exhausted (email SCTP model "
00514 "author that he should implement reuse of ephemeral ports!!!)");
00515 return nextEphemeralPort++;
00516 }
00517
00518 void SCTP::updateSockPair(SCTPAssociation *conn, IPvXAddress localAddr, IPvXAddress remoteAddr, int32 localPort, int32 remotePort)
00519 {
00520 SockPair key;
00521 sctpEV3<<"updateSockPair: localAddr: "<<localAddr<<" remoteAddr="<<remoteAddr<<" localPort="<<localPort<<" remotePort="<<remotePort<<"\n";
00522
00523 key.localAddr = (conn->localAddr = localAddr);
00524 key.remoteAddr = (conn->remoteAddr = remoteAddr);
00525 key.localPort = conn->localPort = localPort;
00526 key.remotePort = conn->remotePort = remotePort;
00527
00528 for (SctpConnMap::iterator i=sctpConnMap.begin(); i!=sctpConnMap.end(); i++)
00529 {
00530 if (i->second == conn)
00531 {
00532 sctpConnMap.erase(i);
00533 break;
00534 }
00535 }
00536
00537 sctpEV3<<"updateSockPair conn="<<conn<<" localAddr="<<key.localAddr<<" remoteAddr="<<key.remoteAddr<<" localPort="<<key.localPort<<" remotePort="<<remotePort<<"\n";
00538
00539 sctpConnMap[key] = conn;
00540 sizeConnMap = sctpConnMap.size();
00541
00542 sctpEV3<<"assoc inserted in sctpConnMap\n";
00543 printInfoConnMap();
00544 }
00545
00546 void SCTP::addLocalAddress(SCTPAssociation *conn, IPvXAddress address)
00547 {
00548
00549
00550
00551 SockPair key;
00552
00553 key.localAddr = conn->localAddr;
00554 key.remoteAddr = conn->remoteAddr;
00555 key.localPort = conn->localPort;
00556 key.remotePort = conn->remotePort;
00557
00558 SctpConnMap::iterator i = sctpConnMap.find(key);
00559 if (i!=sctpConnMap.end())
00560 {
00561 ASSERT(i->second==conn);
00562 if (key.localAddr.isUnspecified())
00563 {
00564 sctpConnMap.erase(i);
00565 sizeConnMap--;
00566 }
00567 }
00568 else
00569 sctpEV3<<"no actual sockPair found\n";
00570 key.localAddr = address;
00571
00572
00573 sctpConnMap[key] = conn;
00574 sizeConnMap = sctpConnMap.size();
00575 sctpEV3<<"number of connections="<<sizeConnMap<<"\n";
00576
00577 printInfoConnMap();
00578 }
00579
00580 void SCTP::addLocalAddressToAllRemoteAddresses(SCTPAssociation *conn, IPvXAddress address, std::vector<IPvXAddress> remAddresses)
00581 {
00582
00583
00584
00585 SockPair key;
00586
00587 for (AddressVector::iterator i=remAddresses.begin(); i!=remAddresses.end(); ++i)
00588 {
00589
00590 key.localAddr = conn->localAddr;
00591 key.remoteAddr = (*i);
00592 key.localPort = conn->localPort;
00593 key.remotePort = conn->remotePort;
00594
00595 SctpConnMap::iterator j = sctpConnMap.find(key);
00596 if (j!=sctpConnMap.end())
00597 {
00598 ASSERT(j->second==conn);
00599 if (key.localAddr.isUnspecified())
00600 {
00601 sctpConnMap.erase(j);
00602 sizeConnMap--;
00603 }
00604
00605 }
00606 else
00607 sctpEV3<<"no actual sockPair found\n";
00608 key.localAddr = address;
00609 sctpConnMap[key] = conn;
00610
00611 sizeConnMap++;
00612 sctpEV3<<"number of connections="<<sctpConnMap.size()<<"\n";
00613
00614 printInfoConnMap();
00615 }
00616 }
00617
00618 void SCTP::removeLocalAddressFromAllRemoteAddresses(SCTPAssociation *conn, IPvXAddress address, std::vector<IPvXAddress> remAddresses)
00619 {
00620
00621
00622
00623 SockPair key;
00624
00625 for (AddressVector::iterator i=remAddresses.begin(); i!=remAddresses.end(); ++i)
00626 {
00627
00628 key.localAddr = address;
00629 key.remoteAddr = (*i);
00630 key.localPort = conn->localPort;
00631 key.remotePort = conn->remotePort;
00632
00633 SctpConnMap::iterator j = sctpConnMap.find(key);
00634 if (j!=sctpConnMap.end())
00635 {
00636 ASSERT(j->second==conn);
00637 sctpConnMap.erase(j);
00638 sizeConnMap--;
00639 }
00640 else
00641 sctpEV3<<"no actual sockPair found\n";
00642
00643
00644
00645 printInfoConnMap();
00646 }
00647 }
00648
00649 void SCTP::removeRemoteAddressFromAllConnections(SCTPAssociation *conn, IPvXAddress address, std::vector<IPvXAddress> locAddresses)
00650 {
00651
00652
00653
00654 SockPair key;
00655
00656 for (AddressVector::iterator i=locAddresses.begin(); i!=locAddresses.end(); i++)
00657 {
00658
00659 key.localAddr = (*i);
00660 key.remoteAddr = address;
00661 key.localPort = conn->localPort;
00662 key.remotePort = conn->remotePort;
00663
00664 SctpConnMap::iterator j = sctpConnMap.find(key);
00665 if (j!=sctpConnMap.end())
00666 {
00667 ASSERT(j->second==conn);
00668 sctpConnMap.erase(j);
00669 sizeConnMap--;
00670 }
00671 else
00672 sctpEV3<<"no actual sockPair found\n";
00673
00674
00675
00676 printInfoConnMap();
00677 }
00678 }
00679
00680 void SCTP::addRemoteAddress(SCTPAssociation *conn, IPvXAddress localAddress, IPvXAddress remoteAddress)
00681 {
00682
00683 sctpEV3<<"Add remote Address: "<<remoteAddress<<" to local Address "<<localAddress<<"\n";
00684
00685 SockPair key;
00686 key.localAddr = localAddress;
00687 key.remoteAddr = remoteAddress;
00688 key.localPort = conn->localPort;
00689 key.remotePort = conn->remotePort;
00690
00691 SctpConnMap::iterator i = sctpConnMap.find(key);
00692 if (i!=sctpConnMap.end())
00693 {
00694 ASSERT(i->second==conn);
00695 }
00696 else
00697 {
00698
00699
00700
00701 sctpConnMap[key] = conn;
00702 sizeConnMap++;
00703 }
00704
00705
00706 printInfoConnMap();
00707 }
00708
00709 void SCTP::addForkedAssociation(SCTPAssociation *assoc, SCTPAssociation *newAssoc, IPvXAddress localAddr, IPvXAddress remoteAddr, int32 localPort, int32 remotePort)
00710 {
00711 SockPair keyAssoc;
00712
00713 ev<<"addForkedConnection assocId="<<assoc->assocId<<" newId="<<newAssoc->assocId<<"\n";
00714
00715 for (SctpConnMap::iterator j=sctpConnMap.begin(); j!=sctpConnMap.end(); ++j)
00716 if (assoc->assocId==j->second->assocId)
00717 keyAssoc = j->first;
00718
00719 updateSockPair(assoc, localAddr, remoteAddr, localPort, remotePort);
00720 updateSockPair(newAssoc, keyAssoc.localAddr, keyAssoc.remoteAddr, keyAssoc.localPort, keyAssoc.remotePort);
00721
00722 AppConnKey key;
00723 key.appGateIndex = assoc->appGateIndex;
00724 key.assocId = assoc->assocId;
00725 sctpAppConnMap.erase(key);
00726 key.assocId = assoc->assocId = getNewConnId();
00727 sctpAppConnMap[key] = assoc;
00728
00729
00730 key.appGateIndex = newAssoc->appGateIndex;
00731 key.assocId = newAssoc->assocId;
00732 sctpAppConnMap[key] = newAssoc;
00733
00734
00735 printInfoConnMap();
00736 }
00737
00738
00739
00740 void SCTP::removeAssociation(SCTPAssociation *conn)
00741 {
00742 bool ok = false;
00743 bool find = false;
00744 const int32 id = conn->assocId;
00745
00746 sctpEV3 << "Deleting SCTP connection " << conn << " id= "<< id << endl;
00747
00748 printInfoConnMap();
00749 if (sizeConnMap > 0) {
00750 AssocStatMap::iterator assocStatMapIterator = assocStatMap.find(conn->assocId);
00751 if (assocStatMapIterator != assocStatMap.end()) {
00752 assocStatMapIterator->second.stop = simulation.getSimTime();
00753 assocStatMapIterator->second.lifeTime = assocStatMapIterator->second.stop - assocStatMapIterator->second.start;
00754 assocStatMapIterator->second.throughput = assocStatMapIterator->second.ackedBytes*8 / assocStatMapIterator->second.lifeTime.dbl();
00755 }
00756 while (!ok) {
00757 if (sizeConnMap == 0) {
00758 ok = true;
00759 }
00760 else {
00761 for (SctpConnMap::iterator sctpConnMapIterator = sctpConnMap.begin();
00762 sctpConnMapIterator != sctpConnMap.end(); sctpConnMapIterator++) {
00763 if (sctpConnMapIterator->second != NULL) {
00764 SCTPAssociation* assoc = sctpConnMapIterator->second;
00765 if (assoc->assocId == conn->assocId) {
00766 if (assoc->T1_InitTimer) {
00767 assoc->stopTimer(assoc->T1_InitTimer);
00768 }
00769 if (assoc->T2_ShutdownTimer) {
00770 assoc->stopTimer(assoc->T2_ShutdownTimer);
00771 }
00772 if (assoc->T5_ShutdownGuardTimer) {
00773 assoc->stopTimer(assoc->T5_ShutdownGuardTimer);
00774 }
00775 if (assoc->SackTimer) {
00776 assoc->stopTimer(assoc->SackTimer);
00777 }
00778 sctpConnMap.erase(sctpConnMapIterator);
00779 sizeConnMap--;
00780 find = true;
00781 break;
00782 }
00783 }
00784 }
00785 }
00786
00787 if (!find) {
00788 ok = true;
00789 }
00790 else {
00791 find = false;
00792 }
00793 }
00794 }
00795
00796
00797 char str[128];
00798 for (SCTPAssociation::SCTPPathMap::iterator pathMapIterator = conn->sctpPathMap.begin();
00799 pathMapIterator != conn->sctpPathMap.end(); pathMapIterator++) {
00800 const SCTPPathVariables* path = pathMapIterator->second;
00801 snprintf((char*)&str, sizeof(str), "Number of Fast Retransmissions %d:%s",
00802 conn->assocId, path->remoteAddress.str().c_str());
00803 recordScalar(str, path->numberOfFastRetransmissions);
00804 snprintf((char*)&str, sizeof(str), "Number of Timer-Based Retransmissions %d:%s",
00805 conn->assocId, path->remoteAddress.str().c_str());
00806 recordScalar(str, path->numberOfTimerBasedRetransmissions);
00807 snprintf((char*)&str, sizeof(str), "Number of Heartbeats Sent %d:%s",
00808 conn->assocId, path->remoteAddress.str().c_str());
00809 recordScalar(str, path->numberOfHeartbeatsSent);
00810 snprintf((char*)&str, sizeof(str), "Number of Heartbeats Received %d:%s",
00811 conn->assocId, path->remoteAddress.str().c_str());
00812 recordScalar(str, path->numberOfHeartbeatsRcvd);
00813 snprintf((char*)&str, sizeof(str), "Number of Heartbeat ACKs Sent %d:%s",
00814 conn->assocId, path->remoteAddress.str().c_str());
00815 recordScalar(str, path->numberOfHeartbeatAcksSent);
00816 snprintf((char*)&str, sizeof(str), "Number of Heartbeat ACKs Received %d:%s",
00817 conn->assocId, path->remoteAddress.str().c_str());
00818 recordScalar(str, path->numberOfHeartbeatAcksRcvd);
00819 }
00820
00821
00822 conn->removePath();
00823 conn->deleteStreams();
00824
00825
00826
00827 for (SCTPQueue::PayloadQueue::iterator i = conn->getRetransmissionQueue()->payloadQueue.begin();
00828 i != conn->getRetransmissionQueue()->payloadQueue.end(); i++) {
00829 SCTPQueue::PayloadQueue::iterator j = conn->getTransmissionQueue()->payloadQueue.find(i->second->tsn);
00830 if(j != conn->getTransmissionQueue()->payloadQueue.end()) {
00831 conn->getTransmissionQueue()->payloadQueue.erase(j);
00832 }
00833 }
00834
00835 delete conn->getRetransmissionQueue();
00836 delete conn->getTransmissionQueue();
00837
00838 AppConnKey key;
00839 key.appGateIndex = conn->appGateIndex;
00840 key.assocId = conn->assocId;
00841 sctpAppConnMap.erase(key);
00842 assocList.remove(conn);
00843 delete conn;
00844 }
00845
00846 SCTPAssociation* SCTP::getAssoc(int32 assocId)
00847 {
00848 for (SctpAppConnMap::iterator i = sctpAppConnMap.begin(); i!=sctpAppConnMap.end(); i++)
00849 {
00850 if (i->first.assocId==assocId)
00851 return i->second;
00852 }
00853 return NULL;
00854 }
00855
00856 void SCTP::finish()
00857 {
00858 SctpConnMap::iterator connMapIterator = sctpConnMap.begin();
00859 while (connMapIterator != sctpConnMap.end()) {
00860 removeAssociation(connMapIterator->second);
00861 connMapIterator = sctpConnMap.begin();
00862 }
00863 ev << getFullPath() << ": finishing SCTP with "
00864 << sctpConnMap.size() << " connections open." << endl;
00865
00866 for (AssocStatMap::const_iterator iterator = assocStatMap.begin();
00867 iterator != assocStatMap.end(); iterator++) {
00868 const SCTP::AssocStat& assoc = iterator->second;
00869
00870 ev << "Association " << assoc.assocId << ": started at " << assoc.start
00871 << " and finished at " << assoc.stop << " --> lifetime: " << assoc.lifeTime << endl;
00872 ev << "Association " << assoc.assocId << ": sent bytes=" << assoc.sentBytes
00873 << ", acked bytes=" << assoc.ackedBytes<< ", throughput=" << assoc.throughput<< " bit/s" << endl;
00874 ev << "Association " << assoc.assocId << ": transmitted Bytes="
00875 << assoc.transmittedBytes<< ", retransmitted Bytes=" << assoc.transmittedBytes-assoc.ackedBytes<< endl;
00876 ev << "Association " << assoc.assocId << ": number of Fast RTX="
00877 << assoc.numFastRtx << ", number of Timer-Based RTX=" << assoc.numT3Rtx
00878 << ", path failures=" << assoc.numPathFailures<< ", ForwardTsns=" << assoc.numForwardTsn<< endl;
00879 ev << "AllMessages=" <<numPacketsReceived<< " BadMessages=" <<numPacketsDropped<< endl;
00880
00881 recordScalar("Association Lifetime", assoc.lifeTime);
00882 recordScalar("Acked Bytes", assoc.ackedBytes);
00883 recordScalar("Throughput [bit/s]", assoc.throughput);
00884 recordScalar("Transmitted Bytes", assoc.transmittedBytes);
00885 recordScalar("Fast RTX", assoc.numFastRtx);
00886 recordScalar("Timer-Based RTX", assoc.numT3Rtx);
00887 recordScalar("Duplicate Acks", assoc.numDups);
00888 recordScalar("Packets Received", numPacketsReceived);
00889 recordScalar("Packets Dropped", numPacketsDropped);
00890
00891 }
00892 }