INET Framework for OMNeT++/OMNEST
inet::sctp::SCTP Class Reference

Implements the SCTP protocol. More...

#include <SCTP.h>

Inheritance diagram for inet::sctp::SCTP:

Classes

struct  AppAssocKey
 
struct  AssocStat
 
struct  SockPair
 
struct  VTagPair
 

Public Types

typedef std::map< int32, AssocStatAssocStatMap
 
typedef std::map< int32, VTagPairSctpVTagMap
 
typedef std::map< AppAssocKey, SCTPAssociation * > SctpAppAssocMap
 
typedef std::map< SockPair, SCTPAssociation * > SctpAssocMap
 

Public Member Functions

void printInfoAssocMap ()
 
void printVTagMap ()
 
void removeAssociation (SCTPAssociation *assoc)
 
virtual ~SCTP ()
 
virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void finish () override
 
virtual void send_to_ip (SCTPMessage *msg)
 
AssocStatgetAssocStat (uint32 assocId)
 
void updateSockPair (SCTPAssociation *assoc, L3Address localAddr, L3Address remoteAddr, int32 localPort, int32 remotePort)
 To be called from SCTPAssociation when socket pair changes. More...
 
void addLocalAddress (SCTPAssociation *assoc, L3Address address)
 
void addLocalAddressToAllRemoteAddresses (SCTPAssociation *assoc, L3Address address, std::vector< L3Address > remAddresses)
 
bool addRemoteAddress (SCTPAssociation *assoc, L3Address localAddress, L3Address remoteAddress)
 
void removeLocalAddressFromAllRemoteAddresses (SCTPAssociation *assoc, L3Address address, std::vector< L3Address > remAddresses)
 
void removeRemoteAddressFromAllAssociations (SCTPAssociation *assoc, L3Address address, std::vector< L3Address > locAddresses)
 
