#include <SCTP.h>
Classes | |
struct | AppConnKey |
struct | AssocStat |
struct | SockPair |
struct | VTagPair |
Public Types | |
typedef std::map< int32, AssocStat > | AssocStatMap |
typedef std::map< int32, VTagPair > | SctpVTagMap |
typedef std::map< AppConnKey, SCTPAssociation * > | SctpAppConnMap |
typedef std::map< SockPair, SCTPAssociation * > | SctpConnMap |
Public Member Functions | |
void | printInfoConnMap () |
void | printVTagMap () |
void | removeAssociation (SCTPAssociation *assoc) |
virtual | ~SCTP () |
virtual void | initialize () |
virtual void | handleMessage (cMessage *msg) |
virtual void | finish () |
AssocStat * | getAssocStat (uint32 assocId) |
void | updateSockPair (SCTPAssociation *assoc, IPvXAddress localAddr, IPvXAddress remoteAddr, int32 localPort, int32 remotePort) |
void | addLocalAddress (SCTPAssociation *conn, IPvXAddress address) |
void | addLocalAddressToAllRemoteAddresses (SCTPAssociation *conn, IPvXAddress address, std::vector< IPvXAddress > remAddresses) |
void | addRemoteAddress (SCTPAssociation *conn, IPvXAddress localAddress, IPvXAddress remoteAddress) |
void | removeLocalAddressFromAllRemoteAddresses (SCTPAssociation *conn, IPvXAddress address, std::vector< IPvXAddress > remAddresses) |
void | removeRemoteAddressFromAllConnections (SCTPAssociation *conn, IPvXAddress address, std::vector< IPvXAddress > locAddresses) |
void | addForkedAssociation (SCTPAssociation *assoc, SCTPAssociation *newAssoc, IPvXAddress localAddr, IPvXAddress remoteAddr, int32 localPort, int32 remotePort) |
uint16 | getEphemeralPort () |
SCTPAssociation * | getAssoc (int32 assocId) |
SCTPAssociation * | findAssocWithVTag (uint32 peerVTag, uint32 remotePort, uint32 localPort) |
SctpVTagMap | getVTagMap () |
void | bindPortForUDP () |
Static Public Member Functions | |
static int32 | getNewConnId () |
Public Attributes | |
AssocStatMap | assocStatMap |
SctpVTagMap | sctpVTagMap |
SctpAppConnMap | sctpAppConnMap |
SctpConnMap | sctpConnMap |
std::list< SCTPAssociation * > | assocList |
simtime_t | testTimeout |
uint32 | numGapReports |
uint32 | numPacketsReceived |
uint32 | numPacketsDropped |
Static Public Attributes | |
static bool | testing |
static bool | logverbose |
Protected Member Functions | |
SCTPAssociation * | findAssocForMessage (IPvXAddress srcAddr, IPvXAddress destAddr, uint32 srcPort, uint32 destPort, bool findListen) |
SCTPAssociation * | findAssocForApp (int32 appGateIndex, int32 assocId) |
void | sendAbortFromMain (SCTPMessage *sctpmsg, IPvXAddress srcAddr, IPvXAddress destAddr) |
void | sendShutdownCompleteFromMain (SCTPMessage *sctpmsg, IPvXAddress srcAddr, IPvXAddress destAddr) |
void | updateDisplayString () |
Protected Attributes | |
int32 | sizeConnMap |
uint16 | nextEphemeralPort |
Static Protected Attributes | |
static int32 | nextConnId = 0 |
Implements the SCTP protocol. This section describes the internal architecture of the SCTP model.
You may want to check the SCTPSocket class which makes it easier to use SCTP from applications.
The SCTP protocol implementation is composed of several classes (discussion follows below):
SCTP subclassed from cSimpleModule. It manages socketpair-to-connection mapping, and dispatches segments and user commands to the appropriate SCTPAssociation object.
SCTPAssociation manages the connection, with the help of other objects. SCTPAssociation itself implements the basic SCTP "machinery": takes care of the state machine, stores the state variables (TCB), sends/receives etc.
SCTPAssociation internally relies on 3 objects. The first two are subclassed from SCTPSendQueue and SCTPReceiveQueue. They manage the actual data stream, so SCTPAssociation itself only works with sequence number variables. This makes it possible to easily accomodate need for various types of simulated data transfer: real byte stream, "virtual" bytes (byte counts only), and sequence of cMessage objects (where every message object is mapped to a SCTP sequence number range).
Currently implemented send queue and receive queue classes are SCTPVirtualDataSendQueue and SCTPVirtualDataRcvQueue which implement queues with "virtual" bytes (byte counts only).
The third object is subclassed from SCTPAlgorithm. Control over retransmissions, congestion control and ACK sending are "outsourced" from SCTPAssociation into SCTPAlgorithm: delayed acks, slow start, fast rexmit, etc. are all implemented in SCTPAlgorithm subclasses.
The concrete SCTPAlgorithm class to use can be chosen per connection (in OPEN) or in a module parameter.
Definition at line 84 of file SCTP.h.
typedef std::map<int32,AssocStat> SCTP::AssocStatMap |
typedef std::map<AppConnKey,SCTPAssociation*> SCTP::SctpAppConnMap |
typedef std::map<SockPair,SCTPAssociation*> SCTP::SctpConnMap |
typedef std::map<int32, VTagPair> SCTP::SctpVTagMap |
SCTP::~SCTP | ( | ) | [virtual] |
Definition at line 114 of file SCTP.cc.
{ sctpEV3<<"delete SCTPMain\n"; if (!(sctpAppConnMap.empty())) { sctpEV3<<"clear appConnMap ptr="<<&sctpAppConnMap<<"\n"; sctpAppConnMap.clear(); } if (!(assocStatMap.empty())) { sctpEV3<<"clear assocStatMap ptr="<<&assocStatMap<<"\n"; assocStatMap.clear(); } if (!(sctpVTagMap.empty())) { sctpVTagMap.clear(); } sctpEV3<<"after clearing maps\n"; }
void SCTP::addForkedAssociation | ( | SCTPAssociation * | assoc, | |
SCTPAssociation * | newAssoc, | |||
IPvXAddress | localAddr, | |||
IPvXAddress | remoteAddr, | |||
int32 | localPort, | |||
int32 | remotePort | |||
) |
Update assocs socket pair, and register newAssoc (which'll keep LISTENing). Also, assoc will get a new assocId (and newAssoc will live on with its old assocId).
Definition at line 709 of file SCTP.cc.
Referenced by SCTPAssociation::processInitArrived().
{ SockPair keyAssoc; ev<<"addForkedConnection assocId="<<assoc->assocId<<" newId="<<newAssoc->assocId<<"\n"; for (SctpConnMap::iterator j=sctpConnMap.begin(); j!=sctpConnMap.end(); ++j) if (assoc->assocId==j->second->assocId) keyAssoc = j->first; // update conn's socket pair, and register newConn (which'll keep LISTENing) updateSockPair(assoc, localAddr, remoteAddr, localPort, remotePort); updateSockPair(newAssoc, keyAssoc.localAddr, keyAssoc.remoteAddr, keyAssoc.localPort, keyAssoc.remotePort); // conn will get a new assocId... AppConnKey key; key.appGateIndex = assoc->appGateIndex; key.assocId = assoc->assocId; sctpAppConnMap.erase(key); key.assocId = assoc->assocId = getNewConnId(); sctpAppConnMap[key] = assoc; // ...and newConn will live on with the old assocId key.appGateIndex = newAssoc->appGateIndex; key.assocId = newAssoc->assocId; sctpAppConnMap[key] = newAssoc; /*ev<<"assocId="<<assoc->assocId<<" remoteAddr="<<assoc->remoteAddr<<"\n"; assoc->removeOldPath();*/ printInfoConnMap(); }
void SCTP::addLocalAddress | ( | SCTPAssociation * | conn, | |
IPvXAddress | address | |||
) |
Definition at line 546 of file SCTP.cc.
Referenced by SCTPAssociation::processInitArrived(), and SCTPAssociation::sendInit().
{ //sctpEV3<<"Add local address: "<<address<<"\n"; SockPair key; key.localAddr = conn->localAddr; key.remoteAddr = conn->remoteAddr; key.localPort = conn->localPort; key.remotePort = conn->remotePort; SctpConnMap::iterator i = sctpConnMap.find(key); if (i!=sctpConnMap.end()) { ASSERT(i->second==conn); if (key.localAddr.isUnspecified()) { sctpConnMap.erase(i); sizeConnMap--; } } else sctpEV3<<"no actual sockPair found\n"; key.localAddr = address; //key.localAddr = address.get4().getInt(); // //sctpEV3<<"laddr="<<key.localAddr<<" lp="<<key.localPort<<" raddr="<<key.remoteAddr<<" rPort="<<key.remotePort<<"\n"; sctpConnMap[key] = conn; sizeConnMap = sctpConnMap.size(); sctpEV3<<"number of connections="<<sizeConnMap<<"\n"; printInfoConnMap(); }
void SCTP::addLocalAddressToAllRemoteAddresses | ( | SCTPAssociation * | conn, | |
IPvXAddress | address, | |||
std::vector< IPvXAddress > | remAddresses | |||
) |
Definition at line 580 of file SCTP.cc.
{ //sctpEV3<<"Add local address: "<<address<<"\n"; SockPair key; for (AddressVector::iterator i=remAddresses.begin(); i!=remAddresses.end(); ++i) { //sctpEV3<<"remote address="<<(*i)<<"\n"; key.localAddr = conn->localAddr; key.remoteAddr = (*i); key.localPort = conn->localPort; key.remotePort = conn->remotePort; SctpConnMap::iterator j = sctpConnMap.find(key); if (j!=sctpConnMap.end()) { ASSERT(j->second==conn); if (key.localAddr.isUnspecified()) { sctpConnMap.erase(j); sizeConnMap--; } } else sctpEV3<<"no actual sockPair found\n"; key.localAddr = address; sctpConnMap[key] = conn; sizeConnMap++; sctpEV3<<"number of connections="<<sctpConnMap.size()<<"\n"; printInfoConnMap(); } }
void SCTP::addRemoteAddress | ( | SCTPAssociation * | conn, | |
IPvXAddress | localAddress, | |||
IPvXAddress | remoteAddress | |||
) |
Definition at line 680 of file SCTP.cc.
Referenced by SCTPAssociation::processInitAckArrived(), and SCTPAssociation::processInitArrived().
{ sctpEV3<<"Add remote Address: "<<remoteAddress<<" to local Address "<<localAddress<<"\n"; SockPair key; key.localAddr = localAddress; key.remoteAddr = remoteAddress; key.localPort = conn->localPort; key.remotePort = conn->remotePort; SctpConnMap::iterator i = sctpConnMap.find(key); if (i!=sctpConnMap.end()) { ASSERT(i->second==conn); } else { //sctpEV3<<"no actual sockPair found\n"; sctpConnMap[key] = conn; sizeConnMap++; } //sctpEV3<<"number of connections="<<sctpConnMap.size()<<"\n"; printInfoConnMap(); }
void SCTP::bindPortForUDP | ( | ) |
Definition at line 79 of file SCTP.cc.
Referenced by initialize().
{ EV << "Binding to UDP port " << 9899 << endl; cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND); UDPControlInfo *ctrl = new UDPControlInfo(); ctrl->setSrcPort(9899); ctrl->setSockId(UDPSocket::generateSocketId()); msg->setControlInfo(ctrl); send(msg, "to_ip"); }
SCTPAssociation * SCTP::findAssocForApp | ( | int32 | appGateIndex, | |
int32 | assocId | |||
) | [protected] |
Definition at line 500 of file SCTP.cc.
Referenced by handleMessage().
{ AppConnKey key; key.appGateIndex = appGateIndex; key.assocId = assocId; sctpEV3<<"findAssoc for appGateIndex "<<appGateIndex<<" and assoc "<<assocId<<"\n"; SctpAppConnMap::iterator i = sctpAppConnMap.find(key); return i==sctpAppConnMap.end() ? NULL : i->second; }
SCTPAssociation * SCTP::findAssocForMessage | ( | IPvXAddress | srcAddr, | |
IPvXAddress | destAddr, | |||
uint32 | srcPort, | |||
uint32 | destPort, | |||
bool | findListen | |||
) | [protected] |
Definition at line 426 of file SCTP.cc.
Referenced by handleMessage().
{ SockPair key; key.localAddr = destAddr; key.remoteAddr = srcAddr; key.localPort = destPort; key.remotePort = srcPort; SockPair save = key; sctpEV3<<"findAssocForMessage: srcAddr="<<destAddr<<" destAddr="<<srcAddr<<" srcPort="<<destPort<<" destPort="<<srcPort<<"\n"; printInfoConnMap(); // try with fully qualified SockPair SctpConnMap::iterator i; i = sctpConnMap.find(key); if (i!=sctpConnMap.end()) return i->second; // try with localAddr missing (only localPort specified in passive/active open) key.localAddr.set("0.0.0.0"); i = sctpConnMap.find(key); if (i!=sctpConnMap.end()) { //sctpEV3<<"try with localAddr missing (only localPort specified in passive/active open)\n"; return i->second; } if (findListen==true) { /*key = save; key.localPort = 0; key.localAddr.set("0.0.0.0"); i = sctpConnMap.find(key); if (i!=sctpConnMap.end()) { return i->second; }*/ // try fully qualified local socket + blank remote socket (for incoming SYN) key = save; key.remoteAddr.set("0.0.0.0"); key.remotePort = 0; i = sctpConnMap.find(key); if (i!=sctpConnMap.end()) { //sctpEV3<<"try fully qualified local socket + blank remote socket \n"; return i->second; } // try with blank remote socket, and localAddr missing (for incoming SYN) key.localAddr.set("0.0.0.0"); i = sctpConnMap.find(key); if (i!=sctpConnMap.end()) { //sctpEV3<<"try with blank remote socket, and localAddr missing \n"; return i->second; } } // given up sctpEV3<<"giving up on trying to find assoc for localAddr="<<srcAddr<<" remoteAddr="<<destAddr<<" localPort="<<srcPort<<" remotePort="<<destPort<<"\n"; return NULL; }
SCTPAssociation * SCTP::findAssocWithVTag | ( | uint32 | peerVTag, | |
uint32 | remotePort, | |||
uint32 | localPort | |||
) |
Definition at line 407 of file SCTP.cc.
Referenced by handleMessage().
{ printVTagMap(); sctpEV3<<"findAssocWithVTag: peerVTag="<<peerVTag<<" srcPort="<<remotePort<<" destPort="<<localPort<<"\n"; printInfoConnMap(); // try with fully qualified SockPair for (SctpVTagMap::iterator i=sctpVTagMap.begin(); i!=sctpVTagMap.end();i++) { if ((i->second.peerVTag==peerVTag && i->second.localPort==localPort && i->second.remotePort==remotePort) || (i->second.localVTag==peerVTag && i->second.localPort==localPort && i->second.remotePort==remotePort)) return getAssoc(i->first); } return NULL; }
void SCTP::finish | ( | ) | [virtual] |
Definition at line 856 of file SCTP.cc.
{ SctpConnMap::iterator connMapIterator = sctpConnMap.begin(); while (connMapIterator != sctpConnMap.end()) { removeAssociation(connMapIterator->second); connMapIterator = sctpConnMap.begin(); } ev << getFullPath() << ": finishing SCTP with " << sctpConnMap.size() << " connections open." << endl; for (AssocStatMap::const_iterator iterator = assocStatMap.begin(); iterator != assocStatMap.end(); iterator++) { const SCTP::AssocStat& assoc = iterator->second; ev << "Association " << assoc.assocId << ": started at " << assoc.start << " and finished at " << assoc.stop << " --> lifetime: " << assoc.lifeTime << endl; ev << "Association " << assoc.assocId << ": sent bytes=" << assoc.sentBytes << ", acked bytes=" << assoc.ackedBytes<< ", throughput=" << assoc.throughput<< " bit/s" << endl; ev << "Association " << assoc.assocId << ": transmitted Bytes=" << assoc.transmittedBytes<< ", retransmitted Bytes=" << assoc.transmittedBytes-assoc.ackedBytes<< endl; ev << "Association " << assoc.assocId << ": number of Fast RTX=" << assoc.numFastRtx << ", number of Timer-Based RTX=" << assoc.numT3Rtx << ", path failures=" << assoc.numPathFailures<< ", ForwardTsns=" << assoc.numForwardTsn<< endl; ev << "AllMessages=" <<numPacketsReceived<< " BadMessages=" <<numPacketsDropped<< endl; recordScalar("Association Lifetime", assoc.lifeTime); recordScalar("Acked Bytes", assoc.ackedBytes); recordScalar("Throughput [bit/s]", assoc.throughput); recordScalar("Transmitted Bytes", assoc.transmittedBytes); recordScalar("Fast RTX", assoc.numFastRtx); recordScalar("Timer-Based RTX", assoc.numT3Rtx); recordScalar("Duplicate Acks", assoc.numDups); recordScalar("Packets Received", numPacketsReceived); recordScalar("Packets Dropped", numPacketsDropped); } }
SCTPAssociation * SCTP::getAssoc | ( | int32 | assocId | ) |
Definition at line 846 of file SCTP.cc.
Referenced by findAssocWithVTag().
{ for (SctpAppConnMap::iterator i = sctpAppConnMap.begin(); i!=sctpAppConnMap.end(); i++) { if (i->first.assocId==assocId) return i->second; } return NULL; }
AssocStat* SCTP::getAssocStat | ( | uint32 | assocId | ) | [inline] |
Definition at line 199 of file SCTP.h.
Referenced by SCTPAssociation::dequeueAckedChunks(), and SCTPAssociation::handleChunkReportedAsMissing().
{ SCTP::AssocStatMap::iterator found = assocStatMap.find(assocId); if(found != assocStatMap.end()) { return(&found->second); } return(NULL); }
uint16 SCTP::getEphemeralPort | ( | ) |
To be called from SCTPAssociation: reserves an ephemeral port for the connection.
Definition at line 510 of file SCTP.cc.
Referenced by SCTPAssociation::process_ASSOCIATE().
{ if (nextEphemeralPort==5000) error("Ephemeral port range 1024..4999 exhausted (email SCTP model " "author that he should implement reuse of ephemeral ports!!!)"); return nextEphemeralPort++; }
static int32 SCTP::getNewConnId | ( | ) | [inline, static] |
Generates a new integer, to be used as assocId. (assocId is part of the key which associates connections with their apps).
Definition at line 231 of file SCTP.h.
Referenced by addForkedAssociation(), SCTPSocket::connect(), SCTPSocket::listen(), and SCTPSocket::SCTPSocket().
{return ++nextConnId;}
SctpVTagMap SCTP::getVTagMap | ( | ) | [inline] |
Definition at line 235 of file SCTP.h.
{return sctpVTagMap;};
void SCTP::handleMessage | ( | cMessage * | msg | ) | [virtual] |
Definition at line 135 of file SCTP.cc.
{ IPvXAddress destAddr; IPvXAddress srcAddr; IPControlInfo *controlInfo =NULL; IPv6ControlInfo *controlInfoV6 =NULL; bool findListen = false; bool bitError = false; sctpEV3<<"\n\nSCTPMain handleMessage at "<<getFullPath()<<"\n"; if (msg->isSelfMessage()) { sctpEV3<<"selfMessage\n"; SCTPAssociation *assoc = (SCTPAssociation *) msg->getContextPointer(); bool ret = assoc->processTimer(msg); if (!ret) removeAssociation(assoc); } else if (msg->arrivedOn("from_ip") || msg->arrivedOn("from_ipv6")) { sctpEV3<<"Message from IP\n"; printInfoConnMap(); if (!dynamic_cast<SCTPMessage *>(msg)) { sctpEV3<<"no sctp message, delete it\n"; delete msg; return; } SCTPMessage *sctpmsg = check_and_cast<SCTPMessage *>(msg); numPacketsReceived++; if ((sctpmsg->hasBitError() || !(sctpmsg->getChecksumOk()))) { sctpEV3<<"Packet has bit-error. delete it\n"; bitError = true; numPacketsDropped++; delete msg; return; } if (msg->arrivedOn("from_ip")) { if (par("udpEncapsEnabled")) { std::cout<<"Laenge SCTPMSG="<<sctpmsg->getByteLength()<<"\n"; UDPControlInfo *ctrl = check_and_cast<UDPControlInfo *>(msg->removeControlInfo()); srcAddr = ctrl->getSrcAddr(); destAddr = ctrl->getDestAddr(); std::cout<<"controlInfo srcAddr="<<srcAddr<<" destAddr="<<destAddr<<"\n"; std::cout<<"VTag="<<sctpmsg->getTag()<<"\n"; } else { controlInfo = check_and_cast<IPControlInfo *>(msg->removeControlInfo()); IPDatagram *datagram = controlInfo->removeOrigDatagram(); delete datagram; sctpEV3<<"controlInfo srcAddr="<<controlInfo->getSrcAddr()<<" destAddr="<<controlInfo->getDestAddr()<<"\n"; srcAddr = controlInfo->getSrcAddr(); destAddr = controlInfo->getDestAddr(); } } else { controlInfoV6 = check_and_cast<IPv6ControlInfo *>(msg->removeControlInfo()); srcAddr = controlInfoV6->getSrcAddr(); destAddr = controlInfoV6->getDestAddr(); } sctpEV3<<"srcAddr="<<srcAddr<<" destAddr="<<destAddr<<"\n"; if (sctpmsg->getBitLength()>(SCTP_COMMON_HEADER*8)) { if (((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()==INIT || ((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()==INIT_ACK ) findListen = true; SCTPAssociation *assoc = findAssocForMessage(srcAddr, destAddr, sctpmsg->getSrcPort(),sctpmsg->getDestPort(), findListen); if (!assoc && sctpConnMap.size()>0) assoc = findAssocWithVTag(sctpmsg->getTag(),sctpmsg->getSrcPort(), sctpmsg->getDestPort()); if (!assoc) { sctpEV3<<"no assoc found msg="<<sctpmsg->getName()<<"\n"; if (bitError) { delete sctpmsg; return; } if (((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()==SHUTDOWN_ACK) sendShutdownCompleteFromMain(sctpmsg, destAddr, srcAddr); else if (((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()!=ABORT && ((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()!=SHUTDOWN_COMPLETE) { sendAbortFromMain(sctpmsg, destAddr, srcAddr); } delete sctpmsg; } else { bool ret = assoc->processSCTPMessage(sctpmsg, srcAddr, destAddr); if (!ret) { sctpEV3<<"SCTPMain:: removeAssociation \n"; removeAssociation(assoc); delete sctpmsg; } else { delete sctpmsg; } } } else { delete sctpmsg; } } else // must be from app { sctpEV3<<"must be from app\n"; SCTPCommand *controlInfo = check_and_cast<SCTPCommand *>(msg->getControlInfo()); int32 appGateIndex; if (controlInfo->getGate()!=-1) appGateIndex = controlInfo->getGate(); else appGateIndex = msg->getArrivalGate()->getIndex(); int32 assocId = controlInfo->getAssocId(); sctpEV3<<"msg arrived from app for assoc "<<assocId<<"\n"; SCTPAssociation *assoc = findAssocForApp(appGateIndex, assocId); if (!assoc) { sctpEV3 << "no assoc found. msg="<<msg->getName()<<" number of assocs = "<<assocList.size()<<"\n"; if (strcmp(msg->getName(),"PassiveOPEN")==0 || strcmp(msg->getName(),"Associate")==0) { if (assocList.size()>0) { assoc = NULL; SCTPOpenCommand* open = check_and_cast<SCTPOpenCommand*>(controlInfo); sctpEV3<<"Looking for assoc with remoteAddr="<<open->getRemoteAddr()<<", remotePort="<<open->getRemotePort()<<", localPort="<<open->getLocalPort()<<"\n"; for (std::list<SCTPAssociation*>::iterator iter=assocList.begin(); iter!=assocList.end(); iter++) { sctpEV3<<"remoteAddr="<<(*iter)->remoteAddr<<", remotePort="<<(*iter)->remotePort<<", localPort="<<(*iter)->localPort<<"\n"; if ((*iter)->remoteAddr == open->getRemoteAddr() && (*iter)->localPort==open->getLocalPort() && (*iter)->remotePort==open->getRemotePort()) { assoc = (*iter); break; } } } if (assoc==NULL) { assoc = new SCTPAssociation(this,appGateIndex,assocId); AppConnKey key; key.appGateIndex = appGateIndex; key.assocId = assocId; sctpAppConnMap[key] = assoc; sctpEV3 << "SCTP association created for appGateIndex " << appGateIndex << " and assoc "<<assocId<<"\n"; bool ret = assoc->processAppCommand(PK(msg)); if (!ret) { removeAssociation(assoc); } } } } else { sctpEV3<<"assoc found\n"; bool ret = assoc->processAppCommand(PK(msg)); if (!ret) removeAssociation(assoc); } delete msg; } if (ev.isGUI()) updateDisplayString(); }
void SCTP::initialize | ( | ) | [virtual] |
Definition at line 91 of file SCTP.cc.
{ nextEphemeralPort = (uint16)(intrand(10000) + 30000); //sctpEV3<<"SCTPMain initialize\n"; cModule *netw = simulation.getSystemModule(); testing = netw->hasPar("testing") && netw->par("testing").boolValue(); if(testing) { } if (netw->hasPar("testTimeout")) { testTimeout = (simtime_t)netw->par("testTimeout"); } numPacketsReceived = 0; numPacketsDropped = 0; sizeConnMap = 0; if ((bool)par("udpEncapsEnabled")) bindPortForUDP(); }
void SCTP::printInfoConnMap | ( | ) |
Definition at line 37 of file SCTP.cc.
Referenced by addForkedAssociation(), addLocalAddress(), addLocalAddressToAllRemoteAddresses(), addRemoteAddress(), SCTPAssociation::cloneAssociation(), findAssocForMessage(), findAssocWithVTag(), handleMessage(), removeAssociation(), removeLocalAddressFromAllRemoteAddresses(), removeRemoteAddressFromAllConnections(), SCTPAssociation::sendInit(), and updateSockPair().
{ SCTPAssociation* assoc; SockPair key; sctpEV3<<"Number of Assocs: "<<sizeConnMap<<"\n"; if (sizeConnMap>0) { for (SctpConnMap::iterator i = sctpConnMap.begin(); i!=sctpConnMap.end(); ++i) { assoc = i->second; key = i->first; sctpEV3<<"assocId: "<<assoc->assocId<<" assoc: "<<assoc<<" src: "<<IPvXAddress(key.localAddr)<<" dst: "<<IPvXAddress(key.remoteAddr)<<" lPort: "<<key.localPort<<" rPort: "<<key.remotePort<<"\n"; } sctpEV3<<"\n"; } }
void SCTP::printVTagMap | ( | ) |
Definition at line 58 of file SCTP.cc.
Referenced by findAssocWithVTag().
{ int32 assocId; VTagPair key; sctpEV3<<"Number of Assocs: "<<sctpVTagMap.size()<<"\n"; if (sctpVTagMap.size()>0) { for (SctpVTagMap::iterator i = sctpVTagMap.begin(); i!=sctpVTagMap.end(); ++i) { assocId = i->first; key = i->second; sctpEV3<<"assocId: "<<assocId<<" peerVTag: "<<key.peerVTag<< " localVTag: "<<key.localVTag<< " localPort: "<<key.localPort<<" rPort: "<<key.remotePort<<"\n"; } sctpEV3<<"\n"; } }
void SCTP::removeAssociation | ( | SCTPAssociation * | assoc | ) |
Definition at line 740 of file SCTP.cc.
Referenced by finish(), handleMessage(), SCTPAssociation::process_RCV_Message(), SCTPAssociation::process_TIMEOUT_HEARTBEAT(), SCTPAssociation::process_TIMEOUT_INIT_REXMIT(), SCTPAssociation::process_TIMEOUT_RTX(), SCTPAssociation::process_TIMEOUT_SHUTDOWN(), SCTPAssociation::processTimer(), and SCTPAssociation::updateCounters().
{ bool ok = false; bool find = false; const int32 id = conn->assocId; sctpEV3 << "Deleting SCTP connection " << conn << " id= "<< id << endl; printInfoConnMap(); if (sizeConnMap > 0) { AssocStatMap::iterator assocStatMapIterator = assocStatMap.find(conn->assocId); if (assocStatMapIterator != assocStatMap.end()) { assocStatMapIterator->second.stop = simulation.getSimTime(); assocStatMapIterator->second.lifeTime = assocStatMapIterator->second.stop - assocStatMapIterator->second.start; assocStatMapIterator->second.throughput = assocStatMapIterator->second.ackedBytes*8 / assocStatMapIterator->second.lifeTime.dbl(); } while (!ok) { if (sizeConnMap == 0) { ok = true; } else { for (SctpConnMap::iterator sctpConnMapIterator = sctpConnMap.begin(); sctpConnMapIterator != sctpConnMap.end(); sctpConnMapIterator++) { if (sctpConnMapIterator->second != NULL) { SCTPAssociation* assoc = sctpConnMapIterator->second; if (assoc->assocId == conn->assocId) { if (assoc->T1_InitTimer) { assoc->stopTimer(assoc->T1_InitTimer); } if (assoc->T2_ShutdownTimer) { assoc->stopTimer(assoc->T2_ShutdownTimer); } if (assoc->T5_ShutdownGuardTimer) { assoc->stopTimer(assoc->T5_ShutdownGuardTimer); } if (assoc->SackTimer) { assoc->stopTimer(assoc->SackTimer); } sctpConnMap.erase(sctpConnMapIterator); sizeConnMap--; find = true; break; } } } } if (!find) { ok = true; } else { find = false; } } } // T.D. 26.11.09: Write statistics char str[128]; for (SCTPAssociation::SCTPPathMap::iterator pathMapIterator = conn->sctpPathMap.begin(); pathMapIterator != conn->sctpPathMap.end(); pathMapIterator++) { const SCTPPathVariables* path = pathMapIterator->second; snprintf((char*)&str, sizeof(str), "Number of Fast Retransmissions %d:%s", conn->assocId, path->remoteAddress.str().c_str()); recordScalar(str, path->numberOfFastRetransmissions); snprintf((char*)&str, sizeof(str), "Number of Timer-Based Retransmissions %d:%s", conn->assocId, path->remoteAddress.str().c_str()); recordScalar(str, path->numberOfTimerBasedRetransmissions); snprintf((char*)&str, sizeof(str), "Number of Heartbeats Sent %d:%s", conn->assocId, path->remoteAddress.str().c_str()); recordScalar(str, path->numberOfHeartbeatsSent); snprintf((char*)&str, sizeof(str), "Number of Heartbeats Received %d:%s", conn->assocId, path->remoteAddress.str().c_str()); recordScalar(str, path->numberOfHeartbeatsRcvd); snprintf((char*)&str, sizeof(str), "Number of Heartbeat ACKs Sent %d:%s", conn->assocId, path->remoteAddress.str().c_str()); recordScalar(str, path->numberOfHeartbeatAcksSent); snprintf((char*)&str, sizeof(str), "Number of Heartbeat ACKs Received %d:%s", conn->assocId, path->remoteAddress.str().c_str()); recordScalar(str, path->numberOfHeartbeatAcksRcvd); } conn->removePath(); conn->deleteStreams(); // TD 20.11.09: Chunks may be in the transmission and retransmission queues simultaneously. // Remove entry from transmission queue if it is already in the retransmission queue. for (SCTPQueue::PayloadQueue::iterator i = conn->getRetransmissionQueue()->payloadQueue.begin(); i != conn->getRetransmissionQueue()->payloadQueue.end(); i++) { SCTPQueue::PayloadQueue::iterator j = conn->getTransmissionQueue()->payloadQueue.find(i->second->tsn); if(j != conn->getTransmissionQueue()->payloadQueue.end()) { conn->getTransmissionQueue()->payloadQueue.erase(j); } } // TD 20.11.09: Now, both queues can be safely deleted. delete conn->getRetransmissionQueue(); delete conn->getTransmissionQueue(); AppConnKey key; key.appGateIndex = conn->appGateIndex; key.assocId = conn->assocId; sctpAppConnMap.erase(key); assocList.remove(conn); delete conn; }
void SCTP::removeLocalAddressFromAllRemoteAddresses | ( | SCTPAssociation * | conn, | |
IPvXAddress | address, | |||
std::vector< IPvXAddress > | remAddresses | |||
) |
Definition at line 618 of file SCTP.cc.
{ //sctpEV3<<"Remove local address: "<<address<<"\n"; SockPair key; for (AddressVector::iterator i=remAddresses.begin(); i!=remAddresses.end(); ++i) { //sctpEV3<<"remote address="<<(*i)<<"\n"; key.localAddr = address; key.remoteAddr = (*i); key.localPort = conn->localPort; key.remotePort = conn->remotePort; SctpConnMap::iterator j = sctpConnMap.find(key); if (j!=sctpConnMap.end()) { ASSERT(j->second==conn); sctpConnMap.erase(j); sizeConnMap--; } else sctpEV3<<"no actual sockPair found\n"; //sctpEV3<<"number of connections="<<sctpConnMap.size()<<"\n"; printInfoConnMap(); } }
void SCTP::removeRemoteAddressFromAllConnections | ( | SCTPAssociation * | conn, | |
IPvXAddress | address, | |||
std::vector< IPvXAddress > | locAddresses | |||
) |
Definition at line 649 of file SCTP.cc.
{ //sctpEV3<<"Remove remote address: "<<address<<"\n"; SockPair key; for (AddressVector::iterator i=locAddresses.begin(); i!=locAddresses.end(); i++) { //sctpEV3<<"local address="<<(*i)<<"\n"; key.localAddr = (*i); key.remoteAddr = address; key.localPort = conn->localPort; key.remotePort = conn->remotePort; SctpConnMap::iterator j = sctpConnMap.find(key); if (j!=sctpConnMap.end()) { ASSERT(j->second==conn); sctpConnMap.erase(j); sizeConnMap--; } else sctpEV3<<"no actual sockPair found\n"; //sctpEV3<<"number of connections="<<sctpConnMap.size()<<"\n"; printInfoConnMap(); } }
void SCTP::sendAbortFromMain | ( | SCTPMessage * | sctpmsg, | |
IPvXAddress | srcAddr, | |||
IPvXAddress | destAddr | |||
) | [protected] |
Definition at line 320 of file SCTP.cc.
Referenced by handleMessage().
{ SCTPMessage *msg = new SCTPMessage(); sctpEV3<<"\n\nSCTPMain:sendABORT \n"; msg->setSrcPort(sctpmsg->getDestPort()); msg->setDestPort(sctpmsg->getSrcPort()); msg->setBitLength(SCTP_COMMON_HEADER*8); msg->setChecksumOk(true); SCTPAbortChunk* abortChunk = new SCTPAbortChunk("ABORT"); abortChunk->setChunkType(ABORT); if (sctpmsg->getChunksArraySize()>0 && ((SCTPChunk*)(sctpmsg->getChunks(0)))->getChunkType()==INIT) { SCTPInitChunk* initChunk = check_and_cast<SCTPInitChunk *>(sctpmsg->getChunks(0)); abortChunk->setT_Bit(0); msg->setTag(initChunk->getInitTag()); } else { abortChunk->setT_Bit(1); msg->setTag(sctpmsg->getTag()); } abortChunk->setBitLength(SCTP_ABORT_CHUNK_LENGTH*8); msg->addChunk(abortChunk); if ((bool)par("udpEncapsEnabled")) { msg->setKind(UDP_C_DATA); std::cout<<"VTag="<<msg->getTag()<<"\n"; UDPControlInfo *ctrl = new UDPControlInfo(); ctrl->setSrcPort(9899); ctrl->setDestAddr(destAddr.get4()); ctrl->setDestPort(9899); msg->setControlInfo(ctrl); } else { IPControlInfo *controlInfo = new IPControlInfo(); controlInfo->setProtocol(IP_PROT_SCTP); controlInfo->setSrcAddr(srcAddr.get4()); controlInfo->setDestAddr(destAddr.get4()); msg->setControlInfo(controlInfo); } send(msg,"to_ip"); }
void SCTP::sendShutdownCompleteFromMain | ( | SCTPMessage * | sctpmsg, | |
IPvXAddress | srcAddr, | |||
IPvXAddress | destAddr | |||
) | [protected] |
Definition at line 368 of file SCTP.cc.
Referenced by handleMessage().
{ SCTPMessage *msg = new SCTPMessage(); sctpEV3<<"\n\nSCTP:sendABORT \n"; msg->setSrcPort(sctpmsg->getDestPort()); msg->setDestPort(sctpmsg->getSrcPort()); msg->setBitLength(SCTP_COMMON_HEADER*8); msg->setChecksumOk(true); SCTPShutdownCompleteChunk* scChunk = new SCTPShutdownCompleteChunk("SHUTDOWN_COMPLETE"); scChunk->setChunkType(SHUTDOWN_COMPLETE); scChunk->setTBit(1); msg->setTag(sctpmsg->getTag()); scChunk->setBitLength(SCTP_SHUTDOWN_ACK_LENGTH*8); msg->addChunk(scChunk); IPControlInfo *controlInfo = new IPControlInfo(); controlInfo->setProtocol(IP_PROT_SCTP); controlInfo->setSrcAddr(srcAddr.get4()); controlInfo->setDestAddr(destAddr.get4()); msg->setControlInfo(controlInfo); send(msg,"to_ip"); }
void SCTP::updateDisplayString | ( | ) | [protected] |
Definition at line 395 of file SCTP.cc.
Referenced by handleMessage().
{ if (ev.disable_tracing) { // in express mode, we don't bother to update the display // (std::map's iteration is not very fast if map is large) getDisplayString().setTagArg("t",0,""); return; } }
void SCTP::updateSockPair | ( | SCTPAssociation * | assoc, | |
IPvXAddress | localAddr, | |||
IPvXAddress | remoteAddr, | |||
int32 | localPort, | |||
int32 | remotePort | |||
) |
To be called from SCTPAssociation when socket pair changes
Definition at line 518 of file SCTP.cc.
Referenced by addForkedAssociation(), SCTPAssociation::process_ASSOCIATE(), SCTPAssociation::process_OPEN_PASSIVE(), and SCTPAssociation::processInitArrived().
{ SockPair key; sctpEV3<<"updateSockPair: localAddr: "<<localAddr<<" remoteAddr="<<remoteAddr<<" localPort="<<localPort<<" remotePort="<<remotePort<<"\n"; key.localAddr = (conn->localAddr = localAddr); key.remoteAddr = (conn->remoteAddr = remoteAddr); key.localPort = conn->localPort = localPort; key.remotePort = conn->remotePort = remotePort; for (SctpConnMap::iterator i=sctpConnMap.begin(); i!=sctpConnMap.end(); i++) { if (i->second == conn) { sctpConnMap.erase(i); break; } } sctpEV3<<"updateSockPair conn="<<conn<<" localAddr="<<key.localAddr<<" remoteAddr="<<key.remoteAddr<<" localPort="<<key.localPort<<" remotePort="<<remotePort<<"\n"; sctpConnMap[key] = conn; sizeConnMap = sctpConnMap.size(); //sctpEV3<<"number of connections="<<sctpConnMap.size()<<"\n"; sctpEV3<<"assoc inserted in sctpConnMap\n"; printInfoConnMap(); }
std::list<SCTPAssociation*> SCTP::assocList |
Definition at line 167 of file SCTP.h.
Referenced by handleMessage(), removeAssociation(), SCTPAssociation::sendInit(), and SCTPAssociation::sendInitAck().
Definition at line 156 of file SCTP.h.
Referenced by finish(), SCTPAssociation::pathStatusIndication(), SCTPAssociation::process_SEND(), SCTPAssociation::process_TIMEOUT_RTX(), SCTPAssociation::processDataArrived(), removeAssociation(), SCTPAssociation::sendOnPath(), SCTPAssociation::stateEntered(), and ~SCTP().
bool SCTP::logverbose [static] |
int32 SCTP::nextConnId = 0 [static, protected] |
uint16 SCTP::nextEphemeralPort [protected] |
Definition at line 172 of file SCTP.h.
Referenced by getEphemeralPort(), and initialize().
uint32 SCTP::numGapReports |
uint32 SCTP::numPacketsDropped |
Definition at line 190 of file SCTP.h.
Referenced by finish(), handleMessage(), and initialize().
uint32 SCTP::numPacketsReceived |
Definition at line 189 of file SCTP.h.
Referenced by finish(), handleMessage(), and initialize().
Definition at line 165 of file SCTP.h.
Referenced by addForkedAssociation(), findAssocForApp(), getAssoc(), handleMessage(), removeAssociation(), and ~SCTP().
Definition at line 166 of file SCTP.h.
Referenced by addForkedAssociation(), addLocalAddress(), addLocalAddressToAllRemoteAddresses(), addRemoteAddress(), findAssocForMessage(), finish(), handleMessage(), printInfoConnMap(), removeAssociation(), removeLocalAddressFromAllRemoteAddresses(), removeRemoteAddressFromAllConnections(), and updateSockPair().
Definition at line 158 of file SCTP.h.
Referenced by findAssocWithVTag(), printVTagMap(), SCTPAssociation::stateEntered(), and ~SCTP().
int32 SCTP::sizeConnMap [protected] |
Definition at line 169 of file SCTP.h.
Referenced by addLocalAddress(), addLocalAddressToAllRemoteAddresses(), addRemoteAddress(), initialize(), printInfoConnMap(), removeAssociation(), removeLocalAddressFromAllRemoteAddresses(), removeRemoteAddressFromAllConnections(), and updateSockPair().
bool SCTP::testing [static] |
Definition at line 181 of file SCTP.h.
Referenced by initialize(), and SCTPAssociation::processTimer().
simtime_t SCTP::testTimeout |
Definition at line 187 of file SCTP.h.
Referenced by initialize(), and SCTPAssociation::SCTPAssociation().