void addForkedAssociation (SCTPAssociation *assoc, SCTPAssociation *newAssoc, L3Address localAddr, L3Address remoteAddr, int32 localPort, int32 remotePort)
 Update assocs socket pair, and register newAssoc (which'll keep LISTENing). More...
 
uint16 getEphemeralPort ()
 To be called from SCTPAssociation: reserves an ephemeral port for the connection. More...
 
SCTPAssociationgetAssoc (int32 assocId)
 
SCTPAssociationfindAssocWithVTag (uint32 peerVTag, uint32 remotePort, uint32 localPort)
 
SCTPAssociationfindAssocForInitAck (SCTPInitAckChunk *initack, L3Address srcAddr, L3Address destAddr, uint32 srcPort, uint32 destPort, bool findListen)
 
SctpVTagMap getVTagMap ()
 
void bindPortForUDP ()
 
SocketOptionscollectSocketOptions ()
 Getter and Setter for the socket options. More...
 
void setSocketOptions (SocketOptions *options)
 
int getMaxInitRetrans ()
 
int getMaxInitRetransTimeout ()
 
double getRtoInitial ()
 
double getRtoMin ()
 
double getRtoMax ()
 
int getSackFrequency ()
 
double getSackPeriod ()
 
int getMaxBurst ()
 
int getFragPoint ()
 
int getNagle ()
 
bool getEnableHeartbeats ()
 
int getPathMaxRetrans ()
 
int getAssocMaxRtx ()
 
double getHbInterval ()
 
void setRtoInitial (double rtoInitial)
 
void setRtoMin (double rtoMin)
 
void setRtoMax (double rtoMax)
 

Public Attributes

AssocStatMap assocStatMap
 
SctpVTagMap sctpVTagMap
 
SctpAppAssocMap sctpAppAssocMap
 
SctpAssocMap sctpAssocMap
 
std::list< SCTPAssociation * > assocList
 
UDPSocket udpSocket
 
SocketOptionssocketOptions
 
simtime_t testTimeout
 
uint32 numGapReports
 
uint32 numPacketsReceived
 
uint32 numPacketsDropped
 
bool auth
 
bool addIP
 
bool pktdrop
 
bool sackNow
 
uint64 numPktDropReports
 

Protected Member Functions

SCTPAssociationfindAssocForMessage (L3Address srcAddr, L3Address destAddr, uint32 srcPort, uint32 destPort, bool findListen)
 
SCTPAssociationfindAssocForApp (int32 appGateIndex, int32 assocId)
 
int32 findAssocForFd (int32 fd)
 
void sendAbortFromMain (SCTPMessage *sctpmsg, L3Address fromAddr, L3Address toAddr)
 
void sendShutdownCompleteFromMain (SCTPMessage *sctpmsg, L3Address fromAddr, L3Address toAddr)
 
virtual void refreshDisplay () const override
 

Protected Attributes

IRoutingTablert
 
IInterfaceTableift
 
int32 sizeAssocMap
 
uint16 nextEphemeralPort
 

Detailed Description

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: the module class
  • SCTPAssociation: manages an association
  • SCTPSendQueue, SCTPReceiveQueue: abstract base classes for various types of send and receive queues
  • SCTPAlgorithm: abstract base class for SCTP algorithms

SCTP subclassed from cSimpleModule. It manages socketpair-to-association mapping, and dispatches segments and user commands to the appropriate SCTPAssociation object.

SCTPAssociation manages the association, 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 association (in OPEN) or in a module parameter.

Member Typedef Documentation

Constructor & Destructor Documentation

inet::sctp::SCTP::~SCTP ( )
virtual
119 {
120  EV_DEBUG << "delete SCTPMain\n";
121  if (!(sctpAppAssocMap.empty())) {
122  EV_DEBUG << "clear appConnMap ptr=" << &sctpAppAssocMap << "\n";
123  sctpAppAssocMap.clear();
124  }
125  if (!(assocStatMap.empty())) {
126  EV_DEBUG << "clear assocStatMap ptr=" << &assocStatMap << "\n";
127  assocStatMap.clear();
128  }
129  if (!(sctpVTagMap.empty())) {
130  sctpVTagMap.clear();
131  }
132  EV_DEBUG << "after clearing maps\n";
133 }
SctpAppAssocMap sctpAppAssocMap
Definition: SCTP.h:178
SctpVTagMap sctpVTagMap
Definition: SCTP.h:173
AssocStatMap assocStatMap
Definition: SCTP.h:171

Member Function Documentation

void inet::sctp::SCTP::addForkedAssociation ( SCTPAssociation assoc,
SCTPAssociation newAssoc,
L3Address  localAddr,
L3Address  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).

Referenced by inet::sctp::SCTPAssociation::processInitArrived().

763 {
764  SockPair keyAssoc;
765  bool found = false;
766 
767  EV_INFO << "addForkedConnection assocId=" << assoc->assocId << " newId=" << newAssoc->assocId << "\n";
768 
769  for (auto & elem : sctpAssocMap) {
770  if (assoc->assocId == elem.second->assocId) {
771  keyAssoc = elem.first;
772  found = true;
773  break;
774  }
775  }
776 
777  ASSERT(found == true);
778 
779  // update assoc's socket pair, and register newAssoc (which'll keep LISTENing)
780  updateSockPair(assoc, localAddr, remoteAddr, localPort, remotePort);
781  updateSockPair(newAssoc, keyAssoc.localAddr, keyAssoc.remoteAddr, keyAssoc.localPort, keyAssoc.remotePort);
782 
783  // assoc will get a new assocId...
784  AppAssocKey key;
785  key.appGateIndex = assoc->appGateIndex;
786  key.assocId = assoc->assocId;
787  sctpAppAssocMap.erase(key);
788  key.assocId = assoc->assocId = SCTPSocket::getNewAssocId();
789  sctpAppAssocMap[key] = assoc;
790 
791  // ...and newAssoc will live on with the old assocId
792  key.appGateIndex = newAssoc->appGateIndex;
793  key.assocId = newAssoc->assocId;
794  sctpAppAssocMap[key] = newAssoc;
795  sizeAssocMap = sctpAssocMap.size();
797 }
void printInfoAssocMap()
Definition: SCTP.cc:42
static int32 getNewAssocId()
Generates a new integer, to be used as assocId.
Definition: SCTPSocket.h:147
int32 sizeAssocMap
Definition: SCTP.h:190
SctpAppAssocMap sctpAppAssocMap
Definition: SCTP.h:178
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179
void updateSockPair(SCTPAssociation *assoc, L3Address localAddr, L3Address remoteAddr, int32 localPort, int32 remotePort)
To be called from SCTPAssociation when socket pair changes.
Definition: SCTP.cc:599
void inet::sctp::SCTP::addLocalAddress ( SCTPAssociation assoc,
L3Address  address 
)

Referenced by inet::sctp::SCTPAssociation::processInitArrived(), and inet::sctp::SCTPAssociation::sendInit().

635 {
636  SockPair key;
637 
638  key.localAddr = assoc->localAddr;
639  key.remoteAddr = assoc->remoteAddr;
640  key.localPort = assoc->localPort;
641  key.remotePort = assoc->remotePort;
642 
643  auto i = sctpAssocMap.find(key);
644  if (i != sctpAssocMap.end()) {
645  ASSERT(i->second == assoc);
646  if (key.localAddr.isUnspecified()) {
647  sctpAssocMap.erase(i);
648  sizeAssocMap--;
649  }
650  }
651  else
652  EV_INFO << "no actual sockPair found\n";
653  key.localAddr = address;
654  sctpAssocMap[key] = assoc;
655  sizeAssocMap = sctpAssocMap.size();
656  EV_INFO << "addLocalAddress " << address << " number of connections now=" << sizeAssocMap << "\n";
657 
659 }
void printInfoAssocMap()
Definition: SCTP.cc:42
int32 sizeAssocMap
Definition: SCTP.h:190
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179
void inet::sctp::SCTP::addLocalAddressToAllRemoteAddresses ( SCTPAssociation assoc,
L3Address  address,
std::vector< L3Address remAddresses 
)

Referenced by inet::sctp::SCTPAssociation::processAsconfAckArrived(), and inet::sctp::SCTPAssociation::sendAsconf().

662 {
663  SockPair key;
664 
665  for (auto & remAddresse : remAddresses) {
666  //EV_DEBUG<<"remote address="<<(*i)<<"\n";
667  key.localAddr = assoc->localAddr;
668  key.remoteAddr = (remAddresse);
669  key.localPort = assoc->localPort;
670  key.remotePort = assoc->remotePort;
671 
672  auto j = sctpAssocMap.find(key);
673  if (j != sctpAssocMap.end()) {
674  ASSERT(j->second == assoc);
675  if (key.localAddr.isUnspecified()) {
676  sctpAssocMap.erase(j);
677  sizeAssocMap--;
678  }
679  }
680  else
681  EV_INFO << "no actual sockPair found\n";
682  key.localAddr = address;
683  sctpAssocMap[key] = assoc;
684 
685  sizeAssocMap++;
686  EV_DEBUG << "number of connections=" << sctpAssocMap.size() << "\n";
687 
689  }
690 }
void printInfoAssocMap()
Definition: SCTP.cc:42
int32 sizeAssocMap
Definition: SCTP.h:190
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179
bool inet::sctp::SCTP::addRemoteAddress ( SCTPAssociation assoc,
L3Address  localAddress,
L3Address  remoteAddress 
)

Referenced by inet::sctp::SCTPAssociation::processAsconfArrived(), inet::sctp::SCTPAssociation::processInitAckArrived(), and inet::sctp::SCTPAssociation::processInitArrived().

739 {
740  EV_INFO << "Add remote Address: " << remoteAddress << " to local Address " << localAddress << "\n";
741 
742  SockPair key;
743  key.localAddr = localAddress;
744  key.remoteAddr = remoteAddress;
745  key.localPort = assoc->localPort;
746  key.remotePort = assoc->remotePort;
747 
748  auto i = sctpAssocMap.find(key);
749  if (i != sctpAssocMap.end()) {
750  ASSERT(i->second == assoc);
751  return false;
752  }
753  else {
754  sctpAssocMap[key] = assoc;
755  sizeAssocMap++;
756  }
757 
759  return true;
760 }
void printInfoAssocMap()
Definition: SCTP.cc:42
int32 sizeAssocMap
Definition: SCTP.h:190
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179
void inet::sctp::SCTP::bindPortForUDP ( )

Referenced by initialize().

79 {
80  EV_INFO << "Binding to UDP port " << SCTP_UDP_PORT << endl;
81 
82  udpSocket.setOutputGate(gate("to_ip"));
84 }
UDPSocket udpSocket
Definition: SCTP.h:182
void setOutputGate(cGate *toUdp)
Sets the gate on which to send to UDP.
Definition: UDPSocket.h:110
#define SCTP_UDP_PORT
Definition: SCTP.h:41
void bind(int localPort)
Bind the socket to a local port number.
Definition: UDPSocket.cc:53
SocketOptions * inet::sctp::SCTP::collectSocketOptions ( )

Getter and Setter for the socket options.

Referenced by handleMessage().

306 {
307  SocketOptions* sockOptions = new SocketOptions();
308  sockOptions->maxInitRetrans = (int) par("maxInitRetrans");
309  sockOptions->maxInitRetransTimeout = SCTP_TIMEOUT_INIT_REXMIT_MAX;
310  sockOptions->rtoInitial = (int) par("rtoInitial");
311  sockOptions->rtoMin = (int) par("rtoMin");
312  sockOptions->rtoMax = (int) par("rtoMax");
313  sockOptions->sackFrequency = (int) par("sackFrequency");
314  sockOptions->sackPeriod = (double) par("sackPeriod");
315  sockOptions->maxBurst = (int) par("maxBurst");
316  sockOptions->fragPoint = (int) par("fragPoint");
317  sockOptions->nagle = ((bool) par("nagleEnabled")) ? 1 : 0;
318  sockOptions->enableHeartbeats = (bool) par("enableHeartbeats");
319  sockOptions->pathMaxRetrans = (int) par("pathMaxRetrans");
320  sockOptions->hbInterval = (double) par("hbInterval");
321  sockOptions->assocMaxRtx = (int) par("assocMaxRetrans");
322  return sockOptions;
323 }
#define SCTP_TIMEOUT_INIT_REXMIT_MAX
Definition: SCTPAssociation.h:247
SCTPAssociation * inet::sctp::SCTP::findAssocForApp ( int32  appGateIndex,
int32  assocId 
)
protected

Referenced by handleMessage().

571 {
572  AppAssocKey key;
573  key.appGateIndex = appGateIndex;
574  key.assocId = assocId;
575  EV_INFO << "findAssoc for appGateIndex " << appGateIndex << " and assoc " << assocId << "\n";
576  auto i = sctpAppAssocMap.find(key);
577  return (i == sctpAppAssocMap.end()) ? nullptr : i->second;
578 }
SctpAppAssocMap sctpAppAssocMap
Definition: SCTP.h:178
int32 inet::sctp::SCTP::findAssocForFd ( int32  fd)
protected

Referenced by handleMessage().

581 {
582  SCTPAssociation *assoc = NULL;
583  for (auto & elem : sctpAppAssocMap) {
584  assoc = elem.second;
585  if (assoc->fd == fd)
586  return assoc->assocId;
587  }
588  return -1;
589 }
SctpAppAssocMap sctpAppAssocMap
Definition: SCTP.h:178
SCTPAssociation * inet::sctp::SCTP::findAssocForInitAck ( SCTPInitAckChunk initack,
L3Address  srcAddr,
L3Address  destAddr,
uint32  srcPort,
uint32  destPort,
bool  findListen 
)

Referenced by handleMessage().

504 {
505  SCTPAssociation *assoc = nullptr;
506  int numberAddresses = initAckChunk->getAddressesArraySize();
507  for (int32 j = 0; j < numberAddresses; j++) {
508  if (initAckChunk->getAddresses(j).getType() == L3Address::IPv6)
509  continue;
510  assoc = findAssocForMessage(initAckChunk->getAddresses(j), destAddr, srcPort, destPort, findListen);
511  if (assoc) {
512  break;
513  }
514  }
515  return assoc;
516 }
Definition: L3Address.h:47
SCTPAssociation * findAssocForMessage(L3Address srcAddr, L3Address destAddr, uint32 srcPort, uint32 destPort, bool findListen)
Definition: SCTP.cc:519
int32_t int32
Definition: Compat.h:31
SCTPAssociation * inet::sctp::SCTP::findAssocForMessage ( L3Address  srcAddr,
L3Address  destAddr,
uint32  srcPort,
uint32  destPort,
bool  findListen 
)
protected

Referenced by findAssocForInitAck(), and handleMessage().

520 {
521  SockPair key;
522 
523  key.localAddr = destAddr;
524  key.remoteAddr = srcAddr;
525  key.localPort = destPort;
526  key.remotePort = srcPort;
527  SockPair save = key;
528  EV_DEBUG << "findAssocForMessage: srcAddr=" << destAddr << " destAddr=" << srcAddr << " srcPort=" << destPort << " destPort=" << srcPort << "\n";
530 
531  // try with fully qualified SockPair
532  auto i = sctpAssocMap.find(key);
533  if (i != sctpAssocMap.end())
534  return i->second;
535 
536  // try with localAddr missing (only localPort specified in passive/active open)
537  key.localAddr = L3Address();
538 
539  i = sctpAssocMap.find(key);
540  if (i != sctpAssocMap.end()) {
541  // try with localAddr missing (only localPort specified in passive/active open)
542  return i->second;
543  }
544 
545  if (findListen == true) {
546  // try fully qualified local socket + blank remote socket (for incoming SYN)
547  key = save;
548  key.remoteAddr = L3Address();
549  key.remotePort = 0;
550  i = sctpAssocMap.find(key);
551  if (i != sctpAssocMap.end()) {
552  // try fully qualified local socket + blank remote socket
553  return i->second;
554  }
555 
556  // try with blank remote socket, and localAddr missing (for incoming SYN)
557  key.localAddr = L3Address();
558  i = sctpAssocMap.find(key);
559  if (i != sctpAssocMap.end()) {
560  // try with blank remote socket, and localAddr missing
561  return i->second;
562  }
563  }
564  // given up
565 
566  EV_INFO << "giving up on trying to find assoc for localAddr=" << srcAddr << " remoteAddr=" << destAddr << " localPort=" << srcPort << " remotePort=" << destPort << "\n";
567  return nullptr;
568 }
void printInfoAssocMap()
Definition: SCTP.cc:42
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179
SCTPAssociation * inet::sctp::SCTP::findAssocWithVTag ( uint32  peerVTag,
uint32  remotePort,
uint32  localPort 
)

Referenced by handleMessage().

487 {
488  printVTagMap();
489  EV_DEBUG << "findAssocWithVTag: peerVTag=" << peerVTag << " srcPort=" << remotePort << " destPort=" << localPort << "\n";
491 
492  // try with fully qualified SockPair
493  for (auto & elem : sctpVTagMap) {
494  if ((elem.second.peerVTag == peerVTag && elem.second.localPort == localPort
495  && elem.second.remotePort == remotePort)
496  || (elem.second.localVTag == peerVTag && elem.second.localPort == localPort
497  && elem.second.remotePort == remotePort))
498  return getAssoc(elem.first);
499  }
500  return nullptr;
501 }
void printInfoAssocMap()
Definition: SCTP.cc:42
SCTPAssociation * getAssoc(int32 assocId)
Definition: SCTP.cc:921
SctpVTagMap sctpVTagMap
Definition: SCTP.h:173
void printVTagMap()
Definition: SCTP.cc:59
void inet::sctp::SCTP::finish ( )
overridevirtual
931 {
932  auto assocMapIterator = sctpAssocMap.begin();
933  while (assocMapIterator != sctpAssocMap.end()) {
934  removeAssociation(assocMapIterator->second);
935  assocMapIterator = sctpAssocMap.begin();
936  }
937  EV_INFO << getFullPath() << ": finishing SCTP with "
938  << sctpAssocMap.size() << " connections open." << endl;
939 
940  for (AssocStatMap::const_iterator iterator = assocStatMap.begin();
941  iterator != assocStatMap.end(); iterator++)
942  {
943  const SCTP::AssocStat& assoc = iterator->second;
944 
945  EV_DETAIL << "Association " << assoc.assocId << ": started at " << assoc.start
946  << " and finished at " << assoc.stop << " --> lifetime: " << assoc.lifeTime << endl;
947  EV_DETAIL << "Association " << assoc.assocId << ": sent bytes=" << assoc.sentBytes
948  << ", acked bytes=" << assoc.ackedBytes << ", throughput=" << assoc.throughput << " bit/s" << endl;
949  EV_DETAIL << "Association " << assoc.assocId << ": transmitted Bytes="
950  << assoc.transmittedBytes << ", retransmitted Bytes=" << assoc.transmittedBytes - assoc.ackedBytes << endl;
951  EV_DETAIL << "Association " << assoc.assocId << ": number of Fast RTX="
952  << assoc.numFastRtx << ", number of Timer-Based RTX=" << assoc.numT3Rtx
953  << ", path failures=" << assoc.numPathFailures << ", ForwardTsns=" << assoc.numForwardTsn << endl;
954  EV_DETAIL << "AllMessages=" << numPacketsReceived << " BadMessages=" << numPacketsDropped << endl;
955 
956  recordScalar("Association Lifetime", assoc.lifeTime);
957  recordScalar("Acked Bytes", assoc.ackedBytes);
958  recordScalar("Throughput [bit/s]", assoc.throughput);
959  recordScalar("Transmitted Bytes", assoc.transmittedBytes);
960  recordScalar("Fast RTX", assoc.numFastRtx);
961  recordScalar("Timer-Based RTX", assoc.numT3Rtx);
962  recordScalar("Duplicate Acks", assoc.numDups);
963  recordScalar("Packets Received", numPacketsReceived);
964  recordScalar("Packets Dropped", numPacketsDropped);
965  recordScalar("Sum of R Gap Ranges", assoc.sumRGapRanges);
966  recordScalar("Sum of NR Gap Ranges", assoc.sumNRGapRanges);
967  recordScalar("Overfull SACKs", assoc.numOverfullSACKs);
968  recordScalar("Drops Because New TSN Greater Than Highest TSN", assoc.numDropsBecauseNewTSNGreaterThanHighestTSN);
969  recordScalar("Drops Because No Room In Buffer", assoc.numDropsBecauseNoRoomInBuffer);
970  recordScalar("Chunks Reneged", assoc.numChunksReneged);
971  recordScalar("sackPeriod", (simtime_t)socketOptions->sackPeriod);
972  recordScalar("Number of AUTH chunks sent", assoc.numAuthChunksSent);
973  recordScalar("Number of AUTH chunks accepted", assoc.numAuthChunksAccepted);
974  recordScalar("Number of AUTH chunks rejected", assoc.numAuthChunksRejected);
975  recordScalar("Number of StreamReset requests sent", assoc.numResetRequestsSent);
976  recordScalar("Number of StreamReset requests performed", assoc.numResetRequestsPerformed);
977  if ((double)par("fairStart") > 0) {
978  recordScalar("fair acked bytes", assoc.fairAckedBytes);
979  recordScalar("fair start time", assoc.fairStart);
980  recordScalar("fair stop time", assoc.fairStop);
981  recordScalar("fair lifetime", assoc.fairLifeTime);
982  recordScalar("fair throughput", assoc.fairThroughput);
983  }
984  recordScalar("Number of PacketDrop Reports", numPktDropReports);
985 
986  if (assoc.numEndToEndMessages > 0 && (assoc.cumEndToEndDelay / assoc.numEndToEndMessages) > 0) {
987  uint32 msgnum = assoc.numEndToEndMessages - assoc.startEndToEndDelay;
988  if (assoc.stopEndToEndDelay > 0)
989  msgnum -= (assoc.numEndToEndMessages - assoc.stopEndToEndDelay);
990  recordScalar("Average End to End Delay", assoc.cumEndToEndDelay / msgnum);
991  }
992 
993  recordScalar("RTXMethod", (double)par("RTXMethod"));
994  }
995 }
SocketOptions * socketOptions
Definition: SCTP.h:184
void removeAssociation(SCTPAssociation *assoc)
Definition: SCTP.cc:799
AssocStatMap assocStatMap
Definition: SCTP.h:171
uint32 numPacketsReceived
Definition: SCTP.h:208
uint32 numPacketsDropped
Definition: SCTP.h:209
uint32_t uint32
Definition: Compat.h:30
double sackPeriod
Definition: SCTPSocket.h:40
uint64 numPktDropReports
Definition: SCTP.h:214
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179
SCTPAssociation * inet::sctp::SCTP::getAssoc ( int32  assocId)

Referenced by findAssocWithVTag().

922 {
923  for (auto & elem : sctpAppAssocMap) {
924  if (elem.first.assocId == assocId)
925  return elem.second;
926  }
927  return nullptr;
928 }
SctpAppAssocMap sctpAppAssocMap
Definition: SCTP.h:178
AssocStat* inet::sctp::SCTP::getAssocStat ( uint32  assocId)
inline

Referenced by inet::sctp::SCTPAssociation::dequeueAckedChunks(), inet::sctp::SCTPAssociation::handleChunkReportedAsAcked(), inet::sctp::SCTPAssociation::handleChunkReportedAsMissing(), and inet::sctp::SCTPAssociation::processSackArrived().

226  {
227  auto found = assocStatMap.find(assocId);
228  if (found != assocStatMap.end()) {
229  return &found->second;
230  }
231  return nullptr;
232  }
AssocStatMap assocStatMap
Definition: SCTP.h:171
uint16 inet::sctp::SCTP::getEphemeralPort ( )

To be called from SCTPAssociation: reserves an ephemeral port for the connection.

Referenced by inet::sctp::SCTPAssociation::process_ASSOCIATE().

592 {
593  if (nextEphemeralPort == 5000)
594  throw cRuntimeError("Ephemeral port range 1024..4999 exhausted (email SCTP model "
595  "author that he should implement reuse of ephemeral ports!!!)");
596  return nextEphemeralPort++;
597 }
uint16 nextEphemeralPort
Definition: SCTP.h:192
int inet::sctp::SCTP::getFragPoint ( )
inline
275 { return socketOptions->fragPoint; };
int fragPoint
Definition: SCTPSocket.h:42
SocketOptions * socketOptions
Definition: SCTP.h:184
int inet::sctp::SCTP::getMaxBurst ( )
inline
274 { return socketOptions->maxBurst; };
int maxBurst
Definition: SCTPSocket.h:41
SocketOptions * socketOptions
Definition: SCTP.h:184
int inet::sctp::SCTP::getMaxInitRetrans ( )
inline

Referenced by inet::sctp::SCTPAssociation::process_TIMEOUT_INIT_REXMIT().

267 { return socketOptions->maxInitRetrans; };
SocketOptions * socketOptions
Definition: SCTP.h:184
int maxInitRetrans
Definition: SCTPSocket.h:34
int inet::sctp::SCTP::getMaxInitRetransTimeout ( )
inline

Referenced by inet::sctp::SCTPAssociation::process_TIMEOUT_INIT_REXMIT().

SocketOptions * socketOptions
Definition: SCTP.h:184
int maxInitRetransTimeout
Definition: SCTPSocket.h:35
int inet::sctp::SCTP::getNagle ( )
inline
276 { return socketOptions->nagle; };
int nagle
Definition: SCTPSocket.h:43
SocketOptions * socketOptions
Definition: SCTP.h:184
int inet::sctp::SCTP::getPathMaxRetrans ( )
inline
double inet::sctp::SCTP::getRtoInitial ( )
inline

Referenced by inet::sctp::SCTPAssociation::pmStartPathManagement(), and inet::sctp::SCTPPathVariables::SCTPPathVariables().

269 { return socketOptions->rtoInitial; };
SocketOptions * socketOptions
Definition: SCTP.h:184
double rtoInitial
Definition: SCTPSocket.h:36
double inet::sctp::SCTP::getRtoMin ( )
inline

Referenced by inet::sctp::SCTPAssociation::pmRttMeasurement().

270 { return socketOptions->rtoMin; };
SocketOptions * socketOptions
Definition: SCTP.h:184
double rtoMin
Definition: SCTPSocket.h:37
int inet::sctp::SCTP::getSackFrequency ( )
inline
272 { return socketOptions->sackFrequency; };
int sackFrequency
Definition: SCTPSocket.h:39
SocketOptions * socketOptions
Definition: SCTP.h:184
double inet::sctp::SCTP::getSackPeriod ( )
inline
273 { return socketOptions->sackPeriod; };
SocketOptions * socketOptions
Definition: SCTP.h:184
double sackPeriod
Definition: SCTPSocket.h:40
SctpVTagMap inet::sctp::SCTP::getVTagMap ( )
inline
259 { return sctpVTagMap; };
SctpVTagMap sctpVTagMap
Definition: SCTP.h:173
void inet::sctp::SCTP::handleMessage ( cMessage *  msg)
overridevirtual
136 {
137  L3Address destAddr;
138  L3Address srcAddr;
139  bool findListen = false;
140 
141  EV_DEBUG << "\n\nSCTPMain handleMessage at " << getFullPath() << "\n";
142 
143  if (msg->isSelfMessage()) {
144  EV_DEBUG << "selfMessage\n";
145 
146  SCTPAssociation *assoc = (SCTPAssociation *)msg->getContextPointer();
147  if (assoc) {
148  bool ret = assoc->processTimer(msg);
149 
150  if (!ret)
151  removeAssociation(assoc);
152  }
153  }
154  else if (msg->arrivedOn("from_ip")) {
155  EV_INFO << "Message from IP\n";
157  if (!dynamic_cast<SCTPMessage *>(msg)) {
158  EV_INFO << "no sctp message, delete it\n";
159  delete msg;
160  return;
161  }
162  SCTPMessage *sctpmsg = check_and_cast<SCTPMessage *>(msg);
163 
165 
166  if (!pktdrop && (sctpmsg->hasBitError() || !(sctpmsg->getChecksumOk()))) {
167  EV_WARN << "Packet has bit-error. delete it\n";
168 
170  delete msg;
171  return;
172  }
173 
174  if (par("udpEncapsEnabled")) {
175  EV_DETAIL << "Size of SCTPMSG=" << sctpmsg->getByteLength() << "\n";
176  UDPDataIndication *ctrl = check_and_cast<UDPDataIndication *>(msg->removeControlInfo());
177  srcAddr = ctrl->getSrcAddr();
178  destAddr = ctrl->getDestAddr();
179  delete ctrl;
180  EV_INFO << "controlInfo srcAddr=" << srcAddr << " destAddr=" << destAddr << "\n";
181  EV_DETAIL << "VTag=" << sctpmsg->getTag() << "\n";
182  } else {
183  INetworkProtocolControlInfo *controlInfo = check_and_cast<INetworkProtocolControlInfo *>(msg->removeControlInfo());
184  srcAddr = controlInfo->getSourceAddress();
185  destAddr = controlInfo->getDestinationAddress();
186  delete controlInfo;
187  EV_INFO << "controlInfo srcAddr=" << srcAddr << " destAddr=" << destAddr << "\n";
188  }
189 
190  EV_INFO << "srcAddr=" << srcAddr << " destAddr=" << destAddr << "\n";
191  if (sctpmsg->getByteLength() > (SCTP_COMMON_HEADER)) {
192  if (((SCTPChunk *)(sctpmsg->getChunks(0)))->getChunkType() == INIT || ((SCTPChunk *)(sctpmsg->getChunks(0)))->getChunkType() == INIT_ACK)
193  findListen = true;
194 
195  SCTPAssociation *assoc = findAssocForMessage(srcAddr, destAddr, sctpmsg->getSrcPort(), sctpmsg->getDestPort(), findListen);
196  if (!assoc && sctpAssocMap.size() > 0 && (((SCTPChunk *)(sctpmsg->getChunks(0)))->getChunkType() == INIT_ACK)) {
197  SCTPInitAckChunk* initack = check_and_cast<SCTPInitAckChunk *>((SCTPChunk *)(sctpmsg->getChunks(0)));
198  assoc = findAssocForInitAck(initack, srcAddr, destAddr, sctpmsg->getSrcPort(), sctpmsg->getDestPort(), findListen);
199  }
200  if (!assoc && sctpAssocMap.size() > 0 && (((SCTPChunk *)(sctpmsg->getChunks(0)))->getChunkType() == ERRORTYPE
201  || (sctpmsg->getChunksArraySize() > 1 &&
202  (((SCTPChunk *)(sctpmsg->getChunks(1)))->getChunkType() == ASCONF || ((SCTPChunk *)(sctpmsg->getChunks(1)))->getChunkType() == ASCONF_ACK))))
203  {
204  assoc = findAssocWithVTag(sctpmsg->getTag(), sctpmsg->getSrcPort(), sctpmsg->getDestPort());
205  }
206  if (!assoc) {
207  EV_INFO << "no assoc found msg=" << sctpmsg->getName() << "\n";
208  if (sctpmsg->hasBitError() || !(sctpmsg->getChecksumOk())) {
209  delete sctpmsg;
210  return;
211  }
212  if (((SCTPChunk *)(sctpmsg->getChunks(0)))->getChunkType() == SHUTDOWN_ACK)
213  sendShutdownCompleteFromMain(sctpmsg, destAddr, srcAddr);
214  else if (((SCTPChunk *)(sctpmsg->getChunks(0)))->getChunkType() != ABORT &&
215  ((SCTPChunk *)(sctpmsg->getChunks(0)))->getChunkType() != SHUTDOWN_COMPLETE) {
216  sendAbortFromMain(sctpmsg, destAddr, srcAddr);
217  }
218  delete sctpmsg;
219  }
220  else {
221  EV_INFO << "assoc " << assoc->assocId << " found\n";
222  bool ret = assoc->processSCTPMessage(sctpmsg, srcAddr, destAddr);
223  if (!ret) {
224  EV_DEBUG << "SCTPMain:: removeAssociation \n";
225  removeAssociation(assoc);
226  delete sctpmsg;
227  }
228  else {
229  delete sctpmsg;
230  }
231  }
232  }
233  else {
234  delete sctpmsg;
235  }
236  }
237  else { // must be from app
238  EV_DEBUG << "must be from app\n";
239  if (msg->getKind() == SCTP_C_GETSOCKETOPTIONS) {
240  cPacket* cmsg = new cPacket("SocketOptions", SCTP_I_SENDSOCKETOPTIONS);
241  SCTPCommand* indication = new SCTPCommand("SCTP_I_SENDSOCKETOPTIONS");
242  cmsg->setControlInfo(indication);
244  cmsg->setContextPointer((void*) socketOptions);
245  send(cmsg, "to_appl", 0);
246  delete msg;
247  } else {
248  SCTPCommand *controlInfo = check_and_cast<SCTPCommand *>(msg->getControlInfo());
249 
250  int32 appGateIndex;
251  if (controlInfo->getGate() != -1)
252  appGateIndex = controlInfo->getGate();
253  else
254  appGateIndex = msg->getArrivalGate()->getIndex();
255  int32 assocId = controlInfo->getAssocId();
256  if (assocId == -1) {
257  int32 fd = controlInfo->getFd();
258  assocId = findAssocForFd(fd);
259  }
260  EV_INFO << "msg arrived from app for assoc " << assocId << "\n";
261  SCTPAssociation *assoc = findAssocForApp(appGateIndex, assocId);
262 
263  if (!assoc) {
264  EV_INFO << "no assoc found. msg=" << msg->getName() << " number of assocs = " << assocList.size() << "\n";
265 
266  if (strcmp(msg->getName(), "PassiveOPEN") == 0 || strcmp(msg->getName(), "Associate") == 0) {
267  if (assocList.size() > 0) {
268  assoc = nullptr;
269  SCTPOpenCommand *open = check_and_cast<SCTPOpenCommand *>(controlInfo);
270  EV_INFO << "Looking for assoc with remoteAddr=" << open->getRemoteAddr() << ", remotePort=" << open->getRemotePort() << ", localPort=" << open->getLocalPort() << "\n";
271  for (auto & elem : assocList) {
272  EV_DETAIL << "remoteAddr=" << (elem)->remoteAddr << ", remotePort=" << (elem)->remotePort << ", localPort=" << (elem)->localPort << "\n";
273  if ((elem)->remoteAddr == open->getRemoteAddr() && (elem)->localPort == open->getLocalPort() && (elem)->remotePort == open->getRemotePort()) {
274  assoc = (elem);
275  break;
276  }
277  }
278  }
279  if (assocList.size() == 0 || assoc == nullptr) {
280  assoc = new SCTPAssociation(this, appGateIndex, assocId, rt, ift);
281 
282  AppAssocKey key;
283  key.appGateIndex = appGateIndex;
284  key.assocId = assocId;
285  sctpAppAssocMap[key] = assoc;
286  EV_INFO << "SCTP association created for appGateIndex " << appGateIndex << " and assoc " << assocId << "\n";
287  bool ret = assoc->processAppCommand(msg);
288  if (!ret) {
289  removeAssociation(assoc);
290  }
291  }
292  }
293  } else {
294  EV_INFO << "assoc found\n";
295  bool ret = assoc->processAppCommand(msg);
296 
297  if (!ret)
298  removeAssociation(assoc);
299  }
300  delete msg;
301  }
302  }
303 }
SocketOptions * collectSocketOptions()
Getter and Setter for the socket options.
Definition: SCTP.cc:305
SCTPAssociation * findAssocForApp(int32 appGateIndex, int32 assocId)
Definition: SCTP.cc:570
Definition: SCTPCommand.h:83
Definition: SCTPAssociation.h:119
void printInfoAssocMap()
Definition: SCTP.cc:42
bool pktdrop
Definition: SCTP.h:212
int32 findAssocForFd(int32 fd)
Definition: SCTP.cc:580
Definition: SCTPAssociation.h:130
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
SCTPAssociation * findAssocWithVTag(uint32 peerVTag, uint32 remotePort, uint32 localPort)
Definition: SCTP.cc:486
SctpAppAssocMap sctpAppAssocMap
Definition: SCTP.h:178
IInterfaceTable * ift
Definition: SCTP.h:188
SCTPAssociation * findAssocForMessage(L3Address srcAddr, L3Address destAddr, uint32 srcPort, uint32 destPort, bool findListen)
Definition: SCTP.cc:519
SocketOptions * socketOptions
Definition: SCTP.h:184
void removeAssociation(SCTPAssociation *assoc)
Definition: SCTP.cc:799
Definition: SCTPAssociation.h:112
SCTPAssociation * findAssocForInitAck(SCTPInitAckChunk *initack, L3Address srcAddr, L3Address destAddr, uint32 srcPort, uint32 destPort, bool findListen)
Definition: SCTP.cc:503
Definition: SCTPCommand.h:51
uint32 numPacketsReceived
Definition: SCTP.h:208
uint32 numPacketsDropped
Definition: SCTP.h:209
void sendShutdownCompleteFromMain(SCTPMessage *sctpmsg, L3Address fromAddr, L3Address toAddr)
Definition: SCTP.cc:363
int32_t int32
Definition: Compat.h:31
std::list< SCTPAssociation * > assocList
Definition: SCTP.h:180
Definition: SCTPAssociation.h:120
Definition: SCTPAssociation.h:117
Definition: SCTPAssociation.h:126
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179
Definition: SCTPAssociation.h:113
Definition: SCTPAssociation.h:123
IRoutingTable * rt
Definition: SCTP.h:187
void sendAbortFromMain(SCTPMessage *sctpmsg, L3Address fromAddr, L3Address toAddr)
Definition: SCTP.cc:325
void inet::sctp::SCTP::initialize ( int  stage)
overridevirtual
87 {
88  cSimpleModule::initialize(stage);
89 
90  if (stage == INITSTAGE_LOCAL) {
91  ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
92  rt = getModuleFromPar<IRoutingTable>(par("routingTableModule"), this);
93  this->auth = (bool)par("auth");
94  this->pktdrop = (bool)par("packetDrop");
95  this->sackNow = (bool)par("sackNow");
99  sizeAssocMap = 0;
100  nextEphemeralPort = (uint16)(intrand(10000) + 30000);
101 
102  cModule *netw = getSimulation()->getSystemModule();
103  if (netw->hasPar("testTimeout")) {
104  testTimeout = (simtime_t)netw->par("testTimeout");
105  }
106  }
107  else if (stage == INITSTAGE_TRANSPORT_LAYER) {
108  IPSocket socket(gate("to_ip"));
109  socket.registerProtocol(IP_PROT_SCTP);
110  }
111  else if (stage == INITSTAGE_TRANSPORT_LAYER_2) {
112  if (par("udpEncapsEnabled").boolValue()) {
113  bindPortForUDP();
114  }
115  }
116 }
Initialization of transport-layer protocols.
Definition: InitStages.h:90
uint16 nextEphemeralPort
Definition: SCTP.h:192
void bindPortForUDP()
Definition: SCTP.cc:78
bool sackNow
Definition: SCTP.h:213
simtime_t testTimeout
Definition: SCTP.h:206
bool pktdrop
Definition: SCTP.h:212
int32 sizeAssocMap
Definition: SCTP.h:190
Initialization of transport-layer protocols, 2nd stage.
Definition: InitStages.h:96
IInterfaceTable * ift
Definition: SCTP.h:188
Local initializations.
Definition: InitStages.h:35
bool auth
Definition: SCTP.h:210
uint32 numPacketsReceived
Definition: SCTP.h:208
uint32 numPacketsDropped
Definition: SCTP.h:209
uint64 numPktDropReports
Definition: SCTP.h:214
uint16_t uint16
Definition: Compat.h:32
Definition: IPProtocolId_m.h:91
IRoutingTable * rt
Definition: SCTP.h:187
virtual int inet::sctp::SCTP::numInitStages ( ) const
inlineoverridevirtual
219 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::sctp::SCTP::printInfoAssocMap ( )

Referenced by addForkedAssociation(), addLocalAddress(), addLocalAddressToAllRemoteAddresses(), addRemoteAddress(), inet::sctp::SCTPAssociation::cloneAssociation(), findAssocForMessage(), findAssocWithVTag(), handleMessage(), removeAssociation(), removeLocalAddressFromAllRemoteAddresses(), removeRemoteAddressFromAllAssociations(), inet::sctp::SCTPAssociation::sendInit(), and updateSockPair().

43 {
44  SCTPAssociation *assoc;
45  SockPair key;
46  EV_DETAIL << "Number of Assocs: " << sizeAssocMap << "\n";
47  if (sizeAssocMap > 0) {
48  for (auto & elem : sctpAssocMap) {
49  assoc = elem.second;
50  key = elem.first;
51 
52  EV_DETAIL << "assocId: " << assoc->assocId << " assoc: " << assoc << " src: " << key.localAddr << " dst: " << key.remoteAddr << " lPort: " << key.localPort << " rPort: " << key.remotePort << " fd: " << assoc->fd <<"\n";
53  }
54 
55  EV_DETAIL << "\n";
56  }
57 }
int32 sizeAssocMap
Definition: SCTP.h:190
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179
void inet::sctp::SCTP::printVTagMap ( )

Referenced by findAssocWithVTag().

60 {
61  int32 assocId;
62  VTagPair key;
63  EV_DETAIL << "Number of Assocs: " << sctpVTagMap.size() << "\n";
64  if (sctpVTagMap.size() > 0) {
65  for (auto & elem : sctpVTagMap) {
66  assocId = elem.first;
67  key = elem.second;
68 
69  EV_DETAIL << "assocId: " << assocId << " peerVTag: " << key.peerVTag
70  << " localVTag: " << key.localVTag
71  << " localPort: " << key.localPort << " rPort: " << key.remotePort << "\n";
72  }
73 
74  EV_DETAIL << "\n";
75  }
76 }
SctpVTagMap sctpVTagMap
Definition: SCTP.h:173
int32_t int32
Definition: Compat.h:31
void inet::sctp::SCTP::refreshDisplay ( ) const
overrideprotectedvirtual
404 {
405 #if 0
406  if (getEnvir()->disable_tracing) {
407  // in express mode, we don't bother to update the display
408  // (std::map's iteration is not very fast if map is large)
409  getDisplayString().setTagArg("t", 0, "");
410  return;
411  }
412 
413  //char buf[40];
414  //sprintf(buf,"%d conns", sctpAppConnMap.size());
415  //displayString().setTagArg("t",0,buf);
416 
417  int32 numCLOSED = 0, numLISTEN = 0, numSYN_SENT = 0, numSYN_RCVD = 0,
418  numESTABLISHED = 0, numCLOSE_WAIT = 0, numLAST_ACK = 0, numFIN_WAIT_1 = 0,
419  numFIN_WAIT_2 = 0, numCLOSING = 0, numTIME_WAIT = 0;
420 
421  for (auto i = sctpAppConnMap.begin(); i != sctpAppConnMap.end(); ++i) {
422  int32 state = (*i).second->getFsmState();
423  switch (state) {
424  // case SCTP_S_INIT: numINIT++; break;
425  case SCTP_S_CLOSED:
426  numCLOSED++;
427  break;
428 
429  case SCTP_S_COOKIE_WAIT:
430  numLISTEN++;
431  break;
432 
434  numSYN_SENT++;
435  break;
436 
437  case SCTP_S_ESTABLISHED:
438  numESTABLISHED++;
439  break;
440 
442  numCLOSE_WAIT++;
443  break;
444 
446  numLAST_ACK++;
447  break;
448 
450  numFIN_WAIT_1++;
451  break;
452 
454  numFIN_WAIT_2++;
455  break;
456  }
457  }
458  char buf2[300];
459  buf2[0] = '\0';
460  if (numCLOSED > 0)
461  sprintf(buf2 + strlen(buf2), "closed:%d ", numCLOSED);
462  if (numLISTEN > 0)
463  sprintf(buf2 + strlen(buf2), "listen:%d ", numLISTEN);
464  if (numSYN_SENT > 0)
465  sprintf(buf2 + strlen(buf2), "syn_sent:%d ", numSYN_SENT);
466  if (numSYN_RCVD > 0)
467  sprintf(buf2 + strlen(buf2), "syn_rcvd:%d ", numSYN_RCVD);
468  if (numESTABLISHED > 0)
469  sprintf(buf2 + strlen(buf2), "estab:%d ", numESTABLISHED);
470  if (numCLOSE_WAIT > 0)
471  sprintf(buf2 + strlen(buf2), "close_wait:%d ", numCLOSE_WAIT);
472  if (numLAST_ACK > 0)
473  sprintf(buf2 + strlen(buf2), "last_ack:%d ", numLAST_ACK);
474  if (numFIN_WAIT_1 > 0)
475  sprintf(buf2 + strlen(buf2), "fin_wait_1:%d ", numFIN_WAIT_1);
476  if (numFIN_WAIT_2 > 0)
477  sprintf(buf2 + strlen(buf2), "fin_wait_2:%d ", numFIN_WAIT_2);
478  if (numCLOSING > 0)
479  sprintf(buf2 + strlen(buf2), "closing:%d ", numCLOSING);
480  if (numTIME_WAIT > 0)
481  sprintf(buf2 + strlen(buf2), "time_wait:%d ", numTIME_WAIT);
482  getDisplayString().setTagArg("t", 0, buf2);
483 #endif // if 0
484 }
Definition: SCTPAssociation.h:63
Definition: SCTPAssociation.h:60
Definition: SCTPAssociation.h:64
Definition: SCTPAssociation.h:58
Definition: SCTPAssociation.h:62
int32_t int32
Definition: Compat.h:31
Definition: SCTPAssociation.h:59
Definition: SCTPAssociation.h:61
Definition: SCTPAssociation.h:57
void inet::sctp::SCTP::removeAssociation ( SCTPAssociation assoc)

Referenced by finish(), handleMessage(), inet::sctp::SCTPAssociation::process_RCV_Message(), inet::sctp::SCTPAssociation::process_TIMEOUT_HEARTBEAT(), inet::sctp::SCTPAssociation::process_TIMEOUT_RTX(), inet::sctp::SCTPAssociation::process_TIMEOUT_SHUTDOWN(), and inet::sctp::SCTPAssociation::updateCounters().

800 {
801  bool ok = false;
802  bool find = false;
803  const int32 id = assoc->assocId;
804 
805  EV_INFO << "Deleting SCTP connection " << assoc << " id= " << id << endl;
806 
808  if (sizeAssocMap > 0) {
809  auto assocStatMapIterator = assocStatMap.find(assoc->assocId);
810  if (assocStatMapIterator != assocStatMap.end()) {
811  assocStatMapIterator->second.stop = simTime();
812  assocStatMapIterator->second.lifeTime = assocStatMapIterator->second.stop - assocStatMapIterator->second.start;
813  assocStatMapIterator->second.throughput = assocStatMapIterator->second.ackedBytes * 8 / assocStatMapIterator->second.lifeTime.dbl();
814  }
815  while (!ok) {
816  if (sizeAssocMap == 0) {
817  ok = true;
818  }
819  else {
820  for (auto sctpAssocMapIterator = sctpAssocMap.begin();
821  sctpAssocMapIterator != sctpAssocMap.end(); sctpAssocMapIterator++)
822  {
823  if (sctpAssocMapIterator->second != nullptr) {
824  SCTPAssociation *myAssoc = sctpAssocMapIterator->second;
825  if (myAssoc->assocId == assoc->assocId) {
826  if (myAssoc->T1_InitTimer) {
827  myAssoc->stopTimer(myAssoc->T1_InitTimer);
828  }
829  if (myAssoc->T2_ShutdownTimer) {
830  myAssoc->stopTimer(myAssoc->T2_ShutdownTimer);
831  }
832  if (myAssoc->T5_ShutdownGuardTimer) {
833  myAssoc->stopTimer(myAssoc->T5_ShutdownGuardTimer);
834  }
835  if (myAssoc->SackTimer) {
836  myAssoc->stopTimer(myAssoc->SackTimer);
837  }
838  if (myAssoc->StartAddIP) {
839  myAssoc->stopTimer(myAssoc->StartAddIP);
840  }
841  sctpAssocMap.erase(sctpAssocMapIterator);
842  sizeAssocMap--;
843  find = true;
844  break;
845  }
846  }
847  }
848  }
849 
850  if (!find) {
851  ok = true;
852  }
853  else {
854  find = false;
855  }
856  }
857  }
858  // Write statistics
859  char str[128];
860  for (auto pathMapIterator = assoc->sctpPathMap.begin();
861  pathMapIterator != assoc->sctpPathMap.end(); pathMapIterator++)
862  {
863  const SCTPPathVariables *path = pathMapIterator->second;
864  snprintf((char *)&str, sizeof(str), "Number of Fast Retransmissions %d:%s",
865  assoc->assocId, path->remoteAddress.str().c_str());
866  recordScalar(str, path->numberOfFastRetransmissions);
867  snprintf((char *)&str, sizeof(str), "Number of Timer-Based Retransmissions %d:%s",
868  assoc->assocId, path->remoteAddress.str().c_str());
869  recordScalar(str, path->numberOfTimerBasedRetransmissions);
870  snprintf((char *)&str, sizeof(str), "Number of Heartbeats Sent %d:%s",
871  assoc->assocId, path->remoteAddress.str().c_str());
872  recordScalar(str, path->numberOfHeartbeatsSent);
873  snprintf((char *)&str, sizeof(str), "Number of Heartbeats Received %d:%s",
874  assoc->assocId, path->remoteAddress.str().c_str());
875  recordScalar(str, path->numberOfHeartbeatsRcvd);
876  snprintf((char *)&str, sizeof(str), "Number of Heartbeat ACKs Sent %d:%s",
877  assoc->assocId, path->remoteAddress.str().c_str());
878  recordScalar(str, path->numberOfHeartbeatAcksSent);
879  snprintf((char *)&str, sizeof(str), "Number of Heartbeat ACKs Received %d:%s",
880  assoc->assocId, path->remoteAddress.str().c_str());
881  recordScalar(str, path->numberOfHeartbeatAcksRcvd);
882  snprintf((char *)&str, sizeof(str), "Number of Duplicates %d:%s",
883  assoc->assocId, path->remoteAddress.str().c_str());
884  recordScalar(str, path->numberOfDuplicates);
885  snprintf((char *)&str, sizeof(str), "Number of Bytes received from %d:%s",
886  assoc->assocId, path->remoteAddress.str().c_str());
887  recordScalar(str, path->numberOfBytesReceived);
888  }
889  for (uint16 i = 0; i < assoc->inboundStreams; i++) {
890  snprintf((char *)&str, sizeof(str), "Bytes received on stream %d of assoc %d",
891  i, assoc->assocId);
892  recordScalar(str, assoc->getState()->streamThroughput[i]);
893  }
894  recordScalar("Blocking TSNs Moved", assoc->state->blockingTSNsMoved);
895 
896  assoc->removePath();
897  assoc->deleteStreams();
898 
899  // Chunks may be in the transmission and retransmission queues simultaneously.
900  // Remove entry from transmission queue if it is already in the retransmission queue.
901  for (auto i = assoc->getRetransmissionQueue()->payloadQueue.begin();
902  i != assoc->getRetransmissionQueue()->payloadQueue.end(); i++)
903  {
904  auto j = assoc->getTransmissionQueue()->payloadQueue.find(i->second->tsn);
905  if (j != assoc->getTransmissionQueue()->payloadQueue.end()) {
906  assoc->getTransmissionQueue()->payloadQueue.erase(j);
907  }
908  }
909  // Now, both queues can be safely deleted.
910  delete assoc->getRetransmissionQueue();
911  delete assoc->getTransmissionQueue();
912 
913  AppAssocKey key;
914  key.appGateIndex = assoc->appGateIndex;
915  key.assocId = assoc->assocId;
916  sctpAppAssocMap.erase(key);
917  assocList.remove(assoc);
918  delete assoc;
919 }
void printInfoAssocMap()
Definition: SCTP.cc:42
int32 sizeAssocMap
Definition: SCTP.h:190
SctpAppAssocMap sctpAppAssocMap
Definition: SCTP.h:178
AssocStatMap assocStatMap
Definition: SCTP.h:171
int32_t int32
Definition: Compat.h:31
std::list< SCTPAssociation * > assocList
Definition: SCTP.h:180
uint16_t uint16
Definition: Compat.h:32
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179
std::vector< T >::iterator find(std::vector< T > &v, const T &a)
Definition: stlutils.h:48
void inet::sctp::SCTP::removeLocalAddressFromAllRemoteAddresses ( SCTPAssociation assoc,
L3Address  address,
std::vector< L3Address remAddresses 
)

Referenced by inet::sctp::SCTPAssociation::processAsconfAckArrived().

693 {
694  SockPair key;
695 
696  for (auto & remAddresse : remAddresses) {
697  key.localAddr = address;
698  key.remoteAddr = (remAddresse);
699  key.localPort = assoc->localPort;
700  key.remotePort = assoc->remotePort;
701 
702  auto j = sctpAssocMap.find(key);
703  if (j != sctpAssocMap.end()) {
704  ASSERT(j->second == assoc);
705  sctpAssocMap.erase(j);
706  sizeAssocMap--;
707  }
708  else
709  EV_INFO << "no actual sockPair found\n";
710 
712  }
713 }
void printInfoAssocMap()
Definition: SCTP.cc:42
int32 sizeAssocMap
Definition: SCTP.h:190
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179
void inet::sctp::SCTP::removeRemoteAddressFromAllAssociations ( SCTPAssociation assoc,
L3Address  address,
std::vector< L3Address locAddresses 
)

Referenced by inet::sctp::SCTPAssociation::processAsconfArrived().

716 {
717  SockPair key;
718 
719  for (auto & locAddresse : locAddresses) {
720  key.localAddr = (locAddresse);
721  key.remoteAddr = address;
722  key.localPort = assoc->localPort;
723  key.remotePort = assoc->remotePort;
724 
725  auto j = sctpAssocMap.find(key);
726  if (j != sctpAssocMap.end()) {
727  ASSERT(j->second == assoc);
728  sctpAssocMap.erase(j);
729  sizeAssocMap--;
730  }
731  else
732  EV_INFO << "no actual sockPair found\n";
733 
735  }
736 }
void printInfoAssocMap()
Definition: SCTP.cc:42
int32 sizeAssocMap
Definition: SCTP.h:190
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179
void inet::sctp::SCTP::send_to_ip ( SCTPMessage msg)
virtual

Referenced by sendAbortFromMain(), sendShutdownCompleteFromMain(), and inet::sctp::SCTPAssociation::sendToIP().

391 {
392 // enable this and run all SCTP tests tp see if SCTP serializer correctly handles all SCTP packets
393 #if 0
394  char buff[4096];
395  serializer::Buffer b(buff, 4096);
396  serializer::Context ctx;
397  serializer::SCTPSerializer().serializePacket(msg, b, ctx);
398  ASSERT(b.getPos() == msg->getByteLength());
399 #endif
400  send(msg, "to_ip");
401 }
value< double, units::m > b
Definition: Units.h:1054
void inet::sctp::SCTP::sendAbortFromMain ( SCTPMessage sctpmsg,
L3Address  fromAddr,
L3Address  toAddr 
)
protected

Referenced by handleMessage().

326 {
327  SCTPMessage *msg = new SCTPMessage();
328 
329  EV_DEBUG << "\n\nSCTP::sendAbortFromMain()\n";
330 
331  msg->setSrcPort(sctpmsg->getDestPort());
332  msg->setDestPort(sctpmsg->getSrcPort());
333  msg->setBitLength(SCTP_COMMON_HEADER * 8);
334  msg->setChecksumOk(true);
335 
336  SCTPAbortChunk *abortChunk = new SCTPAbortChunk("ABORT");
337  abortChunk->setChunkType(ABORT);
338  if (sctpmsg->getChunksArraySize() > 0 && ((SCTPChunk *)(sctpmsg->getChunks(0)))->getChunkType() == INIT) {
339  SCTPInitChunk *initChunk = check_and_cast<SCTPInitChunk *>(sctpmsg->getChunks(0));
340  abortChunk->setT_Bit(0);
341  msg->setTag(initChunk->getInitTag());
342  }
343  else {
344  abortChunk->setT_Bit(1);
345  msg->setTag(sctpmsg->getTag());
346  }
347  abortChunk->setBitLength(SCTP_ABORT_CHUNK_LENGTH * 8);
348  msg->addChunk(abortChunk);
349  if ((bool)par("udpEncapsEnabled")) {
350  EV_DETAIL << "VTag=" << msg->getTag() << "\n";
351  udpSocket.sendTo(msg, toAddr, SCTP_UDP_PORT);
352  }
353  else {
354  INetworkProtocolControlInfo *controlInfo = toAddr.getAddressType()->createNetworkProtocolControlInfo();
355  controlInfo->setTransportProtocol(IP_PROT_SCTP);
356  controlInfo->setSourceAddress(fromAddr);
357  controlInfo->setDestinationAddress(toAddr);
358  msg->setControlInfo(check_and_cast<cObject *>(controlInfo));
359  send_to_ip(msg);
360  }
361 }
void sendTo(cPacket *msg, L3Address destAddr, int destPort, const SendOptions *options=nullptr)
Sends a data packet to the given address and port.
Definition: UDPSocket.cc:88
UDPSocket udpSocket
Definition: SCTP.h:182
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
virtual void send_to_ip(SCTPMessage *msg)
Definition: SCTP.cc:390
Definition: SCTPAssociation.h:112
#define SCTP_UDP_PORT
Definition: SCTP.h:41
Definition: SCTPAssociation.h:117
#define SCTP_ABORT_CHUNK_LENGTH
Definition: SCTPAssociation.h:218
Definition: IPProtocolId_m.h:91
void inet::sctp::SCTP::sendShutdownCompleteFromMain ( SCTPMessage sctpmsg,
L3Address  fromAddr,
L3Address  toAddr 
)
protected

Referenced by handleMessage().

364 {
365  SCTPMessage *msg = new SCTPMessage();
366 
367  EV_DEBUG << "\n\nSCTP:sendShutdownCompleteFromMain \n";
368 
369  msg->setSrcPort(sctpmsg->getDestPort());
370  msg->setDestPort(sctpmsg->getSrcPort());
371  msg->setBitLength(SCTP_COMMON_HEADER * 8);
372  msg->setChecksumOk(true);
373 
374  SCTPShutdownCompleteChunk *scChunk = new SCTPShutdownCompleteChunk("SHUTDOWN_COMPLETE");
375  scChunk->setChunkType(SHUTDOWN_COMPLETE);
376  scChunk->setTBit(1);
377  msg->setTag(sctpmsg->getTag());
378 
379  scChunk->setBitLength(SCTP_SHUTDOWN_ACK_LENGTH * 8);
380  msg->addChunk(scChunk);
381 
382  INetworkProtocolControlInfo *controlInfo = toAddr.getAddressType()->createNetworkProtocolControlInfo();
383  controlInfo->setTransportProtocol(IP_PROT_SCTP);
384  controlInfo->setSourceAddress(fromAddr);
385  controlInfo->setDestinationAddress(toAddr);
386  msg->setControlInfo(check_and_cast<cObject *>(controlInfo));
387  send_to_ip(msg);
388 }
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
virtual void send_to_ip(SCTPMessage *msg)
Definition: SCTP.cc:390
#define SCTP_SHUTDOWN_ACK_LENGTH
Definition: SCTPAssociation.h:222
Definition: IPProtocolId_m.h:91
Definition: SCTPAssociation.h:123
void inet::sctp::SCTP::setRtoInitial ( double  rtoInitial)
inline
281 { socketOptions->rtoInitial = rtoInitial; };
SocketOptions * socketOptions
Definition: SCTP.h:184
double rtoInitial
Definition: SCTPSocket.h:36
void inet::sctp::SCTP::setRtoMax ( double  rtoMax)
inline
283 { socketOptions->rtoMax = rtoMax; };
SocketOptions * socketOptions
Definition: SCTP.h:184
double rtoMax
Definition: SCTPSocket.h:38
void inet::sctp::SCTP::setRtoMin ( double  rtoMin)
inline
282 { socketOptions->rtoMin = rtoMin; };
SocketOptions * socketOptions
Definition: SCTP.h:184
double rtoMin
Definition: SCTPSocket.h:37
void inet::sctp::SCTP::setSocketOptions ( SocketOptions options)
inline

Referenced by inet::sctp::SCTPAssociation::process_ASSOCIATE(), and inet::sctp::SCTPAssociation::process_OPEN_PASSIVE().

266 { socketOptions = options; };
SocketOptions * socketOptions
Definition: SCTP.h:184
void inet::sctp::SCTP::updateSockPair ( SCTPAssociation assoc,
L3Address  localAddr,
L3Address  remoteAddr,
int32  localPort,
int32  remotePort 
)

To be called from SCTPAssociation when socket pair changes.

Referenced by addForkedAssociation(), inet::sctp::SCTPAssociation::process_ASSOCIATE(), inet::sctp::SCTPAssociation::process_OPEN_PASSIVE(), and inet::sctp::SCTPAssociation::processInitArrived().

600 {
601  SockPair key;
602  EV_INFO << "updateSockPair: localAddr: " << localAddr << " remoteAddr=" << remoteAddr << " localPort=" << localPort << " remotePort=" << remotePort << "\n";
603 
604  key.localAddr = (assoc->localAddr = localAddr);
605  key.remoteAddr = (assoc->remoteAddr = remoteAddr);
606  key.localPort = assoc->localPort = localPort;
607  key.remotePort = assoc->remotePort = remotePort;
608 
609  // Do not update a sock pair that is already stored
610  for (auto & elem : sctpAssocMap) {
611  if (elem.second == assoc &&
612  elem.first.localAddr == key.localAddr &&
613  elem.first.remoteAddr == key.remoteAddr &&
614  elem.first.localPort == key.localPort
615  && elem.first.remotePort == key.remotePort)
616  return;
617  }
618 
619  for (auto i = sctpAssocMap.begin(); i != sctpAssocMap.end(); i++) {
620  if (i->second == assoc) {
621  sctpAssocMap.erase(i);
622  break;
623  }
624  }
625 
626  EV_INFO << "updateSockPair assoc=" << assoc << " localAddr=" << key.localAddr << " remoteAddr=" << key.remoteAddr << " localPort=" << key.localPort << " remotePort=" << remotePort << "\n";
627 
628  sctpAssocMap[key] = assoc;
629  sizeAssocMap = sctpAssocMap.size();
630  EV_DEBUG << "assoc inserted in sctpAssocMap\n";
632 }
void printInfoAssocMap()
Definition: SCTP.cc:42
int32 sizeAssocMap
Definition: SCTP.h:190
SctpAssocMap sctpAssocMap
Definition: SCTP.h:179

Member Data Documentation

bool inet::sctp::SCTP::addIP
AssocStatMap inet::sctp::SCTP::assocStatMap

Referenced by inet::sctp::SCTPAssociation::addAuthChunkIfNecessary(), inet::sctp::SCTPAssociation::createForwardTsnChunk(), inet::sctp::SCTPAssociation::createSack(), finish(), inet::sctp::SCTPAssociation::makeRoomForTsn(), inet::sctp::SCTPAssociation::pathStatusIndication(), inet::sctp::SCTPAssociation::process_RCV_Message(), inet::sctp::SCTPAssociation::process_SEND(), inet::sctp::SCTPAssociation::process_TIMEOUT_RTX(), inet::sctp::SCTPAssociation::processAddInAndOutResetRequestArrived(), inet::sctp::SCTPAssociation::processAsconfArrived(), inet::sctp::SCTPAssociation::processDataArrived(), inet::sctp::SCTPAssociation::processOutAndResponseArrived(), inet::sctp::SCTPAssociation::processResetResponseArrived(), inet::sctp::SCTPAssociation::pushUlp(), removeAssociation(), inet::sctp::SCTPAssociation::retransmitAsconf(), inet::sctp::SCTPAssociation::retransmitCookieEcho(), inet::sctp::SCTPAssociation::sendAbort(), inet::sctp::SCTPAssociation::sendAddOutgoingStreamsRequest(), inet::sctp::SCTPAssociation::sendAsconf(), inet::sctp::SCTPAssociation::sendAsconfAck(), inet::sctp::SCTPAssociation::sendCookieAck(), inet::sctp::SCTPAssociation::sendCookieEcho(), inet::sctp::SCTPAssociation::sendHeartbeat(), inet::sctp::SCTPAssociation::sendHeartbeatAck(), inet::sctp::SCTPAssociation::sendInvalidStreamError(), inet::sctp::SCTPAssociation::sendOnPath(), inet::sctp::SCTPAssociation::sendSack(), inet::sctp::SCTPAssociation::sendShutdown(), inet::sctp::SCTPAssociation::sendStreamResetRequest(), and ~SCTP().

IInterfaceTable* inet::sctp::SCTP::ift
protected

Referenced by handleMessage(), and initialize().

uint16 inet::sctp::SCTP::nextEphemeralPort
protected

Referenced by getEphemeralPort(), and initialize().

uint32 inet::sctp::SCTP::numGapReports
uint32 inet::sctp::SCTP::numPacketsDropped

Referenced by finish(), handleMessage(), and initialize().

uint32 inet::sctp::SCTP::numPacketsReceived

Referenced by finish(), handleMessage(), and initialize().

uint64 inet::sctp::SCTP::numPktDropReports
IRoutingTable* inet::sctp::SCTP::rt
protected

Referenced by handleMessage(), and initialize().

SctpVTagMap inet::sctp::SCTP::sctpVTagMap
SocketOptions* inet::sctp::SCTP::socketOptions

Referenced by finish(), and handleMessage().

simtime_t inet::sctp::SCTP::testTimeout

Referenced by initialize().


The documentation for this class was generated from the following files: