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

#include <SCTPAssociation.h>

Inheritance diagram for inet::sctp::SCTPAssociation:

Classes

struct  calcBytesToSend
 
struct  congestionControlFunctions
 
struct  counter
 
struct  streamSchedulingFunctions
 

Public Member Functions

 SCTPAssociation (SCTP *mod, int32 appGateIndex, int32 assocId, IRoutingTable *rt, IInterfaceTable *ift)
 Constructor. More...
 
 ~SCTPAssociation ()
 Destructor. More...
 
void sendOnPath (SCTPPathVariables *pathId, const bool firstPass=true)
 Utility: Send data from sendQueue. More...
 
void sendOnAllPaths (SCTPPathVariables *firstPath)
 

Static Public Member Functions

static const char * indicationName (const int32 code)
 Utility: returns name of SCTP_I_xxx constants. More...
 
static int getAddressLevel (const L3Address &addr)
 Utility: return IPv4 or IPv6 address level. More...
 

Public Attributes

int32 appGateIndex
 
int32 assocId
 
int32 fd
 
bool listening
 
L3Address remoteAddr
 
L3Address localAddr
 
uint16 localPort
 
uint16 remotePort
 
uint32 localVTag
 
uint32 peerVTag
 
cMessage * T1_InitTimer
 
cMessage * T2_ShutdownTimer
 
cMessage * T5_ShutdownGuardTimer
 
cMessage * SackTimer
 
cMessage * StartTesting
 
cMessage * StartAddIP
 
cOutVector * advMsgRwnd
 
cOutVector * EndToEndDelay
 
bool fairTimer
 
std::map< uint16, cOutVector * > streamThroughputVectors
 
cOutVector * assocThroughputVector
 
cMessage * FairStartTimer
 
cMessage * FairStopTimer
 
uint8_t dacPacketsRcvd
 

Protected Types

typedef struct inet::sctp::SCTPAssociation::streamSchedulingFunctions SSFunctions
 

Protected Member Functions

void startTimer (cMessage *timer, const simtime_t &timeout)
 
SCTPAssociationcloneAssociation ()
 Utility: clone a listening association. More...
 
void initAssociation (SCTPOpenCommand *openCmd)
 Utility: creates send/receive queues and sctpAlgorithm. More...
 
bool tsnIsDuplicate (const uint32 tsn) const
 Methods dealing with the handling of TSNs. More...
 
bool makeRoomForTsn (const uint32 tsn, const uint32 length, const bool uBit)
 
void sendInit ()
 Methods for creating and sending chunks. More...
 
void sendInitAck (SCTPInitChunk *initchunk)
 
void sendCookieEcho (SCTPInitAckChunk *initackchunk)
 
void sendCookieAck (const L3Address &dest)
 
void sendAbort (uint16 tBit=0)
 
void sendHeartbeat (const SCTPPathVariables *path)
 
void sendHeartbeatAck (const SCTPHeartbeatChunk *heartbeatChunk, const L3Address &src, const L3Address &dest)
 
void sendSack ()
 
void sendShutdown ()
 
void sendShutdownAck (const L3Address &dest)
 
void sendShutdownComplete ()
 
SCTPSackChunkcreateSack ()
 
void retransmitInit ()
 Retransmitting chunks. More...
 
void retransmitCookieEcho ()
 
void retransmitReset ()
 
void retransmitShutdown ()
 
void retransmitShutdownAck ()
 
void sendToIP (SCTPMessage *sctpmsg, const L3Address &dest)
 Utility: adds control info to message and sends it to IP. More...
 
void sendToIP (SCTPMessage *sctpmsg)
 
void scheduleSack ()
 
void signalConnectionTimeout ()
 Utility: signal to user that connection timed out. More...
 
void scheduleTimeout (cMessage *msg, const simtime_t &timeout)
 Utility: start a timer. More...
 
cMessage * cancelEvent (cMessage *msg)
 Utility: cancel a timer. More...
 
void sendToApp (cMessage *msg)
 Utility: sends packet to application. More...
 
void sendIndicationToApp (const int32 code, const int32 value=0)
 Utility: sends status indication (SCTP_I_xxx) to application. More...
 
void sendEstabIndicationToApp ()
 Utility: sends SCTP_I_ESTABLISHED indication with SCTPConnectInfo to application. More...
 
void pushUlp ()
 
void sendDataArrivedNotification (uint16 sid)
 
void putInDeliveryQ (uint16 sid)
 
void printAssocBrief ()
 Utility: prints local/remote addr/port and app gate index/assocId. More...
 
void addPath (const L3Address &addr)
 
SCTPPathVariablesgetNextPath (const SCTPPathVariables *oldPath) const
 
const L3AddressgetNextAddress (const SCTPPathVariables *oldPath) const
 
SCTPPathVariablesgetNextDestination (SCTPDataVariables *chunk) const
 
void bytesAllowedToSend (SCTPPathVariables *path, const bool firstPass)
 
void pathStatusIndication (const SCTPPathVariables *path, const bool status)
 
bool allPathsInactive () const
 
void sendStreamResetRequest (SCTPResetInfo *info)
 
void sendStreamResetResponse (uint32 srrsn, int result)
 
void sendStreamResetResponse (SCTPSSNTSNResetRequestParameter *requestParam, int result, bool options)
 
void sendOutgoingResetRequest (SCTPIncomingSSNResetRequestParameter *requestParam)
 
void sendAddOutgoingStreamsRequest (uint16 numStreams)
 
void sendBundledOutgoingResetAndResponse (SCTPIncomingSSNResetRequestParameter *requestParam)
 
void sendAddInAndOutStreamsRequest (SCTPResetInfo *info)
 
void sendDoubleStreamResetResponse (uint32 insrrsn, uint16 inresult, uint32 outsrrsn, uint16 outresult)
 
void checkStreamsToReset ()
 
void sendPacketDrop (const bool flag)
 
void sendHMacError (const uint16 id)
 
void sendInvalidStreamError (uint16 sid)
 
void resetGapLists ()
 
SCTPForwardTsnChunkcreateForwardTsnChunk (const L3Address &pid)
 
bool msgMustBeAbandoned (SCTPDataMsg *msg, int32 stream, bool ordered)
 
bool chunkMustBeAbandoned (SCTPDataVariables *chunk, SCTPPathVariables *sackPath)
 
void advancePeerTsn ()
 
void cucProcessGapReports (const SCTPDataVariables *chunk, SCTPPathVariables *path, const bool isAcked)
 
SCTPDataChunktransformDataChunk (SCTPDataVariables *chunk)
 Manipulating chunks. More...
 
SCTPDataVariablesmakeVarFromMsg (SCTPDataChunk *datachunk)
 
int32 streamScheduler (SCTPPathVariables *path, bool peek)
 Dealing with streams. More...
 
void initStreams (uint32 inStreams, uint32 outStreams)
 
void addInStreams (uint32 inStreams)
 
void addOutStreams (uint32 outStreams)
 
int32 numUsableStreams ()
 
int32 streamSchedulerRoundRobinPacket (SCTPPathVariables *path, bool peek)
 
int32 streamSchedulerRandom (SCTPPathVariables *path, bool peek)
 
int32 streamSchedulerRandomPacket (SCTPPathVariables *path, bool peek)
 
int32 streamSchedulerFairBandwidth (SCTPPathVariables *path, bool peek)
 
int32 streamSchedulerFairBandwidthPacket (SCTPPathVariables *path, bool peek)
 
int32 streamSchedulerPriority (SCTPPathVariables *path, bool peek)
 
int32 streamSchedulerFCFS (SCTPPathVariables *path, bool peek)
 
int32 pathStreamSchedulerManual (SCTPPathVariables *path, bool peek)
 
int32 pathStreamSchedulerMapToPath (SCTPPathVariables *path, bool peek)
 
void process_QUEUE_MSGS_LIMIT (const SCTPCommand *sctpCommand)
 Queue Management. More...
 
void process_QUEUE_BYTES_LIMIT (const SCTPCommand *sctpCommand)
 
int32 getOutstandingBytes () const
 
void dequeueAckedChunks (const uint32 tsna, SCTPPathVariables *path, simtime_t &rttEstimation)
 
SCTPDataMsgpeekOutboundDataMsg ()
 
SCTPDataVariablespeekAbandonedChunk (const SCTPPathVariables *path)
 
SCTPDataVariablesgetOutboundDataChunk (const SCTPPathVariables *path, const int32 availableSpace, const int32 availableCwnd)
 
void fragmentOutboundDataMsgs ()
 
SCTPDataMsgdequeueOutboundDataMsg (SCTPPathVariables *path, const int32 availableSpace, const int32 availableCwnd)
 
bool nextChunkFitsIntoPacket (SCTPPathVariables *path, int32 bytes)
 
void putInTransmissionQ (uint32 tsn, SCTPDataVariables *chunk)
 
uint32 getAllTransQ ()
 
void pmStartPathManagement ()
 Flow control. More...
 
void pmDataIsSentOn (SCTPPathVariables *path)
 
void pmClearPathCounter (SCTPPathVariables *path)
 
void pmRttMeasurement (SCTPPathVariables *path, const simtime_t &rttEstimation)
 
void disposeOf (SCTPMessage *sctpmsg)
 
void resetSsns ()
 Methods for Stream Reset. More...
 
void resetExpectedSsns ()
 
bool sendStreamPresent (uint16 sid)
 
bool receiveStreamPresent (uint16 sid)
 
void resetSsn (uint16 id)
 
void resetExpectedSsn (uint16 id)
 
uint32 getExpectedSsnOfStream (uint16 id)
 
uint32 getSsnOfStream (uint16 id)
 
SCTPParametermakeOutgoingStreamResetParameter (uint32 srsn, SCTPResetInfo *info)
 
SCTPParametermakeIncomingStreamResetParameter (uint32 srsn, SCTPResetInfo *info)
 
SCTPParametermakeSSNTSNResetParameter (uint32 srsn)
 
SCTPParametermakeAddStreamsRequestParameter (uint32 srsn, SCTPResetInfo *info)
 
void sendOutgoingRequestAndResponse (uint32 inRequestSn, uint32 outRequestSn)
 
void sendOutgoingRequestAndResponse (SCTPIncomingSSNResetRequestParameter *inRequestParam, SCTPOutgoingSSNResetRequestParameter *outRequestParam)
 
SCTPEventCode processInAndOutResetRequestArrived (SCTPIncomingSSNResetRequestParameter *inRequestParam, SCTPOutgoingSSNResetRequestParameter *outRequestParam)
 
SCTPEventCode processOutAndResponseArrived (SCTPOutgoingSSNResetRequestParameter *outRequestParam, SCTPStreamResetResponseParameter *responseParam)
 
SCTPEventCode processStreamResetArrived (SCTPStreamResetChunk *strResChunk)
 
void processOutgoingResetRequestArrived (SCTPOutgoingSSNResetRequestParameter *requestParam)
 
void processIncomingResetRequestArrived (SCTPIncomingSSNResetRequestParameter *requestParam)
 
void processSSNTSNResetRequestArrived (SCTPSSNTSNResetRequestParameter *requestParam)
 
void processResetResponseArrived (SCTPStreamResetResponseParameter *responseParam)
 
void processAddInAndOutResetRequestArrived (SCTPAddStreamsRequestParameter *addInRequestParam, SCTPAddStreamsRequestParameter *addOutRequestParam)
 
uint32 getBytesInFlightOfStream (uint16 sid)
 
bool getFragInProgressOfStream (uint16 sid)
 
void setFragInProgressOfStream (uint16 sid, bool frag)
 
bool orderedQueueEmptyOfStream (uint16 sid)
 
bool unorderedQueueEmptyOfStream (uint16 sid)
 
void sendAsconf (const char *type, const bool remote=false)
 Methods for Add-IP and AUTH. More...
 
void sendAsconfAck (const uint32 serialNumber)
 
SCTPEventCode processAsconfArrived (SCTPAsconfChunk *asconfChunk)
 
SCTPEventCode processAsconfAckArrived (SCTPAsconfAckChunk *asconfAckChunk)
 
void retransmitAsconf ()
 
bool typeInChunkList (const uint16 type)
 
bool typeInOwnChunkList (const uint16 type)
 
SCTPAsconfAckChunkcreateAsconfAckChunk (const uint32 serialNumber)
 
SCTPAuthenticationChunkcreateAuthChunk ()
 
SCTPSuccessIndicationcreateSuccessIndication (uint32 correlationId)
 
void calculateAssocSharedKey ()
 
bool compareRandom ()
 
void calculateRcvBuffer ()
 
void listOrderedQ ()
 
void tsnWasReneged (SCTPDataVariables *chunk, const SCTPPathVariables *sackPath, const int type)
 
void printOutstandingTsns ()
 
void initCCParameters (SCTPPathVariables *path)
 SCTPCCFunctions. More...
 
void updateFastRecoveryStatus (const uint32 lastTsnAck)
 
void cwndUpdateBeforeSack ()
 
void cwndUpdateAfterSack ()
 
void cwndUpdateAfterCwndTimeout (SCTPPathVariables *path)
 
void cwndUpdateAfterRtxTimeout (SCTPPathVariables *path)
 
void cwndUpdateMaxBurst (SCTPPathVariables *path)
 
void cwndUpdateBytesAcked (SCTPPathVariables *path, const uint32 ackedBytes, const bool ctsnaAdvanced)
 
int32 rpPathBlockingControl (SCTPPathVariables *path, const double reduction)
 
FSM transitions: analysing events and executing state transitions
SCTPEventCode preanalyseAppCommandEvent (int32 commandCode)
 Maps app command codes (msg kind of app command msgs) to SCTP_E_xxx event codes. More...
 
bool performStateTransition (const SCTPEventCode &event)
 Implemements the pure SCTP state machine. More...
 
void stateEntered (int32 state)
 
Processing app commands. Invoked from processAppCommand().
void process_ASSOCIATE (SCTPEventCode &event, SCTPCommand *sctpCommand, cMessage *msg)
 
void process_OPEN_PASSIVE (SCTPEventCode &event, SCTPCommand *sctpCommand, cMessage *msg)
 
void process_SEND (SCTPEventCode &event, SCTPCommand *sctpCommand, cMessage *msg)
 
void process_CLOSE (SCTPEventCode &event)
 
void process_ABORT (SCTPEventCode &event)
 
void process_STATUS (SCTPEventCode &event, SCTPCommand *sctpCommand, cMessage *msg)
 
void process_RECEIVE_REQUEST (SCTPEventCode &event, SCTPCommand *sctpCommand)
 
void process_PRIMARY (SCTPEventCode &event, SCTPCommand *sctpCommand)
 
void process_STREAM_RESET (SCTPCommand *sctpCommand)
 
Processing SCTP message arrivals. Invoked from processSCTPMessage().
bool process_RCV_Message (SCTPMessage *sctpseg, const L3Address &src, const L3Address &dest)
 
bool processInitArrived (SCTPInitChunk *initChunk, int32 sport, int32 dport)
 Process incoming SCTP packets. More...
 
bool processInitAckArrived (SCTPInitAckChunk *initAckChunk)
 
bool processCookieEchoArrived (SCTPCookieEchoChunk *cookieEcho, L3Address addr)
 
bool processCookieAckArrived ()
 
SCTPEventCode processDataArrived (SCTPDataChunk *dataChunk)
 
SCTPEventCode processSackArrived (SCTPSackChunk *sackChunk)
 
SCTPEventCode processHeartbeatAckArrived (SCTPHeartbeatAckChunk *heartbeatack, SCTPPathVariables *path)
 
SCTPEventCode processForwardTsnArrived (SCTPForwardTsnChunk *forChunk)
 
bool processPacketDropArrived (SCTPPacketDropChunk *pktdrop)
 
void processErrorArrived (SCTPErrorChunk *error)
 
Processing timeouts. Invoked from processTimer().
void process_TIMEOUT_RTX (SCTPPathVariables *path)
 
void process_TIMEOUT_BLOCKING (SCTPPathVariables *path)
 
void process_TIMEOUT_HEARTBEAT (SCTPPathVariables *path)
 
void process_TIMEOUT_HEARTBEAT_INTERVAL (SCTPPathVariables *path, bool force)
 
void process_TIMEOUT_INIT_REXMIT (SCTPEventCode &event)
 
void process_TIMEOUT_PROBING ()
 
void process_TIMEOUT_SHUTDOWN (SCTPEventCode &event)
 
int32 updateCounters (SCTPPathVariables *path)
 
void process_TIMEOUT_RESET (SCTPPathVariables *path)
 
void process_TIMEOUT_ASCONF (SCTPPathVariables *path)
 

Static Protected Member Functions

static void printSegmentBrief (SCTPMessage *sctpmsg)
 Utility: prints important header fields. More...
 
static const char * eventName (const int32 event)
 Utility: returns name of SCTP_E_xxx constants. More...
 

Protected Attributes

IRoutingTablert
 
IInterfaceTableift
 
AddressVector localAddressList
 
AddressVector remoteAddressList
 
uint32 numberOfRemoteAddresses
 
uint32 inboundStreams
 
uint32 outboundStreams
 
uint32 initInboundStreams
 
int32 status
 
uint32 initTsn
 
uint32 initPeerTsn
 
uint32 sackFrequency
 
double sackPeriod
 
CCFunctions ccFunctions
 
uint16 ccModule
 
cOutVector * advRwnd
 
cOutVector * cumTsnAck
 
cOutVector * sendQueue
 
cOutVector * numGapBlocks
 
SCTPStateVariablesstate
 
BytesToBeSent bytes
 
SCTPsctpMain
 
cFSM * fsm
 
SCTPPathMap sctpPathMap
 
QueueCounter qCounter
 
SCTPQueuetransmissionQ
 
SCTPQueueretransmissionQ
 
SCTPSendStreamMap sendStreams
 
SCTPReceiveStreamMap receiveStreams
 
SCTPAlgorithmsctpAlgorithm
 
cOutVector * statisticsOutstandingBytes
 
cOutVector * statisticsQueuedReceivedBytes
 
cOutVector * statisticsQueuedSentBytes
 
cOutVector * statisticsTotalSSthresh
 
cOutVector * statisticsTotalCwnd
 
cOutVector * statisticsTotalBandwidth
 
cOutVector * statisticsRevokableGapBlocksInLastSACK
 
cOutVector * statisticsNonRevokableGapBlocksInLastSACK
 
cOutVector * statisticsArwndInLastSACK
 
cOutVector * statisticsPeerRwnd
 
cOutVector * statisticsNumTotalGapBlocksStored
 
cOutVector * statisticsNumRevokableGapBlocksStored
 
cOutVector * statisticsNumNonRevokableGapBlocksStored
 
cOutVector * statisticsNumDuplicatesStored
 
cOutVector * statisticsNumRevokableGapBlocksSent
 
cOutVector * statisticsNumNonRevokableGapBlocksSent
 
cOutVector * statisticsNumDuplicatesSent
 
cOutVector * statisticsSACKLengthSent
 
SSFunctions ssFunctions
 
uint16 ssModule
 

Private Types

typedef std::map< L3Address, SCTPPathVariables * > SCTPPathMap
 
typedef std::map< L3Address, uint32CounterMap
 
typedef struct inet::sctp::SCTPAssociation::counter QueueCounter
 
typedef struct inet::sctp::SCTPAssociation::calcBytesToSend BytesToBeSent
 
typedef struct inet::sctp::SCTPAssociation::congestionControlFunctions CCFunctions
 
typedef std::map< uint32, SCTPSendStream * > SCTPSendStreamMap
 
typedef std::map< uint32, SCTPReceiveStream * > SCTPReceiveStreamMap
 
typedef std::map< uint32, SCTPPathVariables * > SCTPPathCollection
 

Private Member Functions

SCTPDataVariablesmakeDataVarFromDataMsg (SCTPDataMsg *datMsg, SCTPPathVariables *path)
 
SCTPPathVariableschoosePathForRetransmission ()
 
void timeForSack (bool &sackOnly, bool &sackWithData)
 
void recordCwndUpdate (SCTPPathVariables *path)
 
void sendSACKviaSelectedPath (SCTPMessage *sctpMsg)
 
void checkOutstandingBytes ()
 
void updateHighSpeedCCThresholdIdx (SCTPPathVariables *path)
 
uint32 getInitialCwnd (const SCTPPathVariables *path) const
 
void generateSendQueueAbatedIndication (const uint64 bytes)
 
void renegablyAckChunk (SCTPDataVariables *chunk, SCTPPathVariables *sackPath)
 
void nonRenegablyAckChunk (SCTPDataVariables *chunk, SCTPPathVariables *sackPath, simtime_t &rttEstimation, SCTP::AssocStat *assocStat)
 
void handleChunkReportedAsAcked (uint32 &highestNewAck, simtime_t &rttEstimation, SCTPDataVariables *myChunk, SCTPPathVariables *sackPath, const bool sackIsNonRevokable)
 
void handleChunkReportedAsMissing (const SCTPSackChunk *sackChunk, const uint32 highestNewAck, SCTPDataVariables *myChunk, SCTPPathVariables *sackPath)
 
void moveChunkToOtherPath (SCTPDataVariables *chunk, SCTPPathVariables *newPath)
 
void decreaseOutstandingBytes (SCTPDataVariables *chunk)
 
void increaseOutstandingBytes (SCTPDataVariables *chunk, SCTPPathVariables *path)
 
int32 calculateBytesToSendOnPath (const SCTPPathVariables *pathVar)
 
void storePacket (SCTPPathVariables *pathVar, SCTPMessage *sctpMsg, const uint16 chunksAdded, const uint16 dataChunksAdded, const bool authAdded)
 
void loadPacket (SCTPPathVariables *pathVar, SCTPMessage **sctpMsg, uint16 *chunksAdded, uint16 *dataChunksAdded, bool *authAdded)
 
void ackChunk (SCTPDataVariables *chunk, SCTPPathVariables *sackPath)
 
void unackChunk (SCTPDataVariables *chunk)
 
bool chunkHasBeenAcked (const SCTPDataVariables *chunk) const
 
bool chunkHasBeenAcked (const uint32 tsn) const
 
void checkPseudoCumAck (const SCTPPathVariables *path)
 
std::vector< SCTPPathVariables * > getSortedPathMap ()
 
void chunkReschedulingControl (SCTPPathVariables *path)
 
void recalculateOLIABasis ()
 
uint32 updateOLIA (uint32 w, const uint32 s, const uint32 totalW, double a, const uint32 mtu, const uint32 ackedBytes, SCTPPathVariables *path)
 w: cwnd of the path s: ssthresh of the path totalW: Sum of all cwnds of the association a: factor alpha of olia calculation - see https://tools.ietf.org/html/draft-khalili-mptcp-congestion-control-05 mtu: mtu of the path ackedBytes: ackednowlged bytes path: path variable (for further investigation, debug, etc) More...
 
bool addAuthChunkIfNecessary (SCTPMessage *sctpMsg, const uint16 chunkType, const bool authAdded)
 

Static Private Member Functions

static bool pathMapLargestSSThreshold (const SCTPPathVariables *left, const SCTPPathVariables *right)
 
static bool pathMapLargestSpace (const SCTPPathVariables *left, const SCTPPathVariables *right)
 
static bool pathMapLargestSpaceAndSSThreshold (const SCTPPathVariables *left, const SCTPPathVariables *right)
 
static bool pathMapSmallestLastTransmission (const SCTPPathVariables *left, const SCTPPathVariables *right)
 
static bool pathMapRandomized (const SCTPPathVariables *left, const SCTPPathVariables *right)
 

Private Attributes

SCTPPathCollection assocBestPaths
 
SCTPPathCollection assocMaxWndPaths
 
SCTPPathCollection assocCollectedPaths
 

Friends

class SCTP
 
class SCTPPathVariables
 
int32 getFsmState () const
 
SCTPStateVariablesgetState () const
 
SCTPQueuegetTransmissionQueue () const
 
SCTPQueuegetRetransmissionQueue () const
 
SCTPAlgorithmgetSctpAlgorithm () const
 
SCTPgetSctpMain () const
 
cFSM * getFsm () const
 
cMessage * getInitTimer () const
 
cMessage * getShutdownTimer () const
 
cMessage * getSackTimer () const
 
bool processTimer (cMessage *msg)
 
bool processSCTPMessage (SCTPMessage *sctpmsg, const L3Address &srcAddr, const L3Address &destAddr)
 Process incoming SCTP segment. More...
 
bool processAppCommand (cMessage *msg)
 Process commands from the application. More...
 
void removePath ()
 
void removePath (const L3Address &addr)
 
void deleteStreams ()
 
void stopTimer (cMessage *timer)
 
void stopTimers ()
 
SCTPPathVariablesgetPath (const L3Address &pathId) const
 
void printSctpPathMap () const
 
static const char * stateName (const int32 state)
 Utility: returns name of SCTP_S_xxx constants. More...
 
static uint16 chunkToInt (const char *type)
 
static int32 tsnGe (const uint32 tsn1, const uint32 tsn2)
 
static int32 tsnGt (const uint32 tsn1, const uint32 tsn2)
 
static int32 tsnLe (const uint32 tsn1, const uint32 tsn2)
 
static int32 tsnLt (const uint32 tsn1, const uint32 tsn2)
 
static int32 tsnBetween (const uint32 tsn1, const uint32 midtsn, const uint32 tsn2)
 
static int16 ssnGt (const uint16 ssn1, const uint16 ssn2)
 
static int32 midGt (const uint32 mid1, const uint32 mid2)
 

Member Typedef Documentation

Constructor & Destructor Documentation

inet::sctp::SCTPAssociation::SCTPAssociation ( SCTP mod,
int32  appGateIndex,
int32  assocId,
IRoutingTable rt,
IInterfaceTable ift 
)

Constructor.

Referenced by cloneAssociation().

571 {
572  // ====== Initialize variables ===========================================
573  rt = _rt;
574  ift = _ift;
575  sctpMain = _module;
576  appGateIndex = _appGateIndex;
577  assocId = _assocId;
578  fd = -1;
579  listening = false;
580  localPort = 0;
581  remotePort = 0;
582  localVTag = 0;
583  peerVTag = 0;
587  initInboundStreams = 0;
588  // queues and algorithm will be created on active or passive open
589  transmissionQ = nullptr;
590  retransmissionQ = nullptr;
591  sctpAlgorithm = nullptr;
592  state = nullptr;
594 
595  cumTsnAck = nullptr;
596  sendQueue = nullptr;
597  numGapBlocks = nullptr;
598 
602  bytes.chunk = false;
603  bytes.packet = false;
604  bytes.bytesToSend = 0;
605 
606  fairTimer = false;
608  initTsn = 0;
609  initPeerTsn = 0;
610  sackFrequency = 2;
611  ccFunctions.ccInitParams = nullptr;
613  ccFunctions.ccUpdateAfterSack = nullptr;
616  ccFunctions.ccUpdateMaxBurst = nullptr;
618  ccModule = 0;
619  ssFunctions.ssInitStreams = nullptr;
620  ssFunctions.ssAddInStreams = nullptr;
621  ssFunctions.ssAddOutStreams = nullptr;
622  ssFunctions.ssGetNextSid = nullptr;
623  ssFunctions.ssUsableStreams = nullptr;
624 
625  EV_INFO << "SCTPAssociationBase::SCTPAssociation(): new assocId="
626  << assocId << endl;
627 
628  // ====== FSM ============================================================
629  char fsmName[64];
630  snprintf(fsmName, sizeof(fsmName), "fsm-%d", assocId);
631  fsm = new cFSM();
632  fsm->setName(fsmName);
633  fsm->setState(SCTP_S_CLOSED);
634 
635  // ====== Path Info ======================================================
636  SCTPPathInfo *pinfo = new SCTPPathInfo("pathInfo");
637  pinfo->setRemoteAddress(L3Address());
638 
639  // ====== Timers =========================================================
640  char timerName[128];
641  snprintf(timerName, sizeof(timerName), "T1_INIT of Association %d", assocId);
642  T1_InitTimer = new cMessage(timerName);
643  snprintf(timerName, sizeof(timerName), "T2_SHUTDOWN of Association %d", assocId);
644  T2_ShutdownTimer = new cMessage(timerName);
645  snprintf(timerName, sizeof(timerName), "T5_SHUTDOWN_GUARD of Association %d", assocId);
646  T5_ShutdownGuardTimer = new cMessage(timerName);
647  snprintf(timerName, sizeof(timerName), "SACK_TIMER of Association %d", assocId);
648  SackTimer = new cMessage(timerName);
649 
650  StartTesting = nullptr;
651  if (sctpMain->testTimeout > 0) {
652  StartTesting = new cMessage("StartTesting");
653  StartTesting->setContextPointer(this);
654  StartTesting->setControlInfo(pinfo->dup());
656  }
657 
658  T1_InitTimer->setContextPointer(this);
659  T2_ShutdownTimer->setContextPointer(this);
660  SackTimer->setContextPointer(this);
661  T5_ShutdownGuardTimer->setContextPointer(this);
662 
663  T1_InitTimer->setControlInfo(pinfo);
664  T2_ShutdownTimer->setControlInfo(pinfo->dup());
665  SackTimer->setControlInfo(pinfo->dup());
666  T5_ShutdownGuardTimer->setControlInfo(pinfo->dup());
667 
668  // ====== Output vectors =================================================
669  char vectorName[128];
670  snprintf(vectorName, sizeof(vectorName), "Advertised Receiver Window %d", assocId);
671  advRwnd = new cOutVector(vectorName);
672 
673  snprintf(vectorName, sizeof(vectorName), "Slow Start Threshold %d:Total", assocId);
674  statisticsTotalSSthresh = new cOutVector(vectorName);
675  snprintf(vectorName, sizeof(vectorName), "Congestion Window %d:Total", assocId);
676  statisticsTotalCwnd = new cOutVector(vectorName);
677  snprintf(vectorName, sizeof(vectorName), "Bandwidth %d:Total", assocId);
678  statisticsTotalBandwidth = new cOutVector(vectorName);
679  snprintf(vectorName, sizeof(vectorName), "Queued Received Bytes %d:Total", assocId);
680  statisticsQueuedReceivedBytes = new cOutVector(vectorName);
681  snprintf(vectorName, sizeof(vectorName), "Queued Sent Bytes %d:Total", assocId);
682  statisticsQueuedSentBytes = new cOutVector(vectorName);
683  snprintf(vectorName, sizeof(vectorName), "Outstanding Bytes %d:Total", assocId);
684  statisticsOutstandingBytes = new cOutVector(vectorName);
685 
686  snprintf(vectorName, sizeof(vectorName), "Number of Revokable Gap Blocks in SACK %d", assocId);
687  statisticsRevokableGapBlocksInLastSACK = new cOutVector(vectorName);
688  snprintf(vectorName, sizeof(vectorName), "Number of Non-Revokable Gap Blocks in SACK %d", assocId);
689  statisticsNonRevokableGapBlocksInLastSACK = new cOutVector(vectorName);
690 
691  snprintf(vectorName, sizeof(vectorName), "Number of Total Gap Blocks Stored %d", assocId);
692  statisticsNumTotalGapBlocksStored = new cOutVector(vectorName);
693  snprintf(vectorName, sizeof(vectorName), "Number of Revokable Gap Blocks Stored %d", assocId);
694  statisticsNumRevokableGapBlocksStored = new cOutVector(vectorName);
695  snprintf(vectorName, sizeof(vectorName), "Number of Non-Revokable Gap Blocks Stored %d", assocId);
696  statisticsNumNonRevokableGapBlocksStored = new cOutVector(vectorName);
697  snprintf(vectorName, sizeof(vectorName), "Number of Duplicate TSNs Stored %d", assocId);
698  statisticsNumDuplicatesStored = new cOutVector(vectorName);
699 
700  snprintf(vectorName, sizeof(vectorName), "Number of Revokable Gap Blocks Sent %d", assocId);
701  statisticsNumRevokableGapBlocksSent = new cOutVector(vectorName);
702  snprintf(vectorName, sizeof(vectorName), "Number of Non-Revokable Gap Blocks Sent %d", assocId);
703  statisticsNumNonRevokableGapBlocksSent = new cOutVector(vectorName);
704  snprintf(vectorName, sizeof(vectorName), "Number of Duplicate TSNs Sent %d", assocId);
705  statisticsNumDuplicatesSent = new cOutVector(vectorName);
706  snprintf(vectorName, sizeof(vectorName), "Length of SACK Sent %d", assocId);
707  statisticsSACKLengthSent = new cOutVector(vectorName);
708 
709  snprintf(vectorName, sizeof(vectorName), "Arwnd in Last SACK %d", assocId);
710  statisticsArwndInLastSACK = new cOutVector(vectorName);
711  snprintf(vectorName, sizeof(vectorName), "Peer Rwnd %d", assocId);
712  statisticsPeerRwnd = new cOutVector(vectorName);
713 
714  // ====== Extensions =====================================================
715  StartAddIP = new cMessage("addIP");
716  StartAddIP->setContextPointer(this);
717  StartAddIP->setControlInfo(pinfo->dup());
718  FairStartTimer = new cMessage("fairStart");
719  FairStartTimer->setContextPointer(this);
720  FairStartTimer->setControlInfo(pinfo->dup());
721  FairStopTimer = new cMessage("fairStop");
722  FairStopTimer->setContextPointer(this);
723  FairStopTimer->setControlInfo(pinfo->dup());
724  snprintf(vectorName, sizeof(vectorName), "Advertised Message Receiver Window of Association %d", assocId);
725  advMsgRwnd = new cOutVector(vectorName);
726  snprintf(vectorName, sizeof(vectorName), "End to End Delay of Association %d", assocId);
727  EndToEndDelay = new cOutVector(vectorName);
728 
729  // ====== Assoc throughput ===============================================
730  snprintf(vectorName, sizeof(vectorName), "Throughput of Association %d", assocId);
731  assocThroughputVector = new cOutVector(vectorName);
732  assocThroughputVector->record(0.0);
733 
734  // ====== CMT Delayed Ack ================================================
735  dacPacketsRcvd = 0;
736 
737  // ====== Stream scheduling ==============================================
738  ssModule = sctpMain->par("ssModule");
739 
740  switch (ssModule) {
741  case ROUND_ROBIN:
747  EV_DETAIL << "Setting Stream Scheduler: ROUND_ROBIN" << endl;
748  break;
749 
750  case ROUND_ROBIN_PACKET:
756  EV_DETAIL << "Setting Stream Scheduler: ROUND_ROBIN_PACKET" << endl;
757  break;
758 
759  case RANDOM_SCHEDULE:
765  EV_DETAIL << "Setting Stream Scheduler: RANDOM_SCHEDULE" << endl;
766  break;
767 
774  EV_DETAIL << "Setting Stream Scheduler: RANDOM_SCHEDULE_PACKET" << endl;
775  break;
776 
777  case FAIR_BANDWITH:
783  EV_DETAIL << "Setting Stream Scheduler: FAIR_BANDWITH" << endl;
784  break;
785 
792  EV_DETAIL << "Setting Stream Scheduler: FAIR_BANDWITH_PACKET" << endl;
793  break;
794 
795  case PRIORITY:
801  EV_DETAIL << "Setting Stream Scheduler: PRIORITY" << endl;
802  break;
803 
804  case FCFS:
808  EV_DETAIL << "Setting Stream Scheduler: FCFS" << endl;
809  break;
810 
811  case PATH_MANUAL:
817  EV_DETAIL << "Setting Stream Scheduler: PATH_MANUAL" << endl;
818  break;
819 
820  case PATH_MAP_TO_PATH:
826  EV_DETAIL << "Setting Stream Scheduler: PATH_MAP_TO_PATH" << endl;
827  break;
828  }
829 }
uint32 initTsn
Definition: SCTPAssociation.h:947
cOutVector * advMsgRwnd
Definition: SCTPAssociation.h:925
uint16 ccModule
Definition: SCTPAssociation.h:952
uint32 sackFrequency
Definition: SCTPAssociation.h:949
uint32 localVTag
Definition: SCTPAssociation.h:915
cMessage * FairStartTimer
Definition: SCTPAssociation.h:930
cOutVector * statisticsNumRevokableGapBlocksStored
Definition: SCTPAssociation.h:986
int32 status
Definition: SCTPAssociation.h:946
cOutVector * statisticsNumDuplicatesStored
Definition: SCTPAssociation.h:988
cOutVector * statisticsTotalBandwidth
Definition: SCTPAssociation.h:978
cOutVector * statisticsNumNonRevokableGapBlocksStored
Definition: SCTPAssociation.h:987
int32 numUsableStreams()
Definition: SCTPSSFunctions.cc:143
uint32 numberOfRemoteAddresses
Definition: SCTPAssociation.h:941
simtime_t testTimeout
Definition: SCTP.h:206
BytesToBeSent bytes
Definition: SCTPAssociation.h:961
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
int32 streamSchedulerRoundRobinPacket(SCTPPathVariables *path, bool peek)
Definition: SCTPSSFunctions.cc:154
void(SCTPAssociation::* ssInitStreams)(uint32 inStreams, uint32 outStreams)
Definition: SCTPAssociation.h:1288
cOutVector * sendQueue
Definition: SCTPAssociation.h:956
IInterfaceTable * ift
Definition: SCTPAssociation.h:937
cOutVector * EndToEndDelay
Definition: SCTPAssociation.h:926
int32 streamSchedulerFairBandwidth(SCTPPathVariables *path, bool peek)
Definition: SCTPSSFunctions.cc:294
cOutVector * statisticsRevokableGapBlocksInLastSACK
Definition: SCTPAssociation.h:980
cOutVector * statisticsQueuedReceivedBytes
Definition: SCTPAssociation.h:974
uint32 initPeerTsn
Definition: SCTPAssociation.h:948
#define SCTP_DEFAULT_INBOUND_STREAMS
Definition: SCTPAssociation.h:238
cMessage * FairStopTimer
Definition: SCTPAssociation.h:931
uint64 roomSumRcvStreams
Definition: SCTPAssociation.h:877
cOutVector * statisticsNumNonRevokableGapBlocksSent
Definition: SCTPAssociation.h:990
int32(SCTPAssociation::* ssGetNextSid)(SCTPPathVariables *path, bool peek)
Definition: SCTPAssociation.h:1291
void(SCTPAssociation::* ccUpdateAfterCwndTimeout)(SCTPPathVariables *path)
Definition: SCTPAssociation.h:893
void(SCTPAssociation::* ssAddInStreams)(uint32 inStreams)
Definition: SCTPAssociation.h:1289
Definition: SCTPAssociation.h:207
cOutVector * statisticsNumDuplicatesSent
Definition: SCTPAssociation.h:991
void(SCTPAssociation::* ccUpdateBeforeSack)()
Definition: SCTPAssociation.h:891
cOutVector * statisticsSACKLengthSent
Definition: SCTPAssociation.h:992
uint32 outboundStreams
Definition: SCTPAssociation.h:943
cMessage * T5_ShutdownGuardTimer
Definition: SCTPAssociation.h:921
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
uint32 inboundStreams
Definition: SCTPAssociation.h:942
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
cMessage * SackTimer
Definition: SCTPAssociation.h:922
uint8_t dacPacketsRcvd
Definition: SCTPAssociation.h:933
cMessage * StartTesting
Definition: SCTPAssociation.h:923
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void(SCTPAssociation::* ssAddOutStreams)(uint32 outStreams)
Definition: SCTPAssociation.h:1290
Definition: SCTPAssociation.h:206
cOutVector * statisticsNonRevokableGapBlocksInLastSACK
Definition: SCTPAssociation.h:981
bool chunk
Definition: SCTPAssociation.h:884
Definition: SCTPAssociation.h:208
CCFunctions ccFunctions
Definition: SCTPAssociation.h:951
cOutVector * statisticsNumRevokableGapBlocksSent
Definition: SCTPAssociation.h:989
uint64 bookedSumSendStreams
Definition: SCTPAssociation.h:876
void(SCTPAssociation::* ccUpdateMaxBurst)(SCTPPathVariables *path)
Definition: SCTPAssociation.h:895
uint32 peerVTag
Definition: SCTPAssociation.h:916
Definition: SCTPAssociation.h:209
int32 fd
Definition: SCTPAssociation.h:909
cOutVector * statisticsTotalCwnd
Definition: SCTPAssociation.h:977
void(SCTPAssociation::* ccUpdateBytesAcked)(SCTPPathVariables *path, const uint32 ackedBytes, const bool ctsnaAdvanced)
Definition: SCTPAssociation.h:896
void addOutStreams(uint32 outStreams)
Definition: SCTPSSFunctions.cc:80
void(SCTPAssociation::* ccUpdateAfterRtxTimeout)(SCTPPathVariables *path)
Definition: SCTPAssociation.h:894
cMessage * T2_ShutdownTimer
Definition: SCTPAssociation.h:920
cOutVector * numGapBlocks
Definition: SCTPAssociation.h:957
QueueCounter qCounter
Definition: SCTPAssociation.h:965
Definition: SCTPAssociation.h:202
int32 pathStreamSchedulerMapToPath(SCTPPathVariables *path, bool peek)
Definition: SCTPSSFunctions.cc:498
void(SCTPAssociation::* ccInitParams)(SCTPPathVariables *path)
Definition: SCTPAssociation.h:890
IRoutingTable * rt
Definition: SCTPAssociation.h:936
bool packet
Definition: SCTPAssociation.h:885
Definition: SCTPAssociation.h:201
bool fairTimer
Definition: SCTPAssociation.h:927
Definition: SCTPAssociation.h:203
cOutVector * statisticsQueuedSentBytes
Definition: SCTPAssociation.h:975
int32 streamSchedulerFairBandwidthPacket(SCTPPathVariables *path, bool peek)
Definition: SCTPSSFunctions.cc:301
uint32 initInboundStreams
Definition: SCTPAssociation.h:944
int32 streamScheduler(SCTPPathVariables *path, bool peek)
Dealing with streams.
Definition: SCTPSSFunctions.cc:101
void(SCTPAssociation::* ccUpdateAfterSack)()
Definition: SCTPAssociation.h:892
cOutVector * statisticsTotalSSthresh
Definition: SCTPAssociation.h:976
Definition: SCTPAssociation.h:205
int32 streamSchedulerPriority(SCTPPathVariables *path, bool peek)
Definition: SCTPSSFunctions.cc:246
int32 assocId
Definition: SCTPAssociation.h:908
bool listening
Definition: SCTPAssociation.h:910
cMessage * StartAddIP
Definition: SCTPAssociation.h:924
int32(SCTPAssociation::* ssUsableStreams)()
Definition: SCTPAssociation.h:1292
SCTPAlgorithm * sctpAlgorithm
Definition: SCTPAssociation.h:970
cOutVector * statisticsArwndInLastSACK
Definition: SCTPAssociation.h:982
Definition: SCTPAssociation.h:204
int32 pathStreamSchedulerManual(SCTPPathVariables *path, bool peek)
Definition: SCTPSSFunctions.cc:448
int32 appGateIndex
Definition: SCTPAssociation.h:907
cOutVector * assocThroughputVector
Definition: SCTPAssociation.h:929
cOutVector * cumTsnAck
Definition: SCTPAssociation.h:955
cFSM * fsm
Definition: SCTPAssociation.h:963
cOutVector * advRwnd
Definition: SCTPAssociation.h:954
void addInStreams(uint32 inStreams)
Definition: SCTPSSFunctions.cc:65
cOutVector * statisticsOutstandingBytes
Definition: SCTPAssociation.h:973
Definition: SCTPAssociation.h:57
int32 streamSchedulerFCFS(SCTPPathVariables *path, bool peek)
Definition: SCTPSSFunctions.cc:404
void initStreams(uint32 inStreams, uint32 outStreams)
Definition: SCTPSSFunctions.cc:44
SSFunctions ssFunctions
Definition: SCTPAssociation.h:1294
uint16 localPort
Definition: SCTPAssociation.h:913
cOutVector * statisticsNumTotalGapBlocksStored
Definition: SCTPAssociation.h:985
cOutVector * statisticsPeerRwnd
Definition: SCTPAssociation.h:983
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
int32 streamSchedulerRandomPacket(SCTPPathVariables *path, bool peek)
Definition: SCTPSSFunctions.cc:203
#define SACK_DELAY
Definition: SCTPAssociation.h:248
void scheduleTimeout(cMessage *msg, const simtime_t &timeout)
Utility: start a timer.
Definition: SCTPAssociation.h:1188
uint16 ssModule
Definition: SCTPAssociation.h:1295
int32 streamSchedulerRandom(SCTPPathVariables *path, bool peek)
Definition: SCTPSSFunctions.cc:196
uint32 bytesToSend
Definition: SCTPAssociation.h:886
#define SCTP_DEFAULT_OUTBOUND_STREAMS
Definition: SCTPAssociation.h:239
double sackPeriod
Definition: SCTPAssociation.h:950
Definition: SCTPAssociation.h:200
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
inet::sctp::SCTPAssociation::~SCTPAssociation ( )

Destructor.

832 {
833  EV_TRACE << "Destructor SCTPAssociation " << assocId << endl;
834 
835  delete T1_InitTimer;
836  delete T2_ShutdownTimer;
837  delete T5_ShutdownGuardTimer;
838  delete SackTimer;
839 
840  delete advRwnd;
841  delete cumTsnAck;
842  delete numGapBlocks;
843  delete sendQueue;
844 
849  delete statisticsTotalCwnd;
851 
862 
864  delete statisticsPeerRwnd;
865 
866  delete StartAddIP;
867  delete advMsgRwnd;
868  delete EndToEndDelay;
869 
870  int i = 0;
871  while (streamThroughputVectors[i] != nullptr) {
872  delete streamThroughputVectors[i++];
873  }
874  if (assocThroughputVector != nullptr)
875  delete assocThroughputVector;
876  if (FairStartTimer)
877  delete cancelEvent(FairStartTimer);
878  if (FairStopTimer)
879  delete cancelEvent(FairStopTimer);
880 
882  delete state->asconfChunk;
883 
884  delete fsm;
885  delete state;
886  delete sctpAlgorithm;
887 }
cOutVector * advMsgRwnd
Definition: SCTPAssociation.h:925
cMessage * FairStartTimer
Definition: SCTPAssociation.h:930
cOutVector * statisticsNumRevokableGapBlocksStored
Definition: SCTPAssociation.h:986
cOutVector * statisticsNumDuplicatesStored
Definition: SCTPAssociation.h:988
cOutVector * statisticsTotalBandwidth
Definition: SCTPAssociation.h:978
cOutVector * statisticsNumNonRevokableGapBlocksStored
Definition: SCTPAssociation.h:987
SCTPAsconfChunk * asconfChunk
Definition: SCTPAssociation.h:782
std::map< uint16, cOutVector * > streamThroughputVectors
Definition: SCTPAssociation.h:928
cOutVector * sendQueue
Definition: SCTPAssociation.h:956
cOutVector * EndToEndDelay
Definition: SCTPAssociation.h:926
cMessage * cancelEvent(cMessage *msg)
Utility: cancel a timer.
Definition: SCTPAssociation.h:1194
cOutVector * statisticsRevokableGapBlocksInLastSACK
Definition: SCTPAssociation.h:980
cOutVector * statisticsQueuedReceivedBytes
Definition: SCTPAssociation.h:974
cMessage * FairStopTimer
Definition: SCTPAssociation.h:931
cOutVector * statisticsNumNonRevokableGapBlocksSent
Definition: SCTPAssociation.h:990
cOutVector * statisticsNumDuplicatesSent
Definition: SCTPAssociation.h:991
cOutVector * statisticsSACKLengthSent
Definition: SCTPAssociation.h:992
cMessage * T5_ShutdownGuardTimer
Definition: SCTPAssociation.h:921
cMessage * SackTimer
Definition: SCTPAssociation.h:922
cOutVector * statisticsNonRevokableGapBlocksInLastSACK
Definition: SCTPAssociation.h:981
cOutVector * statisticsNumRevokableGapBlocksSent
Definition: SCTPAssociation.h:989
cOutVector * statisticsTotalCwnd
Definition: SCTPAssociation.h:977
cMessage * T2_ShutdownTimer
Definition: SCTPAssociation.h:920
cOutVector * numGapBlocks
Definition: SCTPAssociation.h:957
cOutVector * statisticsQueuedSentBytes
Definition: SCTPAssociation.h:975
cOutVector * statisticsTotalSSthresh
Definition: SCTPAssociation.h:976
bool asconfOutstanding
Definition: SCTPAssociation.h:781
int32 assocId
Definition: SCTPAssociation.h:908
cMessage * StartAddIP
Definition: SCTPAssociation.h:924
SCTPAlgorithm * sctpAlgorithm
Definition: SCTPAssociation.h:970
cOutVector * statisticsArwndInLastSACK
Definition: SCTPAssociation.h:982
cOutVector * assocThroughputVector
Definition: SCTPAssociation.h:929
cOutVector * cumTsnAck
Definition: SCTPAssociation.h:955
cFSM * fsm
Definition: SCTPAssociation.h:963
cOutVector * advRwnd
Definition: SCTPAssociation.h:954
cOutVector * statisticsOutstandingBytes
Definition: SCTPAssociation.h:973
cOutVector * statisticsNumTotalGapBlocksStored
Definition: SCTPAssociation.h:985
cOutVector * statisticsPeerRwnd
Definition: SCTPAssociation.h:983
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
SCTPStateVariables * state
Definition: SCTPAssociation.h:960

Member Function Documentation

void inet::sctp::SCTPAssociation::ackChunk ( SCTPDataVariables chunk,
SCTPPathVariables sackPath 
)
inlineprivate

Referenced by nonRenegablyAckChunk(), and renegablyAckChunk().

1438  {
1439  chunk->hasBeenAcked = true;
1440  chunk->ackedOnPath = sackPath;
1441  }
bool inet::sctp::SCTPAssociation::addAuthChunkIfNecessary ( SCTPMessage sctpMsg,
const uint16  chunkType,
const bool  authAdded 
)
inlineprivate

Referenced by sendOnPath().

1486  {
1487  if ((state->auth) && (state->peerAuth) && (typeInChunkList(chunkType)) && (authAdded == false)) {
1488  SCTPAuthenticationChunk *authChunk = createAuthChunk();
1489  sctpMsg->addChunk(authChunk);
1490  auto it = sctpMain->assocStatMap.find(assocId);
1491  it->second.numAuthChunksSent++;
1492  return true;
1493  }
1494  return false;
1495  }
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
bool auth
Definition: SCTPAssociation.h:822
SCTP * sctpMain
Definition: SCTPAssociation.h:962
AssocStatMap assocStatMap
Definition: SCTP.h:171
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::addInStreams ( uint32  inStreams)
protected

Referenced by SCTPAssociation(), and sendAddInAndOutStreamsRequest().

66 {
67  uint32 i, j;
68  char vectorName[128];
69  EV_INFO << "Add " << inStreams << " inbound streams" << endl;
70  for (i = receiveStreams.size(), j = 0; j < inStreams; i++, j++) {
71  SCTPReceiveStream *rcvStream = new SCTPReceiveStream(this);
72  this->receiveStreams[i] = rcvStream;
73  rcvStream->setStreamId(i);
74  this->state->numMsgsReq[i] = 0;
75  snprintf(vectorName, sizeof(vectorName), "Stream %d Throughput", i);
76  streamThroughputVectors[i] = new cOutVector(vectorName);
77  }
78 }
std::map< uint16, cOutVector * > streamThroughputVectors
Definition: SCTPAssociation.h:928
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
std::vector< int32 > numMsgsReq
Definition: SCTPAssociation.h:646
uint32_t uint32
Definition: Compat.h:30
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::addOutStreams ( uint32  outStreams)
protected

Referenced by SCTPAssociation(), and sendAddInAndOutStreamsRequest().

81 {
82  uint32 i, j;
83  EV_INFO << "Add " << outStreams << " outbound streams" << endl;
84  for (i = sendStreams.size(), j = 0; j < outStreams; i++, j++) {
85  SCTPSendStream *sendStream = new SCTPSendStream(this, i);
86  sendStream->setStreamId(i);
87  this->sendStreams[i] = sendStream;
88  }
89 }
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
uint32_t uint32
Definition: Compat.h:30
void inet::sctp::SCTPAssociation::addPath ( const L3Address addr)
protected

Referenced by processAsconfArrived(), and processInitAckArrived().

2038 {
2039  EV_INFO << "Add Path remote address: " << addr << "\n";
2040 
2041  auto i = sctpPathMap.find(addr);
2042  if (i == sctpPathMap.end()) {
2043  EV_DEBUG << " get new path for " << addr << " at line " << __LINE__ << "\n";
2044  SCTPPathVariables *path = new SCTPPathVariables(addr, this, rt);
2045  sctpPathMap[addr] = path;
2046  qCounter.roomTransQ[addr] = 0;
2047  qCounter.bookedTransQ[addr] = 0;
2048  qCounter.roomRetransQ[addr] = 0;
2049  }
2050  EV_INFO << "path added\n";
2051 }
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
CounterMap roomRetransQ
Definition: SCTPAssociation.h:880
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
QueueCounter qCounter
Definition: SCTPAssociation.h:965
IRoutingTable * rt
Definition: SCTPAssociation.h:936
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
void inet::sctp::SCTPAssociation::advancePeerTsn ( )
protected

Referenced by createForwardTsnChunk(), and processSackArrived().

2202 {
2203  // Rewrote code for efficiency, it consomed >40% of total CPU time before!
2204  // Find the highest TSN to advance to, not just the first one.
2205  auto iterator = retransmissionQ->payloadQueue.find(state->advancedPeerAckPoint + 1);
2206  while (iterator != retransmissionQ->payloadQueue.end()) {
2207  if (iterator->second->hasBeenAbandoned) {
2208  state->advancedPeerAckPoint = iterator->second->tsn;
2209  state->ackPointAdvanced = true;
2210  iterator++;
2211  }
2212  else {
2213  if (iterator->second->hasBeenAcked == true)
2214  iterator++;
2215  else
2216  break;
2217  }
2218  }
2219 
2220  EV_INFO << "advancedPeerTsnAck now=" << state->advancedPeerAckPoint << endl;
2221 }
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
uint32 advancedPeerAckPoint
Definition: SCTPAssociation.h:836
bool ackPointAdvanced
Definition: SCTPAssociation.h:574
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::allPathsInactive ( ) const
protected

Referenced by process_TIMEOUT_HEARTBEAT(), process_TIMEOUT_RTX(), and updateCounters().

2791 {
2792  for (const auto & elem : sctpPathMap) {
2793  if (elem.second->activePath) {
2794  return false;
2795  }
2796  }
2797  return true;
2798 }
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
void inet::sctp::SCTPAssociation::bytesAllowedToSend ( SCTPPathVariables path,
const bool  firstPass 
)
protected

Referenced by sendOnPath().

558 {
559  assert(path != nullptr);
560 
561  bytes.chunk = false;
562  bytes.packet = false;
563  bytes.bytesToSend = 0;
564 
565  EV_INFO << "bytesAllowedToSend(" << path->remoteAddress << "):"
566  << " osb=" << path->outstandingBytes << " cwnd=" << path->cwnd << endl;
567 
568  // ====== First transmission =============================================
569  if (!state->firstDataSent) {
570  bytes.chunk = true;
571  }
572  // ====== Transmission allowed by peer's receiver window? ================
573  else if ((state->peerWindowFull || (state->peerAllowsChunks && state->peerMsgRwnd <= 0)) && (path->outstandingBytes == 0)) {
574  // Zero Window Probing
575  EV_DETAIL << "bytesAllowedToSend(" << path->remoteAddress << "): zeroWindowProbing" << endl;
576  state->zeroWindowProbing = true;
577  bytes.chunk = true;
578  }
579  // ====== Retransmissions ================================================
580  else {
581  CounterMap::const_iterator it = qCounter.roomTransQ.find(path->remoteAddress);
582  EV_DETAIL << "bytesAllowedToSend(" << path->remoteAddress << "): bytes in transQ=" << it->second << endl;
583  if (it->second > 0) {
584  const int32 allowance = path->cwnd - path->outstandingBytes;
585  EV_DETAIL << "bytesAllowedToSend(" << path->remoteAddress << "): cwnd-osb=" << allowance << endl;
586  if (state->peerRwnd < path->pmtu) {
587  bytes.bytesToSend = 0;
588  bytes.chunk = true;
589  EV_DETAIL << "bytesAllowedToSend(" << path->remoteAddress << "): one chunk" << endl;
590  // RFC4960: When a Fast Retransmit is being performed, the sender SHOULD ignore the value
591  // of cwnd and SHOULD NOT delay retransmission for this single packet.
592  return;
593  }
594  else if (allowance > 0) {
595  CounterMap::const_iterator bit = qCounter.bookedTransQ.find(path->remoteAddress);
596  if (bit->second > (uint32)allowance) {
597  bytes.bytesToSend = allowance;
598  EV_DETAIL << "bytesAllowedToSend(" << path->remoteAddress << "): cwnd does not allow all RTX" << endl;
599  return; // More bytes available than allowed -> just return what is allowed.
600  }
601  else {
602  bytes.bytesToSend = bit->second;
603  EV_DETAIL << "bytesAllowedToSend(" << path->remoteAddress << "): cwnd allows more than those "
604  << bytes.bytesToSend << " bytes for retransmission" << endl;
605  }
606  }
607  else { // You may retransmit one packet
608  bytes.packet = true;
609  EV_DETAIL << "bytesAllowedToSend(" << path->remoteAddress << "): allowance<=0: retransmit one packet" << endl;
610  }
611  }
612 
613  // ====== New transmissions ===========================================
614  if (!bytes.chunk && !bytes.packet) {
615  (this->*ccFunctions.ccUpdateMaxBurst)(path);
616 
617  // ====== Get cwnd value to use, according to maxBurstVariant ======
618  uint32 myCwnd = path->cwnd;
621  {
622  myCwnd = path->tempCwnd;
623  }
624  // ====== Obtain byte allowance ====================================
625  if ((((state->peerAllowsChunks) &&
626  (path->outstandingBytes < myCwnd) &&
627  (!state->peerWindowFull) &&
628  (state->peerMsgRwnd > 0))
629  ||
630  ((!state->peerAllowsChunks) &&
631  (path->outstandingBytes < myCwnd) &&
632  (!state->peerWindowFull)))
633  &&
634  ((path->blockingTimeout < 0.0) || /* Chunk Rescheduling: no new transmission when blocking is active! */
635  (simTime() >= path->blockingTimeout)))
636  {
637  EV_DETAIL << "bytesAllowedToSend(" << path->remoteAddress << "):"
638  << " bookedSumSendStreams=" << qCounter.bookedSumSendStreams
639  << " bytes.bytesToSend=" << bytes.bytesToSend << endl;
640  const int32 allowance = myCwnd - path->outstandingBytes - bytes.bytesToSend;
641  if (allowance > 0) {
642  if (qCounter.bookedSumSendStreams > (uint32)allowance) {
643  bytes.bytesToSend = myCwnd - path->outstandingBytes;
644  EV_DETAIL << "bytesAllowedToSend(" << path->remoteAddress << "): bytesToSend are limited by cwnd: "
645  << bytes.bytesToSend << endl;
646  }
647  else {
649  EV_DETAIL << "bytesAllowedToSend(" << path->remoteAddress << "): send all stored bytes: "
650  << bytes.bytesToSend << endl;
651  }
652  }
653  // Do not send more than the peer's arwnd allows
655  }
656  }
657  }
658 
659  EV_INFO << "bytesAllowedToSend(" << path->remoteAddress << "):"
660  << " osb=" << path->outstandingBytes
661  << " cwnd=" << path->cwnd
662  << " tempCwnd=" << path->tempCwnd
663  << " bytes.packet=" << (bytes.packet ? "YES!" : "no")
664  << " bytes.chunk=" << (bytes.chunk ? "YES!" : "no")
665  << " bytes.bytesToSend=" << bytes.bytesToSend << endl;
666 }
MBVariant maxBurstVariant
Definition: SCTPAssociation.h:702
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
bool zeroWindowProbing
Definition: SCTPAssociation.h:582
uint64 peerRwnd
Definition: SCTPAssociation.h:610
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
BytesToBeSent bytes
Definition: SCTPAssociation.h:961
uint32 peerMsgRwnd
Definition: SCTPAssociation.h:841
bool chunk
Definition: SCTPAssociation.h:884
CCFunctions ccFunctions
Definition: SCTPAssociation.h:951
uint64 bookedSumSendStreams
Definition: SCTPAssociation.h:876
void(SCTPAssociation::* ccUpdateMaxBurst)(SCTPPathVariables *path)
Definition: SCTPAssociation.h:895
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
bool peerAllowsChunks
Definition: SCTPAssociation.h:838
QueueCounter qCounter
Definition: SCTPAssociation.h:965
bool packet
Definition: SCTPAssociation.h:885
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
bool firstDataSent
Definition: SCTPAssociation.h:594
bool peerWindowFull
Definition: SCTPAssociation.h:595
uint32 bytesToSend
Definition: SCTPAssociation.h:886
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::calculateAssocSharedKey ( )
protected
269 {
270  const bool peerFirst = compareRandom();
271  if (peerFirst == true) {
272  for (uint32 i = 0; i < state->sizeKeyVector; i++)
273  state->sharedKey[i] = state->keyVector[i];
274  for (uint32 i = 0; i < state->sizePeerKeyVector; i++)
276  }
277  else {
278  for (uint32 i = 0; i < state->sizePeerKeyVector; i++)
280  for (uint32 i = 0; i < state->sizeKeyVector; i++)
282  }
283 }
uint8 keyVector[512]
Definition: SCTPAssociation.h:825
uint32 sizePeerKeyVector
Definition: SCTPAssociation.h:828
uint8 peerKeyVector[512]
Definition: SCTPAssociation.h:827
bool compareRandom()
Definition: SCTPAssociationAddIP.cc:234
uint32_t uint32
Definition: Compat.h:30
uint8 sharedKey[512]
Definition: SCTPAssociation.h:829
uint32 sizeKeyVector
Definition: SCTPAssociation.h:826
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int32 inet::sctp::SCTPAssociation::calculateBytesToSendOnPath ( const SCTPPathVariables pathVar)
private
void inet::sctp::SCTPAssociation::calculateRcvBuffer ( )
protected

Referenced by createSack(), makeRoomForTsn(), makeVarFromMsg(), processDataArrived(), and processForwardTsnArrived().

50 {
51  uint32 sumDelivery = 0;
52  uint32 sumOrdered = 0;
53  uint32 sumUnOrdered = 0;
54  for (SCTPReceiveStreamMap::const_iterator iterator = receiveStreams.begin();
55  iterator != receiveStreams.end(); iterator++)
56  {
57  const SCTPReceiveStream *stream = iterator->second;
58  sumDelivery += stream->getDeliveryQ()->getQueueSize();
59  sumOrdered += stream->getOrderedQ()->getQueueSize();
60  sumUnOrdered += stream->getUnorderedQ()->getQueueSize();
61  }
62  EV_DEBUG << "DeliveryQ= " << sumDelivery
63  << ", OrderedQ=" << sumOrdered
64  << ", UnorderedQ=" << sumUnOrdered
65  << ", bufferedMessages=" << state->bufferedMessages
66  << endl;
67 }
uint32 bufferedMessages
Definition: SCTPAssociation.h:842
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
uint32_t uint32
Definition: Compat.h:30
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
cMessage* inet::sctp::SCTPAssociation::cancelEvent ( cMessage *  msg)
inlineprotected

Utility: cancel a timer.

Referenced by stopTimer().

1195  {
1196  return sctpMain->cancelEvent(msg);
1197  }
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void inet::sctp::SCTPAssociation::checkOutstandingBytes ( )
private
void inet::sctp::SCTPAssociation::checkPseudoCumAck ( const SCTPPathVariables path)
private
115 {
116  uint32 earliestOutstandingTSN = path->pseudoCumAck;
117  uint32 rtxEarliestOutstandingTSN = path->rtxPseudoCumAck;
118 
120  path->remoteAddress,
121  earliestOutstandingTSN, rtxEarliestOutstandingTSN);
122 
123  if (tsnGt(path->pseudoCumAck, earliestOutstandingTSN) ||
124  tsnGt(path->rtxPseudoCumAck, rtxEarliestOutstandingTSN)) {
125  std::cerr << "WRONG PSEUDO CUM-ACK!" << endl
126  << "pseudoCumAck=" << path->pseudoCumAck << ", earliestOutstandingTSN=" << earliestOutstandingTSN << endl
127  << "rtxPseudoCumAck=" << path->rtxPseudoCumAck << ", rtxEarliestOutstandingTSN=" << rtxEarliestOutstandingTSN << endl;
128  }
129 }
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
void findEarliestOutstandingTSNsForPath(const L3Address &remoteAddress, uint32 &earliestOutstandingTSN, uint32 &rtxEarliestOutstandingTSN) const
Definition: SCTPQueue.cc:208
uint32_t uint32
Definition: Compat.h:30
static int32 tsnGt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1081
void inet::sctp::SCTPAssociation::checkStreamsToReset ( )
protected

Referenced by process_RCV_Message().

41 {
44  state->streamsToReset.clear();
45  std::list<uint16>::iterator it;
46  for (it = state->streamsPending.begin(); it != state->streamsPending.end(); it++) {
47  if (getBytesInFlightOfStream(*it) == 0) {
48  state->streamsToReset.push_back(*it);
49  state->streamsPending.erase(it);
50  }
51  }
52  }
58  state->resetPending = true;
59  }
60  if (state->resetDeferred && (state->streamsToReset.size() > 0 || state->peerRequestType == SSN_TSN)) {
61  switch (state->peerRequestType) {
62  case SSN_TSN: {
63  SCTPSSNTSNResetRequestParameter *ssnParam = check_and_cast<SCTPSSNTSNResetRequestParameter *>(state->incomingRequest);
67  state->sendResponse = 0;
68  sendStreamResetResponse((SCTPSSNTSNResetRequestParameter *)state->incomingRequest, PERFORMED, true);
69  }
70  delete ssnParam;
71  break;
72  }
73  case RESET_INCOMING: {
74  SCTPIncomingSSNResetRequestParameter *inParam = check_and_cast<SCTPIncomingSSNResetRequestParameter *>(state->incomingRequest->dup());
75  state->incomingRequest->setName("StateSackIncoming");
76  inParam->setName("checkInParam");
78  if (state->incomingRequestSet && state->incomingRequest != nullptr) {
79  delete state->incomingRequest;
80  state->incomingRequest = nullptr;
81  state->incomingRequestSet = false;
82  }
83  delete inParam;
84  break;
85  }
86  }
87  state->resetDeferred = false;
89  (state->streamsToReset.size() > 0)) {
93  state->resetPending = true;
94  }
95  }
96 }
uint16 peerRequestType
Definition: SCTPAssociation.h:809
bool resetRequested
Definition: SCTPAssociation.h:590
bool fragInProgress
Definition: SCTPAssociation.h:601
uint32 getBytesInFlightOfStream(uint16 sid)
Definition: SCTPAssociationUtil.cc:78
Definition: SCTPAssociation.h:155
void resetExpectedSsns()
Definition: SCTPAssociationStreamReset.cc:845
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
void sendStreamResetRequest(SCTPResetInfo *info)
Definition: SCTPAssociationStreamReset.cc:483
uint16 sendResponse
Definition: SCTPAssociation.h:642
SCTPResetInfo * resetInfo
Definition: SCTPAssociation.h:808
uint16 localRequestType
Definition: SCTPAssociation.h:810
Definition: SCTPAssociation.h:150
std::list< uint16 > streamsPending
Definition: SCTPAssociation.h:803
uint64 outstandingBytes
Definition: SCTPAssociation.h:622
Definition: SCTPAssociation.h:151
QueueCounter qCounter
Definition: SCTPAssociation.h:965
void processSSNTSNResetRequestArrived(SCTPSSNTSNResetRequestParameter *requestParam)
Definition: SCTPAssociationRcvMessage.cc:2498
SCTPParameter * incomingRequest
Definition: SCTPAssociation.h:800
virtual SCTPParameter * dup() const override
Definition: SCTPMessage_m.h:1257
Definition: SCTPAssociation.h:153
std::list< uint16 > streamsToReset
Definition: SCTPAssociation.h:804
bool resetDeferred
Definition: SCTPAssociation.h:787
bool resetPending
Definition: SCTPAssociation.h:589
Definition: SCTPAssociation.h:163
Definition: SCTPAssociation.h:154
Definition: SCTPAssociation.h:144
void sendStreamResetResponse(uint32 srrsn, int result)
Definition: SCTPAssociationStreamReset.cc:763
void processIncomingResetRequestArrived(SCTPIncomingSSNResetRequestParameter *requestParam)
Definition: SCTPAssociationRcvMessage.cc:2412
bool incomingRequestSet
Definition: SCTPAssociation.h:602
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPPathVariables * inet::sctp::SCTPAssociation::choosePathForRetransmission ( )
private

Referenced by sendOnPath().

238 {
239  uint32 max = 0;
240  SCTPPathVariables *temp = nullptr;
241 
242  for (auto & elem : sctpPathMap) {
243  SCTPPathVariables *path = elem.second;
244  CounterMap::const_iterator tq = qCounter.roomTransQ.find(path->remoteAddress);
245  if ((tq != qCounter.roomTransQ.end()) && (tq->second > max)) {
246  max = tq->second;
247  temp = path;
248  }
249  }
250  return temp;
251 }
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
QueueCounter qCounter
Definition: SCTPAssociation.h:965
uint32_t uint32
Definition: Compat.h:30
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
double max(const double a, const double b)
Returns the maximum of a and b.
Definition: SCTPAssociation.h:275
bool inet::sctp::SCTPAssociation::chunkHasBeenAcked ( const SCTPDataVariables chunk) const
inlineprivate
bool inet::sctp::SCTPAssociation::chunkHasBeenAcked ( const uint32  tsn) const
inlineprivate
1454  {
1455  const SCTPDataVariables *chunk = retransmissionQ->getChunk(tsn);
1456  if (chunk) {
1457  return chunkHasBeenAcked(chunk);
1458  }
1459  return false;
1460  }
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
SCTPDataVariables * getChunk(const uint32 key) const
Definition: SCTPQueue.cc:123
bool chunkHasBeenAcked(const SCTPDataVariables *chunk) const
Definition: SCTPAssociation.h:1448
bool inet::sctp::SCTPAssociation::chunkMustBeAbandoned ( SCTPDataVariables chunk,
SCTPPathVariables sackPath 
)
protected

Referenced by handleChunkReportedAsMissing(), and process_TIMEOUT_RTX().

2266 {
2267  switch (chunk->prMethod) {
2268  case PR_TTL:
2269  if (chunk->expiryTime > 0 && chunk->expiryTime <= simTime()) {
2270  if (!chunk->hasBeenAbandoned) {
2271  EV_INFO << "TSN " << chunk->tsn << " will be abandoned"
2272  << " (expiryTime=" << chunk->expiryTime
2273  << " sendTime=" << chunk->sendTime << ")" << endl;
2274  chunk->hasBeenAbandoned = true;
2275  chunk->sendForwardIfAbandoned = true;
2277  }
2278  }
2279  break;
2280 
2281  case PR_RTX:
2282  if (chunk->numberOfRetransmissions >= chunk->allowedNoRetransmissions) {
2283  if (!chunk->hasBeenAbandoned) {
2284  EV_INFO << "chunkMustBeAbandoned: TSN " << chunk->tsn << " will be abandoned"
2285  << " (maxRetransmissions=" << chunk->allowedNoRetransmissions << ")" << endl;
2286  chunk->hasBeenAbandoned = true;
2287  chunk->sendForwardIfAbandoned = true;
2288  decreaseOutstandingBytes(chunk);
2289  chunk->countsAsOutstanding = false;
2291  }
2292  }
2293  break;
2294  }
2295 
2296  if (chunk->hasBeenAbandoned) {
2297  return true;
2298  }
2299  return false;
2300 }
Definition: SCTPAssociation.h:137
void decreaseOutstandingBytes(SCTPDataVariables *chunk)
Definition: SCTPAssociationRcvMessage.cc:41
Definition: SCTPAssociation.h:136
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
Definition: SCTPCommand.h:78
void inet::sctp::SCTPAssociation::chunkReschedulingControl ( SCTPPathVariables path)
private

Referenced by sendOnPath().

339 {
340  EV << simTime() << ": chunkReschedulingControl:"
341  << "\tqueueFillLevel=" << (100.0 * (double)state->queuedSentBytes) / (double)state->sendQueueLimit << "%"
342  << "\tpeerRwnd=" << state->peerRwnd
343  << endl;
344 
345  double totalBandwidth = 0.0;
346  unsigned int totalOutstandingBytes = 0;
347  unsigned int totalQueuedBytes = 0;
348  for (auto & elem : sctpPathMap) {
349  const SCTPPathVariables *myPath = elem.second;
350  totalQueuedBytes += myPath->queuedBytes;
351  totalOutstandingBytes += myPath->outstandingBytes;
352  totalBandwidth += (double)myPath->cwnd / myPath->srtt.dbl();
353  }
354  assert(totalOutstandingBytes == state->outstandingBytes);
355 
356  const unsigned int queuedBytes = path->queuedBytes;
357  const unsigned int outstandingBytes = path->outstandingBytes;
358 
359  /* senderLimit is just the size of the send queue! */
360  uint32 senderLimit = ((state->sendQueueLimit != 0) ? state->sendQueueLimit : 0xffffffff);
364  {
365  senderLimit = senderLimit / sctpPathMap.size();
366  }
367 
368  /* receiverLimit is the peerRwnd + all bytes queued
369  (i.e. waiting or being outstanding)! */
370  uint32 receiverLimit = state->peerRwnd + totalQueuedBytes;
374  {
375  receiverLimit = receiverLimit / sctpPathMap.size();
376  }
377 
378  const double senderBlockingFraction = (queuedBytes - outstandingBytes) / (double)senderLimit;
379  const double receiverBlockingFraction = (queuedBytes - outstandingBytes) / (double)receiverLimit;
380 
381  EV << " - " << path->remoteAddress
382  << "\tt3=" << (path->T3_RtxTimer->isScheduled() ? path->T3_RtxTimer->getArrivalTime().dbl() : -1.0)
383  << "\tssthresh=" << path->ssthresh
384  << "\tcwnd=" << path->cwnd
385  << "\tsrtt=" << path->srtt
386  << "\tbw=" << (8.0 * (double)path->cwnd) / (1000000.0 * path->srtt) << " Mbit/s"
387  << "\tosb=" << path->outstandingBytes
388  << "\tqueued=" << path->queuedBytes
389  << "\tslimit=" << senderLimit
390  << "\trlimit=" << receiverLimit
391  << "\tsblocking=" << 100.0 * senderBlockingFraction << " %"
392  << "\trblocking=" << 100.0 * receiverBlockingFraction << " %"
393  << endl;
394 
395  path->statisticsPathSenderBlockingFraction->record(senderBlockingFraction);
396  path->statisticsPathReceiverBlockingFraction->record(receiverBlockingFraction);
397 
398  // ====== Chunk Rescheduling =============================================
402  {
405  (senderBlockingFraction >= state->cmtChunkReschedulingThreshold)) ||
408  (receiverBlockingFraction >= state->cmtChunkReschedulingThreshold)))
409  {
410  if ((!path->fastRecoveryActive) && // Only apply when path is not yet in Fast Recovery!
411  ((path->blockingTimeout < 0.0) || // Do not move chunks to an already-blocked path!
412  (simTime() >= path->blockingTimeout)))
413  {
414  // ====== Rescheduling of chunk from other path to current path ====
415  auto iterator = retransmissionQ->payloadQueue.begin();
416  if (iterator != retransmissionQ->payloadQueue.end()) {
417  SCTPDataVariables *chunk = iterator->second;
418  SCTPPathVariables *lastPath = chunk->getLastDestinationPath();
419 
420  if ((chunk->countsAsOutstanding == true) && // T.D. 04.08.2011: Chunk must be outstanding, i.e. in the network!
421  (chunk->hasBeenMoved == false) && // T.D. 08.07.2011: Check, whether this chunk has already been moved!
422  ((lastPath != path) ||
423  (chunk->sendTime + (2 * path->srtt) < simTime())))
424  {
425  assert(chunk->numberOfTransmissions > 0); // It has been transmitted as least once
426  assert(chunk->hasBeenAcked == false); // It has not been acked (since it is outstanding)
427 
428  EV << simTime() << ": RESCHEDULING TSN " << chunk->tsn << " on "
429  << lastPath->remoteAddress << " to "
430  << path->remoteAddress << endl;
431 
432  // ====== Move chunk ======================================
433  lastPath->vectorPathBlockingTSNsMoved->record(chunk->tsn);
434  moveChunkToOtherPath(chunk, path);
435 
436  // This chunk is important, since it is blocking others ...
437  // If SackNow is supported, ensure that it is SACK'ed quickly!
438  chunk->ibit = sctpMain->sackNow;
439 
441  chunk->hasBeenMoved = (lastPath != path);
442 
443  // Restart T3 timer on its old path, if it is scheduled
444  if (lastPath->T3_RtxTimer->isScheduled()) {
445  // Stop timer, if path is empty now.
446  // Else, keep it running, without reset!
447  if (lastPath->queuedBytes == 0) {
448  stopTimer(lastPath->T3_RtxTimer);
449  }
450  }
451 
452  // ====== Handle Congestion Control =======================
453  if (state->cmtMovedChunksReduceCwnd == true) {
454  if (lastPath != path) {
455  if ((lastPath->blockingTimeout >= 0.0) &&
456  (simTime() < lastPath->blockingTimeout))
457  {
458  // Path is already blocked
459  EV << simTime() << "\tCR-3 on path "
460  << lastPath->remoteAddress << " (blocked until "
461  << lastPath->blockingTimeout << ")" << endl;
462  }
463  else if (lastPath->fastRecoveryActive) {
464  // A further problem during Fast Recovery -> block path
465  const simtime_t pause = lastPath->srtt;
466  lastPath->blockingTimeout = simTime() + pause;
467  assert(!lastPath->BlockingTimer->isScheduled());
468  startTimer(lastPath->BlockingTimer, pause);
469  EV << simTime() << "\tCR-2 on path "
470  << lastPath->remoteAddress << " (pause="
471  << pause << "; blocked until "
472  << lastPath->blockingTimeout << ")" << endl;
473  }
474  else {
475  // Go into Fast Recovery mode ...
476  lastPath->requiresRtx = true;
477  (this->*ccFunctions.ccUpdateBeforeSack)();
478  (this->*ccFunctions.ccUpdateAfterSack)();
479  lastPath->requiresRtx = false;
480  EV << simTime() << "\tCR-1 on path "
481  << lastPath->remoteAddress << endl;
482  }
483  }
484  else {
485  EV << simTime() << "\tCR-4 on path "
486  << path->remoteAddress << " (lastTX="
487  << simTime() - chunk->sendTime
488  << ", TSN " << chunk->tsn << ")" << endl;
489 
490  lastPath->requiresRtx = true;
491  (this->*ccFunctions.ccUpdateBeforeSack)();
492  (this->*ccFunctions.ccUpdateAfterSack)();
493  lastPath->requiresRtx = false;
494  }
495  }
496  }
497  }
498  }
499  }
500  }
501  // ====== Test ===========================================================
503  abort();
504  }
505 }
uint64 sendQueueLimit
Definition: SCTPAssociation.h:659
Definition: SCTPAssociation.h:718
Definition: SCTPAssociation.h:730
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
bool sackNow
Definition: SCTP.h:213
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
bool cmtMovedChunksReduceCwnd
Definition: SCTPAssociation.h:742
uint64 peerRwnd
Definition: SCTPAssociation.h:610
Definition: SCTPAssociation.h:719
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
Definition: SCTPAssociation.h:727
BufferSplitVariant cmtBufferSplitVariant
Definition: SCTPAssociation.h:722
ChunkReschedulingVariant cmtChunkReschedulingVariant
Definition: SCTPAssociation.h:732
Definition: SCTPAssociation.h:720
void(SCTPAssociation::* ccUpdateBeforeSack)()
Definition: SCTPAssociation.h:891
double cmtChunkReschedulingThreshold
Definition: SCTPAssociation.h:733
Definition: SCTPAssociation.h:728
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
SCTP * sctpMain
Definition: SCTPAssociation.h:962
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
CCFunctions ccFunctions
Definition: SCTPAssociation.h:951
uint64 outstandingBytes
Definition: SCTPAssociation.h:622
uint32_t uint32
Definition: Compat.h:30
void(SCTPAssociation::* ccUpdateAfterSack)()
Definition: SCTPAssociation.h:892
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
void moveChunkToOtherPath(SCTPDataVariables *chunk, SCTPPathVariables *newPath)
Definition: SCTPAssociationRcvMessage.cc:3858
uint64 queuedSentBytes
Definition: SCTPAssociation.h:623
unsigned int blockingTSNsMoved
Definition: SCTPAssociation.h:744
Definition: SCTPAssociation.h:729
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
uint16 inet::sctp::SCTPAssociation::chunkToInt ( const char *  type)
static

Referenced by cloneAssociation(), and initAssociation().

237 {
238  EV_STATICCONTEXT;
239 
240  if (strcmp(type, "DATA") == 0)
241  return 0;
242  if (strcmp(type, "INIT") == 0)
243  return 1;
244  if (strcmp(type, "INIT_ACK") == 0)
245  return 2;
246  if (strcmp(type, "SACK") == 0)
247  return 3;
248  if (strcmp(type, "HEARTBEAT") == 0)
249  return 4;
250  if (strcmp(type, "HEARTBEAT_ACK") == 0)
251  return 5;
252  if (strcmp(type, "ABORT") == 0)
253  return 6;
254  if (strcmp(type, "SHUTDOWN") == 0)
255  return 7;
256  if (strcmp(type, "SHUTDOWN_ACK") == 0)
257  return 8;
258  if (strcmp(type, "ERRORTYPE") == 0)
259  return 9;
260  if (strcmp(type, "COOKIE_ECHO") == 0)
261  return 10;
262  if (strcmp(type, "COOKIE_ACK") == 0)
263  return 11;
264  if (strcmp(type, "SHUTDOWN_COMPLETE") == 0)
265  return 14;
266  if (strcmp(type, "AUTH") == 0)
267  return 15;
268  if (strcmp(type, "NR-SACK") == 0)
269  return 16;
270  if (strcmp(type, "ASCONF_ACK") == 0)
271  return 128;
272  if (strcmp(type, "PKTDROP") == 0)
273  return 129;
274  if (strcmp(type, "RE_CONFIG") == 0)
275  return 130;
276  if (strcmp(type, "FORWARD_TSN") == 0)
277  return 192;
278  if (strcmp(type, "ASCONF") == 0)
279  return 193;
280  EV_WARN << "ChunkConversion not successful\n";
281  return 0xffff;
282 }
SCTPAssociation * inet::sctp::SCTPAssociation::cloneAssociation ( )
protected

Utility: clone a listening association.

Used for forking.

Referenced by processInitArrived().

302 {
304  const char *queueClass = transmissionQ->getClassName();
305  assoc->transmissionQ = check_and_cast<SCTPQueue *>(inet::utils::createOne(queueClass));
306  assoc->retransmissionQ = check_and_cast<SCTPQueue *>(inet::utils::createOne(queueClass));
307 
308  const char *sctpAlgorithmClass = sctpAlgorithm->getClassName();
309  assoc->sctpAlgorithm = check_and_cast<SCTPAlgorithm *>(inet::utils::createOne(sctpAlgorithmClass));
310  assoc->sctpAlgorithm->setAssociation(assoc);
311  assoc->sctpAlgorithm->initialize();
312  assoc->state = assoc->sctpAlgorithm->createStateVariables();
313 
314  if ((bool)sctpMain->par("auth")) {
315  const char *chunks = sctpMain->par("chunks").stringValue();
316  bool asc = false;
317  bool asca = false;
318  char *chunkscopy = (char *)malloc(strlen(chunks) + 1);
319  strcpy(chunkscopy, chunks);
320  char *token;
321  token = strtok((char *)chunkscopy, ",");
322  while (token != nullptr) {
323  if (chunkToInt(token) == ASCONF)
324  asc = true;
325  if (chunkToInt(token) == ASCONF_ACK)
326  asca = true;
327  if (!typeInOwnChunkList(chunkToInt(token))) {
328  this->state->chunkList.push_back(chunkToInt(token));
329  }
330  token = strtok(nullptr, ",");
331  }
332  if ((bool)sctpMain->par("addIP")) {
333  if (!asc && !typeInOwnChunkList(ASCONF))
334  state->chunkList.push_back(ASCONF);
335  if (!asca && !typeInOwnChunkList(ASCONF_ACK))
336  state->chunkList.push_back(ASCONF_ACK);
337  }
338  free(chunkscopy);
339  }
340 
341  assoc->state->active = false;
342  assoc->state->fork = true;
343  assoc->localAddr = localAddr;
344  assoc->localPort = localPort;
345  assoc->localAddressList = localAddressList;
346  assoc->listening = true;
347 
348  assoc->outboundStreams = outboundStreams;
349  assoc->inboundStreams = inboundStreams;
350  assoc->fd = fd;
351 
352  FSM_Goto((*assoc->fsm), SCTP_S_CLOSED);
354  return assoc;
355 }
SCTPAssociation(SCTP *mod, int32 appGateIndex, int32 assocId, IRoutingTable *rt, IInterfaceTable *ift)
Constructor.
Definition: SCTPAssociationBase.cc:570
void printInfoAssocMap()
Definition: SCTP.cc:42
AddressVector localAddressList
Definition: SCTPAssociation.h:939
IInterfaceTable * ift
Definition: SCTPAssociation.h:937
void setAssociation(SCTPAssociation *_assoc)
Definition: SCTPAlgorithm.h:54
Definition: SCTPAssociation.h:130
uint32 outboundStreams
Definition: SCTPAssociation.h:943
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
uint32 inboundStreams
Definition: SCTPAssociation.h:942
void * malloc(YYSIZE_T)
cObject * createOne(const char *className, const char *defaultNamespace)
Like cObjectFactory::createOne(), except it starts searching for the class in the given namespace...
Definition: INETUtils.cc:105
SCTP * sctpMain
Definition: SCTPAssociation.h:962
std::vector< uint16 > chunkList
Definition: SCTPAssociation.h:823
int32 fd
Definition: SCTPAssociation.h:909
bool typeInOwnChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:295
IRoutingTable * rt
Definition: SCTPAssociation.h:936
L3Address localAddr
Definition: SCTPAssociation.h:912
int32 assocId
Definition: SCTPAssociation.h:908
SCTPAlgorithm * sctpAlgorithm
Definition: SCTPAssociation.h:970
void free(void *)
Definition: SCTPAssociation.h:126
int32 appGateIndex
Definition: SCTPAssociation.h:907
Definition: SCTPAssociation.h:57
uint16 localPort
Definition: SCTPAssociation.h:913
static uint16 chunkToInt(const char *type)
Definition: SCTPAssociationUtil.cc:236
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::compareRandom ( )
protected

Referenced by calculateAssocSharedKey().

235 {
236  int32 i, sizeKeyVector, sizePeerKeyVector, size = 0;
237 
238  sizeKeyVector = sizeof(state->keyVector);
239  sizePeerKeyVector = sizeof(state->peerKeyVector);
240 
241  if (sizeKeyVector != sizePeerKeyVector) {
242  if (sizePeerKeyVector > sizeKeyVector) {
243  size = sizeKeyVector;
244  for (i = sizePeerKeyVector - 1; i > sizeKeyVector; i--) {
245  if (state->peerKeyVector[i] != 0)
246  return false;
247  }
248  }
249  else {
250  size = sizePeerKeyVector;
251  for (i = sizeKeyVector - 1; i > sizePeerKeyVector; i--) {
252  if (state->keyVector[i] != 0)
253  return true;
254  }
255  }
256  }
257  else
258  size = sizeKeyVector;
259  for (i = size - 1; i > 0; i--) {
260  if (state->keyVector[i] < state->peerKeyVector[i])
261  return false;
262  if (state->keyVector[i] > state->peerKeyVector[i])
263  return true;
264  }
265  return true;
266 }
uint8 keyVector[512]
Definition: SCTPAssociation.h:825
uint8 peerKeyVector[512]
Definition: SCTPAssociation.h:827
int32_t int32
Definition: Compat.h:31
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPAsconfAckChunk * inet::sctp::SCTPAssociation::createAsconfAckChunk ( const uint32  serialNumber)
protected

Referenced by processAsconfArrived().

210 {
211  SCTPAsconfAckChunk *asconfAckChunk = new SCTPAsconfAckChunk("ASCONF_ACK");
212  asconfAckChunk->setChunkType(ASCONF_ACK);
213  asconfAckChunk->setSerialNumber(serialNumber);
214  asconfAckChunk->setByteLength(SCTP_ADD_IP_CHUNK_LENGTH);
215  return asconfAckChunk;
216 }
#define SCTP_ADD_IP_CHUNK_LENGTH
Definition: SCTPAssociation.h:231
Definition: SCTPAssociation.h:126
SCTPAuthenticationChunk * inet::sctp::SCTPAssociation::createAuthChunk ( )
protected

Referenced by processAsconfArrived(), processPacketDropArrived(), retransmitAsconf(), retransmitCookieEcho(), sendAbort(), sendAsconf(), sendAsconfAck(), sendCookieAck(), sendCookieEcho(), sendHeartbeat(), sendHeartbeatAck(), sendInvalidStreamError(), sendSack(), and sendShutdown().

219 {
220  SCTPAuthenticationChunk *authChunk = new SCTPAuthenticationChunk("AUTH");
221 
222  authChunk->setChunkType(AUTH);
223  authChunk->setSharedKey(0);
224  authChunk->setHMacIdentifier(1);
225  authChunk->setHMacOk(true);
226  authChunk->setHMACArraySize(SHA_LENGTH);
227  for (int32 i = 0; i < SHA_LENGTH; i++) {
228  authChunk->setHMAC(i, 0);
229  }
230  authChunk->setBitLength((SCTP_AUTH_CHUNK_LENGTH + SHA_LENGTH) * 8);
231  return authChunk;
232 }
#define SHA_LENGTH
Definition: SCTPAssociation.h:235
Definition: SCTPAssociation.h:124
int32_t int32
Definition: Compat.h:31
#define SCTP_AUTH_CHUNK_LENGTH
Definition: SCTPAssociation.h:233
SCTPForwardTsnChunk * inet::sctp::SCTPAssociation::createForwardTsnChunk ( const L3Address pid)
protected

Referenced by processPacketDropArrived(), and sendOnPath().

1284 {
1285  uint16 chunkLength = SCTP_FORWARD_TSN_CHUNK_LENGTH;
1286  SCTPDataVariables *chunk;
1287  typedef std::map<uint16, int16> SidMap;
1288  SidMap sidMap;
1289 
1290  EV_INFO << "Create forwardTsnChunk for " << pid << "\n";
1291  SCTPForwardTsnChunk *forwChunk = new SCTPForwardTsnChunk("FORWARD_TSN");
1292  forwChunk->setChunkType(FORWARD_TSN);
1293  advancePeerTsn();
1294  forwChunk->setNewCumTsn(state->advancedPeerAckPoint);
1295  for (auto & elem : retransmissionQ->payloadQueue) {
1296  chunk = elem.second;
1297  EV_DETAIL << "tsn=" << chunk->tsn << " lastDestination=" << chunk->getLastDestination() << " abandoned=" << chunk->hasBeenAbandoned << "\n";
1298  if (chunk->getLastDestination() == pid && chunk->hasBeenAbandoned && chunk->tsn <= forwChunk->getNewCumTsn()) {
1299  if (chunk->ordered) {
1300  sidMap[chunk->sid] = chunk->ssn;
1301  }
1302  else {
1303  sidMap[chunk->sid] = -1;
1304  }
1305  /* Fake chunk retransmission */
1306  if (chunk->sendForwardIfAbandoned) {
1307  chunk->gapReports = 0;
1308  chunk->hasBeenFastRetransmitted = false;
1309  chunk->sendTime = simTime();
1310  chunk->numberOfRetransmissions++;
1311  chunk->sendForwardIfAbandoned = false;
1312 
1313  auto itt = transmissionQ->payloadQueue.find(chunk->tsn);
1314  if (itt != transmissionQ->payloadQueue.end()) {
1315  transmissionQ->payloadQueue.erase(itt);
1316  chunk->enqueuedInTransmissionQ = false;
1317  auto i = qCounter.roomTransQ.find(pid);
1318  i->second -= ADD_PADDING(chunk->len / 8 + SCTP_DATA_CHUNK_LENGTH);
1319  auto ib = qCounter.bookedTransQ.find(pid);
1320  ib->second -= chunk->booksize;
1321  }
1322  }
1323  }
1324  }
1325  forwChunk->setSidArraySize(sidMap.size());
1326  forwChunk->setSsnArraySize(sidMap.size());
1327  int32 i = 0;
1328  for (auto & elem : sidMap) {
1329  forwChunk->setSid(i, elem.first);
1330  forwChunk->setSsn(i, elem.second);
1331  chunkLength += 4;
1332  i++;
1333  }
1334  forwChunk->setByteLength(chunkLength);
1335  auto iter = sctpMain->assocStatMap.find(assocId);
1336  iter->second.numForwardTsn++;
1337  return forwChunk;
1338 }
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
#define SCTP_FORWARD_TSN_CHUNK_LENGTH
Definition: SCTPAssociation.h:220
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void advancePeerTsn()
Definition: SCTPAssociationUtil.cc:2201
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
AssocStatMap assocStatMap
Definition: SCTP.h:171
QueueCounter qCounter
Definition: SCTPAssociation.h:965
uint32 advancedPeerAckPoint
Definition: SCTPAssociation.h:836
int32_t int32
Definition: Compat.h:31
Definition: SCTPAssociation.h:129
int32 assocId
Definition: SCTPAssociation.h:908
uint16_t uint16
Definition: Compat.h:32
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPSackChunk * inet::sctp::SCTPAssociation::createSack ( )
protected

Referenced by sendInvalidStreamError(), sendOnPath(), sendSack(), and sendStreamResetResponse().

1474 {
1475  EV_INFO << simTime() << "SCTPAssociationUtil:createSACK localAddress=" << localAddr << " remoteAddress=" << remoteAddr << "\n";
1476 
1477  EV_INFO << " localRwnd=" << state->localRwnd << " queuedBytes=" << state->queuedReceivedBytes << "\n";
1478 
1479  // ====== Get receiver window size to be advertised ======================
1480  uint32 arwnd = 0;
1481  uint32 msgRwnd = 0;
1485  {
1486  msgRwnd = 0;
1487  }
1488  else if ((state->messageAcceptLimit > 0 && (int32)(state->localMsgRwnd - state->bufferedMessages) < 3)
1490  {
1491  msgRwnd = 1;
1492  state->swsMsgInvoked = true;
1493  }
1494  else {
1495  if (state->messageAcceptLimit > 0) {
1496  msgRwnd = state->localMsgRwnd - state->bufferedMessages;
1497  }
1498  else {
1499  msgRwnd = state->localRwnd
1502  }
1503  }
1504  if (state->tellArwnd) {
1505  arwnd = msgRwnd;
1506  }
1507  else {
1508  // ====== Receiver buffer is full =====================================
1509  if ((int32)(state->localRwnd - state->queuedReceivedBytes) <= 0) {
1510  arwnd = 0;
1511  if (state->swsLimit > 0) {
1512  state->swsAvoidanceInvoked = true;
1513  }
1514  }
1515  // ====== Silly window syndrome avoidance =============================
1516  else if ((state->localRwnd - state->queuedReceivedBytes < state->swsLimit) ||
1517  (state->swsAvoidanceInvoked == true))
1518  {
1519  arwnd = 1;
1520  if (state->swsLimit > 0)
1521  state->swsAvoidanceInvoked = true;
1522  EV_DETAIL << "arwnd=1; createSack : SWS Avoidance ACTIVE !!!\n";
1523  }
1524  // ====== There is space in the receiver buffer =======================
1525  else {
1527  EV_DETAIL << simTime() << " arwnd = " << state->localRwnd << " - " << state->queuedReceivedBytes << " = " << arwnd << "\n";
1528  }
1529  }
1530 
1531  // ====== Record statistics ==============================================
1532  if (state->messageAcceptLimit > 0) {
1533  advMsgRwnd->record(msgRwnd);
1534  }
1536  advRwnd->record(arwnd);
1537 
1538  // ====== Create SACK chunk ==============================================
1539  SCTPSackChunk *sackChunk = new SCTPSackChunk("SACK");
1540  if (state->nrSack == true) {
1541  sackChunk->setChunkType(NR_SACK);
1542  sackChunk->setName("NR_SACK");
1543  }
1544  else {
1545  sackChunk->setChunkType(SACK);
1546  }
1547  sackChunk->setCumTsnAck(state->gapList.getCumAckTSN());
1548  sackChunk->setA_rwnd(arwnd);
1549  sackChunk->setIsNrSack(state->nrSack);
1550  sackChunk->setSackSeqNum(++state->outgoingSackSeqNum);
1551  if (state->messageAcceptLimit > 0) {
1552  sackChunk->setMsg_rwnd(state->messageAcceptLimit - state->bufferedMessages);
1553  }
1554  else {
1555  sackChunk->setMsg_rwnd(0);
1556  }
1557 
1558  // ====== What has to be stored in the SACK? =============================
1559  const uint32 mtu = getPath(remoteAddr)->pmtu;
1560 
1561  uint32 hdrSize;
1562  if (remoteAddr.getType() == L3Address::IPv6)
1563  hdrSize = 40;
1564  else if (remoteAddr.getType() == L3Address::IPv4)
1565  hdrSize = 20;
1566  else
1567  throw cRuntimeError("Unknown address type");
1568 
1569  const uint32 allowedLength = mtu
1570  - hdrSize
1573  uint32 numDups = state->dupList.size();
1576  size_t revokableGapsSpace = ~0;
1577  size_t nonRevokableGapsSpace = ~0;
1578  size_t sackHeaderLength = ~0;
1579  const uint32 totalGaps = state->gapList.getNumGaps(SCTPGapList::GT_Any);
1580  bool compression = false;
1581 
1582  // ====== Record statistics ==============================================
1583  statisticsNumTotalGapBlocksStored->record(totalGaps);
1584  statisticsNumRevokableGapBlocksStored->record(numRevokableGaps);
1585  statisticsNumNonRevokableGapBlocksStored->record(numNonRevokableGaps);
1586  statisticsNumDuplicatesStored->record(numDups);
1587 
1588  // ====== Optimization ===================================================
1589  const int optR = (int)numRevokableGaps - (int)totalGaps;
1590  const int optNR = (int)numNonRevokableGaps - (int)totalGaps;
1591 
1593  ((numRevokableGaps > 0) || (numNonRevokableGaps > 0)))
1594  {
1595  compression = true;
1596  }
1597 
1598  // ------ Optimization 1: R=ANY, NR=non-revokable ------
1599  if ((state->nrSack == true) &&
1601  ((optR > 0) && (optR >= optNR) && (state->gapListOptimizationVariant >= SCTPStateVariables::GLOV_Optimized2))))
1602  {
1603  assert(totalGaps < numRevokableGaps);
1604  sackHeaderLength = (compression == true) ? SCTP_COMPRESSED_NRSACK_CHUNK_LENGTH : SCTP_NRSACK_CHUNK_LENGTH;
1605  numRevokableGaps = copyToRGaps(sackChunk, &state->gapList, SCTPGapList::GT_Any, compression, revokableGapsSpace); // Add ALL
1606  numNonRevokableGaps = copyToNRGaps(sackChunk, &state->gapList, SCTPGapList::GT_NonRevokable, compression, nonRevokableGapsSpace); // Add NR-acks only
1607  assert(numRevokableGaps == totalGaps);
1608  // opt += optR;
1609  }
1610  // ------ Optimization 2: NR=ANY, R=difference ---------
1611  else if ((state->nrSack == true) &&
1613  {
1614  assert(totalGaps < numNonRevokableGaps);
1615  sackChunk->setNrSubtractRGaps(true);
1616  sackHeaderLength = (compression == true) ? SCTP_COMPRESSED_NRSACK_CHUNK_LENGTH : SCTP_NRSACK_CHUNK_LENGTH;
1617  numRevokableGaps = copyToRGaps(sackChunk, &state->gapList, SCTPGapList::GT_Revokable, compression, revokableGapsSpace); // Add R-acks only
1618  numNonRevokableGaps = copyToNRGaps(sackChunk, &state->gapList, SCTPGapList::GT_Any, compression, nonRevokableGapsSpace); // Add ALL
1619  assert(numNonRevokableGaps == totalGaps);
1620  // opt += optNR;
1621  }
1622  else {
1623  // ------ Regular NR-SACK ---------------------------
1624  if (state->nrSack == true) {
1625  sackHeaderLength = SCTP_NRSACK_CHUNK_LENGTH;
1626  if (compression == true) {
1627  sackHeaderLength = SCTP_COMPRESSED_NRSACK_CHUNK_LENGTH;
1628  }
1629  numRevokableGaps = copyToRGaps(sackChunk, &state->gapList, SCTPGapList::GT_Revokable, compression, revokableGapsSpace); // Add R-acks only
1630  numNonRevokableGaps = copyToNRGaps(sackChunk, &state->gapList, SCTPGapList::GT_NonRevokable, compression, nonRevokableGapsSpace); // Add NR-acks only
1631  }
1632  // ------ Regular SACK ------------------------------
1633  else {
1634  sackHeaderLength = SCTP_SACK_CHUNK_LENGTH;
1635  numRevokableGaps = copyToRGaps(sackChunk, &state->gapList, SCTPGapList::GT_Any, false, revokableGapsSpace); // Add ALL
1636  numNonRevokableGaps = 0;
1637  nonRevokableGapsSpace = 0;
1638  }
1639  }
1640 
1641  // ====== SACK has to be shortened to fit in MTU ===========================
1642  uint32 sackLength = sackHeaderLength + revokableGapsSpace + nonRevokableGapsSpace + numDups * 4;
1643  if (sackLength > allowedLength) {
1644  // Strategy to reduce the SACK size:
1645  // - Report no duplicates (they are not used for congestion control)
1646  // - Split the remaining space equally between
1647  // revokable and non-revokable GapAcks
1648 
1649  // ====== Drop duplicates list ========================================
1650  numDups = 0;
1651  sackLength -= 4 * numDups;
1652 
1653  if (sackLength > allowedLength) {
1654  // Unfortunately, dropping the duplicates has not solved the problem.
1655  // => Now, the gap lists have to be shortened!
1656 
1657  auto iter = sctpMain->assocStatMap.find(assocId);
1658  iter->second.numOverfullSACKs++;
1659  // ====== Undo NR optimization ====================================
1660  if (sackChunk->getNrSubtractRGaps() == true) {
1661  sackChunk->setNrSubtractRGaps(false); // Unset SubtractRGaps!
1662  // This optimization cannot work when lists have to be shortened.
1663  // Just use regular NR list.
1664  }
1665  revokableGapsSpace = allowedLength - sackHeaderLength;
1666  if (totalGaps < (state->gapList.getNumGaps(SCTPGapList::GT_Revokable))) {
1667  numRevokableGaps = copyToRGaps(sackChunk, &state->gapList, SCTPGapList::GT_Any, compression, revokableGapsSpace); // Add ALL
1668  }
1669  else {
1670  numRevokableGaps = copyToRGaps(sackChunk, &state->gapList, SCTPGapList::GT_Revokable, compression, revokableGapsSpace); // Add R-acks only
1671  }
1672  sackLength = sackHeaderLength + revokableGapsSpace + nonRevokableGapsSpace + numDups * 4;
1673 
1674  // ====== Shorten gap lists ========================================
1676  if (sackHeaderLength + revokableGapsSpace < allowedLength) {
1677  // Fill NR-acks up to allowed size
1678  nonRevokableGapsSpace = allowedLength - sackHeaderLength - revokableGapsSpace;
1679  numNonRevokableGaps = copyToNRGaps(sackChunk, &state->gapList, SCTPGapList::GT_NonRevokable, compression, nonRevokableGapsSpace); // Add NR-acks only
1680  sackLength = sackHeaderLength + revokableGapsSpace + nonRevokableGapsSpace + numDups * 4;
1681  }
1682  else {
1683  // Not even space to set R-acks => cut R-acks, no NR-acks!
1684  nonRevokableGapsSpace = allowedLength - sackHeaderLength;
1685  numRevokableGaps = copyToRGaps(sackChunk, &state->gapList, SCTPGapList::GT_Any, compression, revokableGapsSpace); // Add ALL
1686  }
1687  }
1688  else {
1689  if (sackLength > allowedLength) {
1690  double revokableFraction = 1.0;
1691  const uint32 blocksBeRemoved = (sackLength - allowedLength) / 4;
1692  if (numRevokableGaps + numNonRevokableGaps > 0) {
1693  revokableFraction = numRevokableGaps / (double)(numRevokableGaps + numNonRevokableGaps);
1694  }
1695  const uint32 removeRevokable = (uint32)ceil(blocksBeRemoved * revokableFraction);
1696  const uint32 removeNonRevokable = (uint32)ceil(blocksBeRemoved * (1.0 - revokableFraction));
1697  numRevokableGaps -= std::min(removeRevokable, numRevokableGaps);
1698  numNonRevokableGaps -= std::min(removeNonRevokable, numNonRevokableGaps);
1699  revokableGapsSpace = 4 * numRevokableGaps;
1700  nonRevokableGapsSpace = 4 * numNonRevokableGaps;
1701  numRevokableGaps = copyToRGaps(sackChunk, &state->gapList, SCTPGapList::GT_Revokable, compression, revokableGapsSpace); // Add R-acks only
1702  numNonRevokableGaps = copyToNRGaps(sackChunk, &state->gapList, SCTPGapList::GT_NonRevokable, compression, nonRevokableGapsSpace); // Add NR-acks only
1703  sackLength = sackHeaderLength + revokableGapsSpace + nonRevokableGapsSpace + numDups * 4;
1704  }
1705  }
1706 
1707  assert(sackLength <= allowedLength);
1708 
1709  // Update values in SACK chunk ...
1710  sackChunk->setNumGaps(numRevokableGaps);
1711  sackChunk->setNumNrGaps(numNonRevokableGaps);
1712  }
1713  }
1714  sackChunk->setNumDupTsns(numDups);
1715  sackChunk->setByteLength(sackLength);
1716 
1717  // ====== Apply limit ====================================================
1718  if (state->gapReportLimit < 1000000) {
1719  if (!compression) {
1720  numRevokableGaps = std::min(numRevokableGaps, state->gapReportLimit);
1721  numNonRevokableGaps = std::min(numNonRevokableGaps, state->gapReportLimit);
1722  // Update values in SACK chunk ...
1723  sackChunk->setNumGaps(numRevokableGaps);
1724  sackChunk->setNumNrGaps(numNonRevokableGaps);
1725  sackLength = sackHeaderLength + revokableGapsSpace + nonRevokableGapsSpace + numDups * 4;
1726  } else {
1727  assert(false); // NOTE: IMPLEMENT ME!
1728  }
1729  }
1730 
1731  // ====== Add duplicates =================================================
1732  if (numDups > 0) {
1733  sackChunk->setDupTsnsArraySize(numDups);
1734  uint32 key = 0;
1735  for (auto & elem : state->dupList) {
1736  sackChunk->setDupTsns(key, elem);
1737  key++;
1738  if (key == numDups)
1739  break;
1740  }
1741  state->dupList.clear();
1742  }
1743 
1744  // ====== Record statistics ==============================================
1745  statisticsSACKLengthSent->record(sackLength);
1746  statisticsNumRevokableGapBlocksSent->record(numRevokableGaps);
1747  statisticsNumNonRevokableGapBlocksSent->record(numNonRevokableGaps);
1748  statisticsNumDuplicatesSent->record(numDups);
1749 
1750  // ====== Print information ==============================================
1751  EV_DEBUG << "createSack:"
1752  << " bufferedMessages=" << state->bufferedMessages
1753  << " msgRwnd=" << msgRwnd
1754  << " arwnd=" << sackChunk->getA_rwnd()
1755  << " cumAck=" << state->gapList.getCumAckTSN()
1756  << " numRGaps=" << numRevokableGaps
1757  << " numNRGaps=" << numNonRevokableGaps
1758  << " numDups=" << numDups
1759  << " gapList={" << state->gapList << "}"
1760  << endl;
1761  return sackChunk;
1762 }
cOutVector * advMsgRwnd
Definition: SCTPAssociation.h:925
bool smartOverfullSACKHandling
Definition: SCTPAssociation.h:686
bool swsMsgInvoked
Definition: SCTPAssociation.h:847
bool swsAvoidanceInvoked
Definition: SCTPAssociation.h:580
cOutVector * statisticsNumRevokableGapBlocksStored
Definition: SCTPAssociation.h:986
cOutVector * statisticsNumDuplicatesStored
Definition: SCTPAssociation.h:988
Definition: SCTPAssociation.h:682
Definition: L3Address.h:47
cOutVector * statisticsNumNonRevokableGapBlocksStored
Definition: SCTPAssociation.h:987
uint32 getNumGaps(const GapType type) const
Definition: SCTPGapList.h:112
uint32 bufferedMessages
Definition: SCTPAssociation.h:842
void calculateRcvBuffer()
Definition: SCTPAssociationUtil.cc:49
Definition: SCTPAssociation.h:125
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
uint32 swsLimit
Definition: SCTPAssociation.h:664
uint32 gapListOptimizationVariant
Definition: SCTPAssociation.h:685
uint64 localRwnd
Definition: SCTPAssociation.h:612
bool nrSack
Definition: SCTPAssociation.h:677
cOutVector * statisticsQueuedReceivedBytes
Definition: SCTPAssociation.h:974
Definition: SCTPGapList.h:108
cOutVector * statisticsNumNonRevokableGapBlocksSent
Definition: SCTPAssociation.h:990
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
cOutVector * statisticsNumDuplicatesSent
Definition: SCTPAssociation.h:991
#define SCTP_SACK_CHUNK_LENGTH
Definition: SCTPAssociation.h:215
cOutVector * statisticsSACKLengthSent
Definition: SCTPAssociation.h:992
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
uint32 localMsgRwnd
Definition: SCTPAssociation.h:840
SCTP * sctpMain
Definition: SCTPAssociation.h:962
uint32 pmtu
Definition: SCTPAssociation.h:301
#define SCTP_COMPRESSED_NRSACK_CHUNK_LENGTH
Definition: SCTPAssociation.h:244
cOutVector * statisticsNumRevokableGapBlocksSent
Definition: SCTPAssociation.h:989
Definition: SCTPGapList.h:107
SCTPGapList gapList
Definition: SCTPAssociation.h:619
L3Address remoteAddr
Definition: SCTPAssociation.h:911
uint32 outgoingSackSeqNum
Definition: SCTPAssociation.h:774
AssocStatMap assocStatMap
Definition: SCTP.h:171
uint32 messageAcceptLimit
Definition: SCTPAssociation.h:639
Definition: SCTPGapList.h:109
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
uint32 bytesToAddPerRcvdChunk
Definition: SCTPAssociation.h:844
Definition: SCTPAssociation.h:114
L3Address localAddr
Definition: SCTPAssociation.h:912
int32 assocId
Definition: SCTPAssociation.h:908
cOutVector * advRwnd
Definition: SCTPAssociation.h:954
Definition: SCTPAssociation.h:683
uint64 queuedReceivedBytes
Definition: SCTPAssociation.h:625
cOutVector * statisticsNumTotalGapBlocksStored
Definition: SCTPAssociation.h:985
uint32 gapReportLimit
Definition: SCTPAssociation.h:678
uint32 getCumAckTSN() const
Definition: SCTPGapList.h:91
bool tellArwnd
Definition: SCTPAssociation.h:846
std::list< uint32 > dupList
Definition: SCTPAssociation.h:608
Definition: L3Address.h:46
Definition: SCTPAssociation.h:681
#define SCTP_NRSACK_CHUNK_LENGTH
Definition: SCTPAssociation.h:216
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPSuccessIndication * inet::sctp::SCTPAssociation::createSuccessIndication ( uint32  correlationId)
protected

Referenced by processAsconfArrived().

306 {
307  SCTPSuccessIndication *success = new SCTPSuccessIndication("Success");
308 
309  success->setParameterType(SUCCESS_INDICATION);
310  success->setResponseCorrelationId(correlationId);
311  success->setBitLength(SCTP_ADD_IP_PARAMETER_LENGTH * 8);
312  return success;
313 }
#define SCTP_ADD_IP_PARAMETER_LENGTH
Definition: SCTPAssociation.h:232
Definition: SCTPAssociation.h:174
void inet::sctp::SCTPAssociation::cucProcessGapReports ( const SCTPDataVariables chunk,
SCTPPathVariables path,
const bool  isAcked 
)
inlineprotected

Referenced by processSackArrived().

967 {
968  // We only care for newly acked chunks.
969  // Therefore, the previous state must be "unacked".
970  if (chunkHasBeenAcked(chunk) == false) {
971  // For CUCv2, it has to be checked whether it is the first transmission.
972  // Otherwise, the behaviour will be like CUCv1 -> decreasing PseudoCumAck on T3 RTX!
973  if ((path->findPseudoCumAck == true) &&
974  ((chunk->numberOfRetransmissions == 0) ||
976  {
977  path->pseudoCumAck = chunk->tsn;
978  path->findPseudoCumAck = false;
979  }
980  if ((isAcked) && /* Not acked before and acked now => ack for the first time */
981  (path->pseudoCumAck == chunk->tsn))
982  {
983  path->newPseudoCumAck = true;
984  path->findPseudoCumAck = true;
985  }
986 
987  // CUCv2
988  if ((path->findRTXPseudoCumAck == true) &&
989  (chunk->numberOfRetransmissions > 0))
990  {
991  path->rtxPseudoCumAck = chunk->tsn;
992  path->findRTXPseudoCumAck = false;
993  }
994  if ((isAcked) && /* Not acked before and acked now => ack for the first time */
995  (path->rtxPseudoCumAck == chunk->tsn))
996  {
997  path->newRTXPseudoCumAck = true;
998  path->findRTXPseudoCumAck = true;
999  }
1000  }
1001 }
CUCVariant cmtCUCVariant
Definition: SCTPAssociation.h:714
Definition: SCTPAssociation.h:711
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool chunkHasBeenAcked(const SCTPDataVariables *chunk) const
Definition: SCTPAssociation.h:1448
void inet::sctp::SCTPAssociation::cwndUpdateAfterCwndTimeout ( SCTPPathVariables path)
protected

Referenced by stateEntered().

981 {
982  // When the association does not transmit data on a given transport address
983  // within an RTO, the cwnd of the transport address SHOULD be adjusted to 2*MTU.
984  EV_INFO << assocId << ": " << simTime() << ":\tCC [cwndUpdateAfterCwndTimeout]\t" << path->remoteAddress
985  << " (cmtCCGroup=" << path->cmtCCGroup << ")"
986  << "\tsst=" << path->ssthresh
987  << "\tcwnd=" << path->cwnd;
988  path->cwnd = getInitialCwnd(path);
989  EV_INFO << "\t=>\tsst=" << path->ssthresh
990  << "\tcwnd=" << path->cwnd << endl;
991  recordCwndUpdate(path);
992 }
void recordCwndUpdate(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:355
uint32 getInitialCwnd(const SCTPPathVariables *path) const
Definition: SCTPCCFunctions.cc:379
int32 assocId
Definition: SCTPAssociation.h:908
void inet::sctp::SCTPAssociation::cwndUpdateAfterRtxTimeout ( SCTPPathVariables path)
protected

Referenced by stateEntered().

833 {
834  double decreaseFactor = 0.5;
835  path->oliaSentBytes = 0;
836  EV << assocId << ": " << simTime() << ":\tCC [cwndUpdateAfterRtxTimeout]\t" << path->remoteAddress
837  << " (cmtCCGroup=" << path->cmtCCGroup << ")"
838  << "\tsst=" << path->ssthresh
839  << "\tcwnd=" << path->cwnd
840  << "\tSST=" << path->cmtGroupTotalSsthresh
841  << "\tCWND=" << path->cmtGroupTotalCwnd
842  << "\tBW.CWND=" << path->cmtGroupTotalCwndBandwidth;
843  if (state->highSpeedCC == true) {
844  decreaseFactor = HighSpeedCwndAdjustmentTable[path->highSpeedCCThresholdIdx].decreaseFactor;
845  EV << "\tHighSpeedDecreaseFactor=" << decreaseFactor;
846  }
847 
848  // ====== SCTP or CMT-SCTP (independent congestion control) ==============
849  if ((state->allowCMT == false) || (state->cmtCCVariant == SCTPStateVariables::CCCV_CMT)) {
850  path->ssthresh = max((int32)path->cwnd - (int32)rint(decreaseFactor * (double)path->cwnd),
851  4 * (int32)path->pmtu);
852  path->cwnd = path->pmtu;
853  }
854  // ====== Resource Pooling RTX Timeout ===================================
855  else {
856  // ====== CMT/RPv1-SCTP RTX Timeout ===================================
858  const double sstRatio = (double)path->ssthresh / (double)path->cmtGroupTotalSsthresh;
859  const int32 decreasedWindow = (int32)path->cwnd - (int32)rint(path->cmtGroupTotalCwnd * decreaseFactor);
860  path->ssthresh = max(decreasedWindow,
861  max((int32)path->pmtu,
862  (int32)ceil((double)state->rpMinCwnd * (double)path->pmtu * sstRatio)));
863  path->cwnd = max((int32)path->pmtu,
864  (int32)ceil((double)path->pmtu * sstRatio));
865  }
866  // ====== CMT/RPv2-SCTP RTX Timeout ===================================
868  const double pathBandwidth = path->cwnd / GET_SRTT(path->srtt.dbl());
869  const double bandwidthToGive = path->cmtGroupTotalCwndBandwidth / 2.0;
870  const double reductionFactor = max(0.5, bandwidthToGive / pathBandwidth);
871 
872  path->ssthresh = (int32)max((int32)state->rpMinCwnd * (int32)path->pmtu,
873  (int32)ceil(path->cwnd - reductionFactor * path->cwnd));
874  path->cwnd = path->pmtu;
875  }
876  // ====== Like MPTCP RTX Timeout ======================================
878  path->ssthresh = max((int32)path->cwnd - (int32)rint(decreaseFactor * (double)path->cwnd),
879  (int32)state->rpMinCwnd * (int32)path->pmtu);
880  path->cwnd = path->pmtu;
881  }
883  // like draft
884  path->ssthresh = max((int32) path->cwnd - (int32) rint(decreaseFactor * (double) path->cwnd),
885  4 * (int32) path->pmtu);
886  path->cwnd = path->pmtu;
887  }
888  // ====== TEST RTX Timeout ============================================
890  const double pathBandwidth = path->cwnd / GET_SRTT(path->srtt.dbl());
891  const double bandwidthToGive = path->cmtGroupTotalCwndBandwidth / 2.0;
892  const double reductionFactor = max(0.5, bandwidthToGive / pathBandwidth);
893 
894  path->ssthresh = (int32)max((int32)state->rpMinCwnd * (int32)path->pmtu,
895  (int32)ceil(path->cwnd - reductionFactor * path->cwnd));
896  path->cwnd = path->pmtu;
897  }
898  // ====== Like MPTCP RTX Timeout ======================================
900  path->ssthresh = max((int32)path->cwnd - (int32)rint(decreaseFactor * (double)path->cwnd),
901  (int32)state->rpMinCwnd * (int32)path->pmtu);
902  path->cwnd = path->pmtu;
903  }
904  // ====== Other -> error ==============================================
905  else {
906  throw cRuntimeError("Implementation for this cmtCCVariant is missing!");
907  }
908  }
909  path->highSpeedCCThresholdIdx = 0;
910  path->partialBytesAcked = 0;
911  path->vectorPathPbAcked->record(path->partialBytesAcked);
912  EV_INFO << "\t=>\tsst=" << path->ssthresh
913  << "\tcwnd=" << path->cwnd << endl;
914  recordCwndUpdate(path);
915 
916  // Leave Fast Recovery mode
917  if (path->fastRecoveryActive == true) {
918  path->fastRecoveryActive = false;
919  path->fastRecoveryExitPoint = 0;
920  path->vectorPathFastRecoveryState->record(0);
921  }
922 }
Definition: SCTPAssociation.h:760
void recordCwndUpdate(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:355
Definition: SCTPAssociation.h:765
Definition: SCTPAssociation.h:759
bool allowCMT
Definition: SCTPAssociation.h:705
double decreaseFactor
Definition: SCTPCCFunctions.cc:44
CCCVariant cmtCCVariant
Definition: SCTPAssociation.h:767
Definition: SCTPAssociation.h:762
int32_t int32
Definition: Compat.h:31
bool highSpeedCC
Definition: SCTPAssociation.h:754
int32 assocId
Definition: SCTPAssociation.h:908
Definition: SCTPAssociation.h:761
Definition: SCTPAssociation.h:763
Definition: SCTPAssociation.h:764
uint32 rpMinCwnd
Definition: SCTPAssociation.h:770
double max(const double a, const double b)
Returns the maximum of a and b.
Definition: SCTPAssociation.h:275
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::cwndUpdateAfterSack ( )
protected

Referenced by stateEntered().

436 {
437  for (auto iter = sctpPathMap.begin(); iter != sctpPathMap.end(); iter++) {
438  SCTPPathVariables *path = iter->second;
439  if (path->fastRecoveryActive == false) {
440  // ====== Retransmission required -> reduce congestion window ======
441  if (path->requiresRtx) {
442  double decreaseFactor = 0.5;
443  EV << assocId << ": " << simTime() << ":\tCC [cwndUpdateAfterSack]\t" << path->remoteAddress
444  << " (cmtCCGroup=" << path->cmtCCGroup << ")"
445  << "\tsst=" << path->ssthresh
446  << "\tcwnd=" << path->cwnd
447  << "\tSST=" << path->cmtGroupTotalSsthresh
448  << "\tCWND=" << path->cmtGroupTotalCwnd
449  << "\tBW.CWND=" << path->cmtGroupTotalCwndBandwidth;
450  if (state->highSpeedCC == true) {
451  decreaseFactor = HighSpeedCwndAdjustmentTable[path->highSpeedCCThresholdIdx].decreaseFactor;
452  EV << "\tHighSpeedDecreaseFactor=" << decreaseFactor;
453  }
454 
455  // ====== SCTP or CMT-SCTP (independent congestion control) =====
456  if ((state->allowCMT == false) ||
458  {
459  EV_INFO << simTime() << ":\tCC [cwndUpdateAfterSack]\t" << path->remoteAddress
460  << "\tsst=" << path->ssthresh << " cwnd=" << path->cwnd;
461 
462  path->ssthresh = max((int32)path->cwnd - (int32)rint(decreaseFactor * (double)path->cwnd),
463  4 * (int32)path->pmtu);
464  path->cwnd = path->ssthresh;
465  }
466  // ====== Resource Pooling ======================================
467  else {
468  // ====== CMT/RP-SCTPv1 Fast Retransmit ======================
470  const double sstRatio = (double)path->ssthresh / (double)path->cmtGroupTotalSsthresh;
471  const int32 reducedCwnd = rpPathBlockingControl(path, rint(path->cmtGroupTotalCwnd * decreaseFactor));
472  path->ssthresh = max(reducedCwnd,
473  max((int32)path->pmtu,
474  (int32)ceil((double)state->rpMinCwnd * (double)path->pmtu * sstRatio)));
475  path->cwnd = path->ssthresh;
476  }
477  // ====== CMT/RPv2-SCTP Fast Retransmit ======================
479  // Bandwidth is based on cwnd, *not* ssthresh!
480  const double pathBandwidth = path->cwnd / GET_SRTT(path->srtt.dbl());
481  const double bandwidthToGive = path->cmtGroupTotalCwndBandwidth / 2.0;
482  const double reductionFactor = max(0.5, bandwidthToGive / pathBandwidth);
483  const int32 reducedCwnd = rpPathBlockingControl(path, reductionFactor * path->cwnd);
484  path->ssthresh = (int32)max(reducedCwnd, (int32)state->rpMinCwnd * (int32)path->pmtu);
485  path->cwnd = path->ssthresh;
486  }
487  // ====== Like MPTCP Fast Retransmit =========================
489  // Just like plain CMT-SCTP ...
490  const int32 reducedCwnd = rpPathBlockingControl(path, rint(decreaseFactor * (double)path->cwnd));
491  path->ssthresh = max(reducedCwnd, (int32)state->rpMinCwnd * (int32)path->pmtu);
492  path->cwnd = path->ssthresh;
493  }
495  // like draft
496  path->ssthresh = max((int32) path->cwnd-(int32) rint(decreaseFactor * (double) path->cwnd),
497  4 * (int32) path->pmtu);
498  path->cwnd = path->ssthresh;
499  }
500  // ====== TEST Fast Retransmit ===============================
502  // Bandwidth is based on cwnd, *not* ssthresh!
503  const double pathBandwidth = path->cwnd / GET_SRTT(path->srtt.dbl());
504  const double bandwidthToGive = path->cmtGroupTotalCwndBandwidth / 2.0;
505  const double reductionFactor = max(0.5, bandwidthToGive / pathBandwidth);
506  const int32 reducedCwnd = rpPathBlockingControl(path, reductionFactor * path->cwnd);
507  path->ssthresh = (int32)max(reducedCwnd, (int32)state->rpMinCwnd * (int32)path->pmtu);
508  path->cwnd = path->ssthresh;
509  }
510  // ====== TEST Fast Retransmit ===============================
512  // Just like CMT-SCTP ...
513  const int32 reducedCwnd = rpPathBlockingControl(path, rint(decreaseFactor * (double)path->cwnd));
514  path->ssthresh = max(reducedCwnd, (int32)state->rpMinCwnd * (int32)path->pmtu);
515  path->cwnd = path->ssthresh;
516  }
517  // ====== Other -> error =====================================
518  else {
519  throw cRuntimeError("Implementation for this cmtCCVariant is missing!");
520  }
521  }
522 
523  EV_INFO << "\t=>\tsst=" << path->ssthresh << " cwnd=" << path->cwnd << endl;
524  recordCwndUpdate(path);
525  path->partialBytesAcked = 0;
526  path->vectorPathPbAcked->record(path->partialBytesAcked);
527  if (state->highSpeedCC == true) {
529  }
530 
531  // ====== Fast Recovery ========================================
533  uint32 highestAckOnPath = state->lastTsnAck;
534  uint32 highestOutstanding = state->lastTsnAck;
535  for (SCTPQueue::PayloadQueue::const_iterator chunkIterator = retransmissionQ->payloadQueue.begin();
536  chunkIterator != retransmissionQ->payloadQueue.end(); chunkIterator++)
537  {
538  const SCTPDataVariables *chunk = chunkIterator->second;
539  if (chunk->getLastDestinationPath() == path) {
540  if (chunkHasBeenAcked(chunk)) {
541  if (tsnGt(chunk->tsn, highestAckOnPath)) {
542  highestAckOnPath = chunk->tsn;
543  }
544  }
545  else {
546  if (tsnGt(chunk->tsn, highestOutstanding)) {
547  highestOutstanding = chunk->tsn;
548  }
549  }
550  }
551  }
552  path->oliaSentBytes = 0;
553  /* this can ONLY become TRUE, when Fast Recovery IS supported */
554  path->fastRecoveryActive = true;
555  path->fastRecoveryExitPoint = highestOutstanding;
556  path->fastRecoveryEnteringTime = simTime();
557  path->vectorPathFastRecoveryState->record(path->cwnd);
558 
559  EV_INFO << simTime() << ":\tCC [cwndUpdateAfterSack] Entering Fast Recovery on path "
560  << path->remoteAddress
561  << ", exit point is " << path->fastRecoveryExitPoint
562  << ", pseudoCumAck=" << path->pseudoCumAck
563  << ", rtxPseudoCumAck=" << path->rtxPseudoCumAck << endl;
564  }
565  }
566  }
567  else {
568  for (auto & elem : sctpPathMap) {
569  SCTPPathVariables *path = elem.second;
570  if (path->fastRecoveryActive) {
571  EV_INFO << assocId << ": " << simTime() << ":\tCC [cwndUpdateAfterSack] Still in Fast Recovery on path "
572  << path->remoteAddress
573  << ", exit point is " << path->fastRecoveryExitPoint << endl;
574  }
575  }
576  }
577  }
578 }
Definition: SCTPAssociation.h:760
void recordCwndUpdate(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:355
uint32 lastTsnAck
Definition: SCTPAssociation.h:614
Definition: SCTPAssociation.h:765
Definition: SCTPAssociation.h:759
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
bool allowCMT
Definition: SCTPAssociation.h:705
bool fastRecoverySupported
Definition: SCTPAssociation.h:584
double decreaseFactor
Definition: SCTPCCFunctions.cc:44
CCCVariant cmtCCVariant
Definition: SCTPAssociation.h:767
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
void updateHighSpeedCCThresholdIdx(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:123
Definition: SCTPAssociation.h:762
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
int32 rpPathBlockingControl(SCTPPathVariables *path, const double reduction)
Definition: SCTPCCFunctions.cc:412
bool highSpeedCC
Definition: SCTPAssociation.h:754
static int32 tsnGt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1081
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
int32 assocId
Definition: SCTPAssociation.h:908
Definition: SCTPAssociation.h:761
Definition: SCTPAssociation.h:763
Definition: SCTPAssociation.h:764
uint32 rpMinCwnd
Definition: SCTPAssociation.h:770
double max(const double a, const double b)
Returns the maximum of a and b.
Definition: SCTPAssociation.h:275
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool chunkHasBeenAcked(const SCTPDataVariables *chunk) const
Definition: SCTPAssociation.h:1448
void inet::sctp::SCTPAssociation::cwndUpdateBeforeSack ( )
protected

Referenced by stateEntered().

141 {
142  // First, calculate per-path values.
143  for (auto & elem : sctpPathMap)
144  {
145  SCTPPathVariables *otherPath = elem.second;
146  otherPath->utilizedCwnd = otherPath->outstandingBytesBeforeUpdate;
147  }
148 
149  // Calculate per-path-group values.
150  for (auto currentPathIterator = sctpPathMap.begin();
151  currentPathIterator != sctpPathMap.end(); currentPathIterator++)
152  {
153  SCTPPathVariables *currentPath = currentPathIterator->second;
154 
155  currentPath->cmtGroupPaths = 0;
156  currentPath->cmtGroupTotalCwnd = 0;
157  currentPath->cmtGroupTotalSsthresh = 0;
158  currentPath->cmtGroupTotalUtilizedCwnd = 0;
159  currentPath->cmtGroupTotalCwndBandwidth = 0.0;
160  currentPath->cmtGroupTotalUtilizedCwndBandwidth = 0.0;
161 
162  double qNumerator = 0.0;
163  double qDenominator = 0.0;
164  for (SCTPPathMap::const_iterator otherPathIterator = sctpPathMap.begin();
165  otherPathIterator != sctpPathMap.end(); otherPathIterator++)
166  {
167  const SCTPPathVariables *otherPath = otherPathIterator->second;
168  if (otherPath->cmtCCGroup == currentPath->cmtCCGroup) {
169  currentPath->cmtGroupPaths++;
170 
171  currentPath->cmtGroupTotalCwnd += otherPath->cwnd;
172  currentPath->cmtGroupTotalSsthresh += otherPath->ssthresh;
173  currentPath->cmtGroupTotalCwndBandwidth += otherPath->cwnd / GET_SRTT(otherPath->srtt.dbl());
174 
175  if ((otherPath->blockingTimeout < 0.0) || (otherPath->blockingTimeout < simTime())) {
176  currentPath->cmtGroupTotalUtilizedCwnd += otherPath->utilizedCwnd;
177  currentPath->cmtGroupTotalUtilizedCwndBandwidth += otherPath->utilizedCwnd / GET_SRTT(otherPath->srtt.dbl());
178  }
179 
180  qNumerator = max(qNumerator, otherPath->cwnd / (pow(GET_SRTT(otherPath->srtt.dbl()), 2.0)));
181  qDenominator = qDenominator + (otherPath->cwnd / GET_SRTT(otherPath->srtt.dbl()));
182  }
183  }
184  currentPath->cmtGroupAlpha = currentPath->cmtGroupTotalCwnd * (qNumerator / pow(qDenominator, 2.0));
185  }
186 }
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
double max(const double a, const double b)
Returns the maximum of a and b.
Definition: SCTPAssociation.h:275
void inet::sctp::SCTPAssociation::cwndUpdateBytesAcked ( SCTPPathVariables path,
const uint32  ackedBytes,
const bool  ctsnaAdvanced 
)
protected

Referenced by stateEntered().

610 {
611  EV_INFO << simTime() << "====> cwndUpdateBytesAcked:"
612  << " path=" << path->remoteAddress
613  << " ackedBytes=" << ackedBytes
614  << " ctsnaAdvanced=" << ((ctsnaAdvanced == true) ? "yes" : "no")
615  << " cwnd=" << path->cwnd
616  << " ssthresh=" << path->ssthresh
617  << " ackedBytes=" << ackedBytes
618  << " pathOsbBeforeUpdate=" << path->outstandingBytesBeforeUpdate
619  << " pathOsb=" << path->outstandingBytes
620  << endl;
621 
622  if (path->fastRecoveryActive == false) {
623  // T.D. 21.11.09: Increasing cwnd is only allowed when not being in
624  // Fast Recovery mode!
625 
626  // ====== Slow Start ==================================================
627  if (path->cwnd <= path->ssthresh) {
628  // ------ Clear PartialBytesAcked counter --------------------------
629  path->partialBytesAcked = 0;
630 
631  // ------ Increase Congestion Window -------------------------------
632  if ((ctsnaAdvanced == true) &&
633  ((path->outstandingBytesBeforeUpdate >= path->cwnd) ||
634  ((state->strictCwndBooking) && (path->outstandingBytesBeforeUpdate + path->pmtu > path->cwnd))))
635  {
636  EV_INFO << assocId << ": " << simTime() << ":\tCC [cwndUpdateBytesAcked-SlowStart]\t" << path->remoteAddress
637  << " (cmtCCGroup=" << path->cmtCCGroup << ")"
638  << "\tacked=" << ackedBytes
639  << "\tsst=" << path->ssthresh
640  << "\tcwnd=" << path->cwnd
641  << "\tSST=" << path->cmtGroupTotalSsthresh
642  << "\tCWND=" << path->cmtGroupTotalCwnd
643  << "\tBW.CWND=" << path->cmtGroupTotalCwndBandwidth;
644 
645  // ====== SCTP or CMT-SCTP (independent congestion control) =====
646  if ((state->allowCMT == false) || (state->cmtCCVariant == SCTPStateVariables::CCCV_CMT)) {
647  path->cwnd += (int32)min(path->pmtu, ackedBytes);
648  }
649  // ====== Resource Pooling Slow Start ===========================
650  else {
651  // ====== CMT/RPv1-SCTP Slow Start ===========================
653  const double sstRatio = (double)path->ssthresh / (double)path->cmtGroupTotalSsthresh;
654  path->cwnd += (int32)ceil(min(path->pmtu, ackedBytes) * sstRatio);
655  }
656  // ====== CMT/RPv2-SCTP Slow Start ===========================
658  // Increase ratio based on cwnd bandwidth share!
659  const double increaseRatio = ((double)path->cwnd / GET_SRTT(path->srtt.dbl()))
660  / (double)path->cmtGroupTotalCwndBandwidth;
661  path->cwnd += (int32)ceil(min(path->pmtu, ackedBytes) * increaseRatio);
662  }
663  // ====== Like MPTCP Slow Start ==============================
665  // T.D. 14.08.2011: Rewrote MPTCP-Like CC code
666  path->cwnd = updateMPTCP(path->cwnd, path->cmtGroupTotalCwnd,
667  path->cmtGroupAlpha, path->pmtu, ackedBytes);
668  }
670  // OLIA see draft
671  path->cwnd = updateOLIA(path->cwnd, path->ssthresh,
672  path->cmtGroupTotalCwnd, path->cmtGroupAlpha,
673  path->pmtu, ackedBytes, path);
674  }
675  // ====== TEST Slow Start ====================================
677  // Increase ratio based on cwnd bandwidth share!
678  const double increaseRatio = ((double)path->utilizedCwnd / GET_SRTT(path->srtt.dbl()))
679  / (double)path->cmtGroupTotalUtilizedCwndBandwidth;
680  path->cwnd += (int32)ceil(min(path->pmtu, ackedBytes) * increaseRatio);
681  }
682  // ====== Like MPTCP Slow Start ==============================
684  path->cwnd = updateMPTCP(path->cwnd, path->cmtGroupTotalCwnd,
685  path->cmtGroupAlpha, path->pmtu, ackedBytes);
686  }
687  // ====== Other -> error =====================================
688  else {
689  throw cRuntimeError("Implementation for this cmtCCVariant is missing!");
690  }
691  }
692  path->vectorPathPbAcked->record(path->partialBytesAcked);
693  EV << "\t=>\tsst=" << path->ssthresh
694  << "\tcwnd=" << path->cwnd << endl;
695 
696  recordCwndUpdate(path);
697  }
698  // ------ No need to increase Congestion Window --------------------
699  else {
700  EV_INFO << assocId << ": " << simTime() << ":\tCC "
701  << "Not increasing cwnd of path " << path->remoteAddress << " in slow start:\t"
702  << "ctsnaAdvanced=" << ((ctsnaAdvanced == true) ? "yes" : "no") << "\t"
703  << "cwnd=" << path->cwnd << "\t"
704  << "ssthresh=" << path->ssthresh << "\t"
705  << "ackedBytes=" << ackedBytes << "\t"
706  << "pathOsbBeforeUpdate=" << path->outstandingBytesBeforeUpdate << "\t"
707  << "pathOsb=" << path->outstandingBytes << "\t"
708  << "(pathOsbBeforeUpdate >= path->cwnd)="
709  << (path->outstandingBytesBeforeUpdate >= path->cwnd) << endl;
710  }
711  }
712  // ====== Congestion Avoidance ========================================
713  else {
714  // ------ Increase PartialBytesAcked counter -----------------------
715  path->partialBytesAcked += ackedBytes;
716 
717  // ------ Increase Congestion Window -------------------------------
718  double increaseFactor = 1.0;
719  if (state->highSpeedCC == true) {
721  increaseFactor = HighSpeedCwndAdjustmentTable[path->highSpeedCCThresholdIdx].increaseFactor;
722  EV << "HighSpeedCC Increase: factor=" << increaseFactor << endl;
723  }
724 
725  const bool avancedAndEnoughOutstanding =
726  (ctsnaAdvanced == true) &&
727  ((path->outstandingBytesBeforeUpdate >= path->cwnd) ||
728  ((state->strictCwndBooking) &&
729  (path->outstandingBytesBeforeUpdate + path->pmtu > path->cwnd)));
730  const bool enoughPartiallyAcked =
731  (path->partialBytesAcked >= path->cwnd) ||
732  ((state->strictCwndBooking) &&
733  (path->partialBytesAcked >= path->pmtu) &&
734  (path->partialBytesAcked + path->pmtu > path->cwnd));
735 
736  if (avancedAndEnoughOutstanding && enoughPartiallyAcked) {
737  EV << assocId << ": " << simTime() << ":\tCC [cwndUpdateBytesAcked-CgAvoidance]\t" << path->remoteAddress
738  << " (cmtCCGroup=" << path->cmtCCGroup << ")"
739  << "\tacked=" << ackedBytes
740  << "\tsst=" << path->ssthresh
741  << "\tcwnd=" << path->cwnd
742  << "\tSST=" << path->cmtGroupTotalSsthresh
743  << "\tCWND=" << path->cmtGroupTotalCwnd
744  << "\tBW.CWND=" << path->cmtGroupTotalCwndBandwidth;
745 
746  // ====== SCTP or CMT-SCTP (independent congestion control) =====
747  if ((state->allowCMT == false) || (state->cmtCCVariant == SCTPStateVariables::CCCV_CMT)) {
748  path->cwnd += (int32)rint(increaseFactor * path->pmtu);
749  }
750  // ====== Resource Pooling Congestion Avoidance =================
751  else {
752  // ====== CMT/RP-SCTP Congestion Avoidance ===================
754  const double sstRatio = (double)path->ssthresh / (double)path->cmtGroupTotalSsthresh;
755  path->cwnd += (int32)ceil(increaseFactor * path->pmtu * sstRatio);
756  }
757  // ====== CMT/RPv2-SCTP Congestion Avoidance =================
759  // Increase ratio based on cwnd bandwidth share!
760  const double increaseRatio = ((double)path->cwnd / GET_SRTT(path->srtt.dbl()))
761  / (double)path->cmtGroupTotalCwndBandwidth;
762  path->cwnd += (int32)ceil(increaseFactor * path->pmtu * increaseRatio);
763  }
764  // ====== Like MPTCP Congestion Avoidance ====================
766  // T.D. 14.08.2011: Rewrote MPTCP-Like CC code
767  path->cwnd = updateMPTCP(path->cwnd, path->cmtGroupTotalCwnd,
768  path->cmtGroupAlpha, path->pmtu, path->pmtu);
769  }
771  // like draft
772  path->cwnd = updateOLIA(path->cwnd, path->ssthresh,
773  path->cmtGroupTotalCwnd, path->cmtGroupAlpha,
774  path->pmtu, path->pmtu, path);
775  }
776  // ====== TEST Congestion Avoidance ==========================
778  // Increase ratio based on cwnd bandwidth share!
779  const double increaseRatio = ((double)path->utilizedCwnd / GET_SRTT(path->srtt.dbl()))
780  / (double)path->cmtGroupTotalUtilizedCwndBandwidth;
781  path->cwnd += (int32)ceil(increaseFactor * path->pmtu * increaseRatio);
782  }
783  // ====== TEST Congestion Avoidance ==========================
785  path->cwnd = updateMPTCP(path->cwnd, path->cmtGroupTotalCwnd,
786  path->cmtGroupAlpha, path->pmtu, path->pmtu);
787  }
788  // ====== Other -> error =====================================
789  else {
790  throw cRuntimeError("Implementation for this cmtCCVariant is missing!");
791  }
792  }
793  EV << "\t=>\tsst=" << path->ssthresh
794  << "\tcwnd=" << path->cwnd << endl;
795 
796  recordCwndUpdate(path);
797  path->partialBytesAcked =
798  ((path->cwnd < path->partialBytesAcked) ?
799  (path->partialBytesAcked - path->cwnd) : 0);
800  }
801  // ------ No need to increase Congestion Window -------------------
802  else {
803  EV_INFO << assocId << ": " << simTime() << ":\tCC "
804  << "Not increasing cwnd of path " << path->remoteAddress << " in congestion avoidance: "
805  << "ctsnaAdvanced=" << ((ctsnaAdvanced == true) ? "yes" : "no") << "\t"
806  << "cwnd=" << path->cwnd << "\t"
807  << "ssthresh=" << path->ssthresh << "\t"
808  << "ackedBytes=" << ackedBytes << "\t"
809  << "pathOsbBeforeUpdate=" << path->outstandingBytesBeforeUpdate << "\t"
810  << "pathOsb=" << path->outstandingBytes << "\t"
811  << "(pathOsbBeforeUpdate >= path->cwnd)="
812  << (path->outstandingBytesBeforeUpdate >= path->cwnd) << "\t"
813  << "partialBytesAcked=" << path->partialBytesAcked << "\t"
814  << "(path->partialBytesAcked >= path->cwnd)="
815  << (path->partialBytesAcked >= path->cwnd) << endl;
816  }
817  }
818 
819  // ====== Reset PartialBytesAcked counter if no more outstanding bytes
820  if (path->outstandingBytes == 0) {
821  path->partialBytesAcked = 0;
822  }
823  path->vectorPathPbAcked->record(path->partialBytesAcked);
824  }
825  else {
826  EV_INFO << assocId << ": " << simTime() << ":\tCC "
827  << "Not increasing cwnd of path " << path->remoteAddress
828  << " during Fast Recovery" << endl;
829  }
830 }
Definition: SCTPAssociation.h:760
void recordCwndUpdate(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:355
Definition: SCTPAssociation.h:765
Definition: SCTPAssociation.h:759
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
bool allowCMT
Definition: SCTPAssociation.h:705
CCCVariant cmtCCVariant
Definition: SCTPAssociation.h:767
uint32 updateOLIA(uint32 w, const uint32 s, const uint32 totalW, double a, const uint32 mtu, const uint32 ackedBytes, SCTPPathVariables *path)
w: cwnd of the path s: ssthresh of the path totalW: Sum of all cwnds of the association a: factor alp...
Definition: SCTPCCFunctions.cc:257
bool strictCwndBooking
Definition: SCTPAssociation.h:745
void updateHighSpeedCCThresholdIdx(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:123
Definition: SCTPAssociation.h:762
int32_t int32
Definition: Compat.h:31
bool highSpeedCC
Definition: SCTPAssociation.h:754
int32 assocId
Definition: SCTPAssociation.h:908
Definition: SCTPAssociation.h:761
double increaseFactor
Definition: SCTPCCFunctions.cc:43
Definition: SCTPAssociation.h:763
Definition: SCTPAssociation.h:764
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::cwndUpdateMaxBurst ( SCTPPathVariables path)
protected

Referenced by stateEntered().

925 {
930  {
931  if (path->cwnd > ((path->outstandingBytes + state->maxBurst * path->pmtu))) {
932  EV_INFO << assocId << ": " << simTime() << ":\tCC [cwndUpdateMaxBurst]\t"
933  << path->remoteAddress
934  << "\tsst=" << path->ssthresh
935  << "\tcwnd=" << path->cwnd
936  << "\ttempCwnd=" << path->tempCwnd
937  << "\tosb=" << path->outstandingBytes
938  << "\tmaxBurst=" << state->maxBurst * path->pmtu;
939 
940  // ====== Update cwnd or tempCwnd, according to MaxBurst variant ===
943  {
944  path->cwnd = path->outstandingBytes + (state->maxBurst * path->pmtu);
945  }
948  {
949  path->tempCwnd = path->outstandingBytes + (state->maxBurst * path->pmtu);
950  }
951  else {
952  assert(false);
953  }
954 
956  if (path->ssthresh < path->cwnd) {
957  path->ssthresh = path->cwnd;
958  }
959  }
961  if (path->ssthresh < path->tempCwnd) {
962  path->ssthresh = path->tempCwnd;
963  }
964  }
965  recordCwndUpdate(path);
966 
967  EV_INFO << "\t=>\tsst=" << path->ssthresh
968  << "\tcwnd=" << path->cwnd
969  << "\ttempCwnd=" << path->tempCwnd
970  << endl;
971  }
972  // ====== Possible transmission will not exceed burst size ============
973  else {
974  // Just store current cwnd to tempCwnd
975  path->tempCwnd = path->cwnd;
976  }
977  }
978 }
MBVariant maxBurstVariant
Definition: SCTPAssociation.h:702
void recordCwndUpdate(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:355
uint32 maxBurst
Definition: SCTPAssociation.h:692
Definition: SCTPAssociation.h:694
int32 assocId
Definition: SCTPAssociation.h:908
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::decreaseOutstandingBytes ( SCTPDataVariables chunk)
private

Referenced by chunkMustBeAbandoned(), handleChunkReportedAsMissing(), moveChunkToOtherPath(), nonRenegablyAckChunk(), putInTransmissionQ(), renegablyAckChunk(), storePacket(), and tsnWasReneged().

42 {
43  SCTPPathVariables *lastPath = chunk->getLastDestinationPath();
44 
45  if (chunk->countsAsOutstanding) {
46  assert(lastPath->outstandingBytes >= chunk->booksize);
47  lastPath->outstandingBytes -= chunk->booksize;
48  lastPath->statisticsPathOutstandingBytes->record(lastPath->outstandingBytes);
49  state->outstandingBytes -= chunk->booksize;
50  SCTPSendStream *stream = nullptr;
51  auto associter = sendStreams.find(chunk->sid);
52  if (associter != sendStreams.end()) {
53  stream = associter->second;
54  } else {
55  throw cRuntimeError("Stream with id %d not found", chunk->sid);
56  }
57  stream->setBytesInFlight(stream->getBytesInFlight() - chunk->booksize);
58  assert((int64)state->outstandingBytes >= 0);
60 
61  chunk->countsAsOutstanding = false;
62 
63  auto iterator = qCounter.roomRetransQ.find(lastPath->remoteAddress);
65  if (state->osbWithHeader)
66  iterator->second -= ADD_PADDING(chunk->booksize);
67  else
68  iterator->second -= ADD_PADDING(chunk->booksize + SCTP_DATA_CHUNK_LENGTH);
69  }
70 }
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
CounterMap roomRetransQ
Definition: SCTPAssociation.h:880
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
bool osbWithHeader
Definition: SCTPAssociation.h:832
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
uint64 outstandingBytes
Definition: SCTPAssociation.h:622
QueueCounter qCounter
Definition: SCTPAssociation.h:965
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
uint32 outstandingMessages
Definition: SCTPAssociation.h:843
cOutVector * statisticsOutstandingBytes
Definition: SCTPAssociation.h:973
int64_t int64
Definition: Compat.h:29
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::deleteStreams ( )

Referenced by inet::sctp::SCTP::removeAssociation().

92 {
93  for (auto & elem : sendStreams) {
94  delete elem.second;
95  }
96  for (auto & elem : receiveStreams) {
97  delete elem.second;
98  }
99 }
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
void inet::sctp::SCTPAssociation::dequeueAckedChunks ( const uint32  tsna,
SCTPPathVariables path,
simtime_t &  rttEstimation 
)
protected

Referenced by process_RCV_Message(), and processSackArrived().

2061 {
2062  SCTP::AssocStat *assocStat = sctpMain->getAssocStat(assocId);
2063 
2064  // Set it ridiculously high
2065  rttEstimation = SIMTIME_MAX;
2066 
2067  // Are there chunks in the retransmission queue ? If Yes -> check for dequeue.
2068  auto iterator = retransmissionQ->payloadQueue.begin();
2069  while (iterator != retransmissionQ->payloadQueue.end()) {
2070  SCTPDataVariables *chunk = iterator->second;
2071  if (tsnGe(tsna, chunk->tsn)) {
2072  EV_DETAIL << simTime() << ": CumAcked TSN " << chunk->tsn
2073  << " on path " << chunk->getLastDestination() << endl;
2074 
2075  if (!chunkHasBeenAcked(chunk)) {
2076  SCTPPathVariables *lastPath = chunk->getLastDestinationPath();
2077  // CumAck affects lastPath -> reset its T3 timer later.
2078  lastPath->newCumAck = true;
2079  // CumAck of SACK has acknowledged this chunk. Handle Pseudo CumAck.
2080  lastPath->findPseudoCumAck = true;
2081  lastPath->newPseudoCumAck = true;
2082  // T.D. 22.11.09: CUCv2
2083  lastPath->findRTXPseudoCumAck = true;
2084  lastPath->newRTXPseudoCumAck = true;
2085  }
2086 
2087  nonRenegablyAckChunk(chunk, sackPath, rttEstimation, assocStat);
2088  }
2089  else {
2090  break;
2091  }
2092  iterator = retransmissionQ->payloadQueue.begin();
2093  }
2094 
2095  EV_DEBUG << "dequeueAckedChunks(): rttEstimation=" << rttEstimation << endl;
2096 }
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void nonRenegablyAckChunk(SCTPDataVariables *chunk, SCTPPathVariables *sackPath, simtime_t &rttEstimation, SCTP::AssocStat *assocStat)
Definition: SCTPAssociationRcvMessage.cc:1877
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
int32 assocId
Definition: SCTPAssociation.h:908
static int32 tsnGe(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1080
AssocStat * getAssocStat(uint32 assocId)
Definition: SCTP.h:225
bool chunkHasBeenAcked(const SCTPDataVariables *chunk) const
Definition: SCTPAssociation.h:1448
SCTPDataMsg * inet::sctp::SCTPAssociation::dequeueOutboundDataMsg ( SCTPPathVariables path,
const int32  availableSpace,
const int32  availableCwnd 
)
protected

Referenced by sendOnPath().

2482 {
2483  SCTPDataMsg *datMsg = nullptr;
2484  cPacketQueue *streamQ = nullptr;
2485  int32 nextStream = -1;
2486 
2487  EV_INFO << "dequeueOutboundDataMsg: " << availableSpace << " bytes left to be sent" << endl;
2488 
2490 
2491  /* Only change stream if we don't have to finish a fragmented message */
2493  nextStream = state->lastStreamScheduled;
2494  else
2495  nextStream = (this->*ssFunctions.ssGetNextSid)(path, false);
2496 
2497  if (nextStream == -1)
2498  return nullptr;
2499 
2500  EV_INFO << "dequeueOutboundDataMsg: now stream " << nextStream << endl;
2501 
2502  SCTPSendStream *stream = sendStreams.find(nextStream)->second;
2503  streamQ = nullptr;
2504 
2505  if (!stream->getUnorderedStreamQ()->isEmpty()) {
2506  streamQ = stream->getUnorderedStreamQ();
2507  EV_DETAIL << "DequeueOutboundDataMsg() found chunks in stream " << nextStream << " unordered queue, queue size=" << stream->getUnorderedStreamQ()->getLength() << "\n";
2508  }
2509  else if (!stream->getStreamQ()->isEmpty()) {
2510  streamQ = stream->getStreamQ();
2511  EV_DETAIL << "DequeueOutboundDataMsg() found chunks in stream " << nextStream << " ordered queue, queue size=" << stream->getStreamQ()->getLength() << "\n";
2512  }
2513 
2514  if (streamQ) {
2515  int32 b = ADD_PADDING(((SCTPDataMsg *)streamQ->front())->getEncapsulatedPacket()->getByteLength() + SCTP_DATA_CHUNK_LENGTH);
2516 
2517  if ((b <= availableSpace) &&
2518  ((int32)((SCTPDataMsg *)streamQ->front())->getBooksize() <= availableCwnd))
2519  {
2520  datMsg = (SCTPDataMsg *)streamQ->pop();
2521  sendQueue->record(streamQ->getLength());
2522 
2523  if (!datMsg->getFragment()) {
2524  datMsg->setBBit(true);
2525  datMsg->setEBit(true);
2526  state->lastMsgWasFragment = false;
2527  }
2528  else {
2529  if (datMsg->getEBit())
2530  state->lastMsgWasFragment = false;
2531  else
2532  state->lastMsgWasFragment = true;
2533  }
2534 
2535  EV_DETAIL << "DequeueOutboundDataMsg() found chunk (" << &datMsg << ") in the stream queue " << nextStream << "(" << streamQ << ") queue size=" << streamQ->getLength() << endl;
2536  }
2537  }
2538 
2539 
2540  if (datMsg != nullptr) {
2541  qCounter.roomSumSendStreams -= ADD_PADDING(datMsg->getEncapsulatedPacket()->getByteLength() + SCTP_DATA_CHUNK_LENGTH);
2542  qCounter.bookedSumSendStreams -= datMsg->getBooksize();
2543  }
2544  return datMsg;
2545 }
bool lastMsgWasFragment
Definition: SCTPAssociation.h:665
uint32 lastStreamScheduled
Definition: SCTPAssociation.h:626
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
cOutVector * sendQueue
Definition: SCTPAssociation.h:956
int32(SCTPAssociation::* ssGetNextSid)(SCTPPathVariables *path, bool peek)
Definition: SCTPAssociation.h:1291
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
uint64 bookedSumSendStreams
Definition: SCTPAssociation.h:876
QueueCounter qCounter
Definition: SCTPAssociation.h:965
int32_t int32
Definition: Compat.h:31
SSFunctions ssFunctions
Definition: SCTPAssociation.h:1294
void fragmentOutboundDataMsgs()
Definition: SCTPAssociationUtil.cc:2350
value< double, units::m > b
Definition: Units.h:1054
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::disposeOf ( SCTPMessage sctpmsg)
protected

Referenced by process_RCV_Message(), processPacketDropArrived(), and sendPacketDrop().

2801 {
2802  SCTPChunk *chunk;
2803  uint32 numberOfChunks = sctpmsg->getChunksArraySize();
2804  if (numberOfChunks > 0)
2805  for (uint32 i = 0; i < numberOfChunks; i++) {
2806  chunk = (SCTPChunk *)(sctpmsg->removeChunk());
2807  if (chunk->getChunkType() == DATA)
2808  delete (SCTPSimpleMessage *)chunk->decapsulate();
2809  delete chunk;
2810  }
2811  delete sctpmsg;
2812 }
Definition: SCTPAssociation.h:111
uint32_t uint32
Definition: Compat.h:30
const char * inet::sctp::SCTPAssociation::eventName ( const int32  event)
staticprotected

Utility: returns name of SCTP_E_xxx constants.

161 {
162 #define CASE(x) case x: \
163  s = #x + 7; break
164  const char *s = "unknown";
165  switch (event) {
171  CASE(SCTP_E_SEND);
200  }
201  return s;
202 #undef CASE
203 }
Definition: SCTPAssociation.h:78
Definition: SCTPAssociation.h:96
Definition: SCTPAssociation.h:97
#define CASE(x)
Definition: SCTPAssociation.h:77
Definition: SCTPAssociation.h:87
Definition: SCTPAssociation.h:85
Definition: SCTPAssociation.h:75
Definition: SCTPAssociation.h:93
Definition: SCTPAssociation.h:101
Definition: SCTPAssociation.h:74
Definition: SCTPAssociation.h:81
Definition: SCTPAssociation.h:105
Definition: SCTPAssociation.h:89
Definition: SCTPAssociation.h:106
Definition: SCTPAssociation.h:73
Definition: SCTPAssociation.h:80
Definition: SCTPAssociation.h:76
Definition: SCTPAssociation.h:86
Definition: SCTPAssociation.h:84
Definition: SCTPAssociation.h:83
Definition: SCTPAssociation.h:95
Definition: SCTPAssociation.h:104
Definition: SCTPAssociation.h:103
Definition: SCTPAssociation.h:79
Definition: SCTPAssociation.h:100
value< double, units::s > s
Definition: Units.h:1049
Definition: SCTPAssociation.h:82
Definition: SCTPAssociation.h:90
Definition: SCTPAssociation.h:88
Definition: SCTPAssociation.h:102
Definition: SCTPAssociation.h:92
Definition: SCTPAssociation.h:91
Definition: SCTPAssociation.h:99
Definition: SCTPAssociation.h:94
Definition: SCTPAssociation.h:72
void inet::sctp::SCTPAssociation::fragmentOutboundDataMsgs ( )
protected

Referenced by dequeueOutboundDataMsg().

2350  {
2351  cPacketQueue *streamQ = nullptr;
2352  for (auto iter = sendStreams.begin(); iter != sendStreams.end(); ++iter) {
2353  SCTPSendStream *stream = iter->second;
2354  streamQ = nullptr;
2355 
2356  if (!stream->getUnorderedStreamQ()->isEmpty()) {
2357  streamQ = stream->getUnorderedStreamQ();
2358  EV_DETAIL << "fragmentOutboundDataMsgs() found chunks in stream " << iter->first << " unordered queue, queue size=" << stream->getUnorderedStreamQ()->getLength() << "\n";
2359  }
2360  else if (!stream->getStreamQ()->isEmpty()) {
2361  streamQ = stream->getStreamQ();
2362  EV_DETAIL << "fragmentOutboundDataMsgs() found chunks in stream " << iter->first << " ordered queue, queue size=" << stream->getStreamQ()->getLength() << "\n";
2363  }
2364 
2365  if (streamQ) {
2366  int32 b = ADD_PADDING(((SCTPDataMsg *)streamQ->front())->getEncapsulatedPacket()->getByteLength() + SCTP_DATA_CHUNK_LENGTH);
2367 
2368  /* check if chunk found in queue has to be fragmented */
2370  /* START FRAGMENTATION */
2371  SCTPDataMsg *datMsgQueued = (SCTPDataMsg *)streamQ->pop();
2372  cPacket *datMsgQueuedEncMsg = datMsgQueued->getEncapsulatedPacket();
2373  SCTPDataMsg *datMsgLastFragment = nullptr;
2374  uint32 offset = 0;
2375  uint32 msgbytes = state->fragPoint;
2376  const uint16 fullSizedPackets = (uint16)(datMsgQueued->getByteLength() / msgbytes);
2377  EV_DETAIL << "Fragmentation: chunk " << &datMsgQueued << " - size = " << datMsgQueued->getByteLength() << endl;
2378  EV_DETAIL << assocId << ": number of fullSizedPackets: " << fullSizedPackets << endl;
2379  uint16 pcounter = 0;
2380 
2381  while (datMsgQueued) {
2382  /* detemine size of fragment, either max payload or what's left */
2383  if (msgbytes > datMsgQueuedEncMsg->getByteLength() - offset)
2384  msgbytes = datMsgQueuedEncMsg->getByteLength() - offset;
2385 
2386  /* new DATA msg */
2387  SCTPDataMsg *datMsgFragment = new SCTPDataMsg();
2388  datMsgFragment->setSid(datMsgQueued->getSid());
2389  datMsgFragment->setPpid(datMsgQueued->getPpid());
2390  if (++pcounter == fullSizedPackets && sctpMain->sackNow)
2391  datMsgFragment->setSackNow(true);
2392  else
2393  datMsgFragment->setSackNow(datMsgQueued->getSackNow());
2394  datMsgFragment->setInitialDestination(datMsgQueued->getInitialDestination());
2395  datMsgFragment->setEnqueuingTime(datMsgQueued->getEnqueuingTime());
2396  datMsgFragment->setPrMethod(datMsgQueued->getPrMethod());
2397  datMsgFragment->setPriority(datMsgQueued->getPriority());
2398  //EV_DETAIL << "felix: " << datMsgQueued->getPriority() << endl;
2399  datMsgFragment->setStrReset(datMsgQueued->getStrReset());
2400  datMsgFragment->setMsgNum(datMsgQueued->getMsgNum());
2401  datMsgFragment->setOrdered(datMsgQueued->getOrdered());
2402  datMsgFragment->setExpiryTime(datMsgQueued->getExpiryTime());
2403  datMsgFragment->setRtx(datMsgQueued->getRtx());
2404  datMsgFragment->setFragment(true);
2405 
2406  if (state->padding)
2407  datMsgFragment->setBooksize(ADD_PADDING(msgbytes + state->header));
2408  else
2409  datMsgFragment->setBooksize(msgbytes + state->header);
2410 
2411  /* is this the first fragment? */
2412  if (offset == 0)
2413  datMsgFragment->setBBit(true);
2414 
2415  /* new msg */
2416  cPacket *datMsgFragmentEncMsg = datMsgQueuedEncMsg->dup();
2417 
2418  datMsgFragmentEncMsg->setByteLength(msgbytes);
2419 
2420  SCTPSimpleMessage *datMsgQueuedSimple = dynamic_cast<SCTPSimpleMessage *>(datMsgQueuedEncMsg);
2421  SCTPSimpleMessage *datMsgFragmentSimple = dynamic_cast<SCTPSimpleMessage *>(datMsgFragmentEncMsg);
2422  if ((datMsgQueuedSimple != nullptr) &&
2423  (datMsgFragmentSimple != nullptr) &&
2424  (datMsgQueuedSimple->getDataArraySize() >= msgbytes + offset))
2425  {
2426  datMsgFragmentSimple->setDataArraySize(msgbytes);
2427  datMsgFragmentSimple->setDataLen(msgbytes);
2428  /* copy data */
2429  for (uint32 i = offset; i < offset + msgbytes; i++) {
2430  datMsgFragmentSimple->setData(i - offset, datMsgQueuedSimple->getData(i));
2431  }
2432  }
2433 
2434  offset += msgbytes;
2435  datMsgFragment->encapsulate(datMsgFragmentEncMsg);
2436 
2437  /* insert fragment into queue */
2438  if (!streamQ->isEmpty()) {
2439  if (!datMsgLastFragment) {
2440  /* insert first fragment at the begining of the queue*/
2441  streamQ->insertBefore((SCTPDataMsg *)streamQ->front(), datMsgFragment);
2442  }
2443  else {
2444  /* insert fragment after last inserted */
2445  streamQ->insertAfter(datMsgLastFragment, datMsgFragment);
2446  }
2447  }
2448  else
2449  streamQ->insert(datMsgFragment);
2450 
2451  state->queuedMessages++;
2452  qCounter.roomSumSendStreams += ADD_PADDING(datMsgFragment->getByteLength() + SCTP_DATA_CHUNK_LENGTH);
2453  qCounter.bookedSumSendStreams += datMsgFragment->getBooksize();
2454  EV_DETAIL << "Fragmentation: fragment " << &datMsgFragment << " created, length = " << datMsgFragmentEncMsg->getByteLength() << ", queue size = " << streamQ->getLength() << endl;
2455 
2456  datMsgLastFragment = datMsgFragment;
2457 
2458  /* all fragments done? */
2459  if (datMsgQueuedEncMsg->getByteLength() == offset) {
2460  datMsgFragment->setEBit(true);
2461  if (sctpMain->sackNow)
2462  datMsgFragment->setSackNow(true);
2463  /* remove original element */
2464  EV_DETAIL << "Fragmentation: delete " << &datMsgQueued << endl;
2465  //streamQ->pop();
2466  qCounter.roomSumSendStreams -= ADD_PADDING(datMsgQueued->getByteLength() + SCTP_DATA_CHUNK_LENGTH);
2467  qCounter.bookedSumSendStreams -= datMsgQueued->getBooksize();
2468  delete datMsgQueued;
2469  datMsgQueued = nullptr;
2470  state->queuedMessages--;
2471  }
2472  } // while
2473  }
2474  }
2475  }
2476 
2477 }
bool sackNow
Definition: SCTP.h:213
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
uint32 fragPoint
Definition: SCTPAssociation.h:628
bool padding
Definition: SCTPAssociation.h:833
uint64 queuedMessages
Definition: SCTPAssociation.h:638
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
SCTP * sctpMain
Definition: SCTPAssociation.h:962
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
uint64 bookedSumSendStreams
Definition: SCTPAssociation.h:876
QueueCounter qCounter
Definition: SCTPAssociation.h:965
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
uint16 header
Definition: SCTPAssociation.h:641
int32 assocId
Definition: SCTPAssociation.h:908
uint16_t uint16
Definition: Compat.h:32
value< double, units::m > b
Definition: Units.h:1054
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::generateSendQueueAbatedIndication ( const uint64  bytes)
private

Referenced by processSackArrived().

2017 {
2019  // Just send SCTP_I_SENDQUEUE_ABATED once, after all newly acked
2020  // chunks have been dequeued.
2021  // Only send indication if the sendBuffer size has dropped below the sendQueueLimit
2022  // assert(state->lastSendQueueAbated < simTime());
2023  state->appSendAllowed = true;
2024  EV_DETAIL << simTime() << ":\tSCTP_I_SENDQUEUE_ABATED("
2025  << bytes << ") to refill buffer "
2026  << state->sendBuffer << "/" << state->sendQueueLimit << endl;
2027 
2028  cPacket *msg = new cPacket(indicationName(SCTP_I_SENDQUEUE_ABATED));
2029  msg->setKind(SCTP_I_SENDQUEUE_ABATED);
2030 
2031  SCTPSendQueueAbated *sendQueueAbatedIndication =
2032  new SCTPSendQueueAbated(indicationName(SCTP_I_SENDQUEUE_ABATED));
2033  sendQueueAbatedIndication->setAssocId(assocId);
2034  sendQueueAbatedIndication->setLocalAddr(localAddr);
2035  sendQueueAbatedIndication->setRemoteAddr(remoteAddr);
2036  sendQueueAbatedIndication->setNumMsgs(bytes); // NOTE: Legacy API!
2037 
2038  sendQueueAbatedIndication->setQueuedForStreamArraySize(sendStreams.size());
2039  unsigned int streamID = 0;
2040  for (auto & elem : sendStreams)
2041  {
2042  const SCTPSendStream *stream = elem.second;
2043  sendQueueAbatedIndication->setQueuedForStream(streamID, stream->getUnorderedStreamQ()->getByteLength() + stream->getStreamQ()->getByteLength());
2044  streamID++;
2045  }
2046 
2047  sendQueueAbatedIndication->setBytesAvailable(state->sendQueueLimit - state->sendBuffer);
2048  sendQueueAbatedIndication->setBytesQueued(state->sendBuffer);
2049  sendQueueAbatedIndication->setBytesLimit(state->sendQueueLimit);
2050 
2051  msg->setControlInfo(sendQueueAbatedIndication);
2052  sctpMain->send(msg, "to_appl", appGateIndex);
2053 
2054  state->lastSendQueueAbated = simTime();
2055  }
2056 }
uint64 sendQueueLimit
Definition: SCTPAssociation.h:659
BytesToBeSent bytes
Definition: SCTPAssociation.h:961
Definition: SCTPCommand.h:77
uint64 sendBuffer
Definition: SCTPAssociation.h:660
static const char * indicationName(const int32 code)
Utility: returns name of SCTP_I_xxx constants.
Definition: SCTPAssociationUtil.cc:206
SCTP * sctpMain
Definition: SCTPAssociation.h:962
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
L3Address remoteAddr
Definition: SCTPAssociation.h:911
L3Address localAddr
Definition: SCTPAssociation.h:912
bool appSendAllowed
Definition: SCTPAssociation.h:661
int32 assocId
Definition: SCTPAssociation.h:908
int32 appGateIndex
Definition: SCTPAssociation.h:907
simtime_t lastSendQueueAbated
Definition: SCTPAssociation.h:662
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int inet::sctp::SCTPAssociation::getAddressLevel ( const L3Address addr)
static

Utility: return IPv4 or IPv6 address level.

Referenced by inet::sctp::SCTPNatHook::datagramForwardHook(), inet::sctp::SCTPNatHook::datagramPreRoutingHook(), processInitArrived(), sendAsconf(), and sendInit().

2815 {
2816  if (addr.getType() == L3Address::IPv6) {
2817  switch (addr.toIPv6().getScope()) {
2820  return 0;
2821 
2822  case IPv6Address::LOOPBACK:
2823  return 1;
2824 
2825  case IPv6Address::LINK:
2826  return 2;
2827 
2828  case IPv6Address::SITE:
2829  return 3;
2830 
2831  case IPv6Address::GLOBAL:
2832  return 4;
2833 
2834  default:
2835  throw cRuntimeError("Unknown IPv6 scope: %d", (int)(addr.toIPv6().getScope()));
2836  }
2837  }
2838  else if (addr.getType() == L3Address::IPv4) {
2839  switch (addr.toIPv4().getAddressCategory()) {
2846  case IPv4Address::IETF:
2847  case IPv4Address::TEST_NET:
2848  case IPv4Address::RESERVED:
2849  return 0;
2850 
2851  case IPv4Address::LOOPBACK:
2852  return 1;
2853 
2855  return 2;
2856 
2858  return 3;
2859 
2860  case IPv4Address::GLOBAL:
2861  return 4;
2862 
2863  default:
2864  throw cRuntimeError("Unknown IPv4 address category: %d", (int)(addr.toIPv4().getAddressCategory()));
2865  }
2866  }
2867  throw cRuntimeError("Unknown address type: %d", (int)(addr.getType()));
2868 }
Definition: IPv6Address.h:59
Definition: IPv6Address.h:57
Definition: IPv4Address.h:88
Definition: L3Address.h:47
Definition: IPv4Address.h:89
Definition: IPv4Address.h:87
Definition: IPv4Address.h:93
Definition: IPv6Address.h:58
Definition: IPv4Address.h:85
Definition: IPv4Address.h:91
Definition: IPv4Address.h:96
Definition: IPv6Address.h:56
Definition: IPv6Address.h:60
Definition: IPv4Address.h:95
Definition: IPv4Address.h:94
Definition: IPv4Address.h:90
Definition: IPv4Address.h:86
Definition: IPv6Address.h:55
Definition: IPv4Address.h:97
Definition: L3Address.h:46
Definition: IPv4Address.h:92
uint32 inet::sctp::SCTPAssociation::getAllTransQ ( )
protected

Referenced by sendOnPath().

1478 {
1479  uint32 sum = 0;
1480  for (auto & elem : qCounter.roomTransQ) {
1481  sum += elem.second;
1482  }
1483  return sum;
1484 }
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
QueueCounter qCounter
Definition: SCTPAssociation.h:965
uint32_t uint32
Definition: Compat.h:30
uint32 inet::sctp::SCTPAssociation::getBytesInFlightOfStream ( uint16  sid)
protected

Referenced by checkStreamsToReset(), process_STREAM_RESET(), and processIncomingResetRequestArrived().

79 {
80  auto streamIterator = sendStreams.find(sid);
81  assert(streamIterator != sendStreams.end());
82  return (streamIterator->second)->getBytesInFlight();
83 }
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
uint32 inet::sctp::SCTPAssociation::getExpectedSsnOfStream ( uint16  id)
protected

Referenced by processOutgoingResetRequestArrived().

862 {
863  uint16 str;
864  auto iterator = receiveStreams.find(id);
865  str = iterator->second->getExpectedStreamSeqNum();
866  return str;
867 }
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
uint16_t uint16
Definition: Compat.h:32
bool inet::sctp::SCTPAssociation::getFragInProgressOfStream ( uint16  sid)
protected

Referenced by process_STREAM_RESET(), and processIncomingResetRequestArrived().

101 {
102  auto streamIterator = sendStreams.find(sid);
103  assert(streamIterator != sendStreams.end());
104  return (streamIterator->second)->getFragInProgress();
105 }
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
cFSM* inet::sctp::SCTPAssociation::getFsm ( ) const
inline
1023 { return fsm; };
cFSM * fsm
Definition: SCTPAssociation.h:963
int32 inet::sctp::SCTPAssociation::getFsmState ( ) const
inline
1017 { return fsm->getState(); };
cFSM * fsm
Definition: SCTPAssociation.h:963
uint32 inet::sctp::SCTPAssociation::getInitialCwnd ( const SCTPPathVariables path) const
private
380 {
381  uint32 newCwnd;
382 
383  const uint32 upperLimit = (state->initialWindow > 0) ? (state->initialWindow * path->pmtu) : max(2 * path->pmtu, 4380);
384  if ((state->allowCMT == false) || (state->cmtCCVariant == SCTPStateVariables::CCCV_CMT)) {
385  newCwnd = (int32)min((state->initialWindow > 0) ? (state->initialWindow * path->pmtu) : (4 * path->pmtu),
386  upperLimit);
387  }
388  else {
389  newCwnd = (int32)min((int32)ceil(((state->initialWindow > 0) ?
390  (state->initialWindow * path->pmtu) :
391  (4 * path->pmtu)) / (double)sctpPathMap.size()),
392  upperLimit);
393  if (newCwnd < path->pmtu) { // T.D. 09.09.2010: cwnd < MTU makes no sense ...
394  newCwnd = path->pmtu;
395  }
396  } return newCwnd;
397 }
Definition: SCTPAssociation.h:759
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
bool allowCMT
Definition: SCTPAssociation.h:705
uint32 initialWindow
Definition: SCTPAssociation.h:703
CCCVariant cmtCCVariant
Definition: SCTPAssociation.h:767
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
double max(const double a, const double b)
Returns the maximum of a and b.
Definition: SCTPAssociation.h:275
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
cMessage* inet::sctp::SCTPAssociation::getInitTimer ( ) const
inline
1024 { return T1_InitTimer; };
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
const L3Address& inet::sctp::SCTPAssociation::getNextAddress ( const SCTPPathVariables oldPath) const
inlineprotected

Referenced by sendAsconf().

1221  {
1222  const SCTPPathVariables *nextPath = getNextPath(oldPath);
1223  if (nextPath != nullptr) {
1224  return nextPath->remoteAddress;
1225  }
1227  }
static const L3Address zeroAddress
Definition: SCTPAssociation.h:528
SCTPPathVariables * getNextPath(const SCTPPathVariables *oldPath) const
Definition: SCTPAssociationUtil.cc:2594
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
SCTPPathVariables * inet::sctp::SCTPAssociation::getNextDestination ( SCTPDataVariables chunk) const
protected

Referenced by handleChunkReportedAsMissing(), and process_TIMEOUT_RTX().

2619 {
2620  SCTPPathVariables *next;
2621 
2622  EV_DEBUG << "Running getNextDestination()" << endl;
2623  if (chunk->numberOfTransmissions == 0) {
2624  if (chunk->getInitialDestinationPath() == nullptr) {
2625  next = state->getPrimaryPath();
2626  }
2627  else {
2628  next = chunk->getInitialDestinationPath();
2629  }
2630  }
2631  else {
2632  if (chunk->hasBeenFastRetransmitted) {
2633  EV_DETAIL << "Chunk " << chunk->tsn << " is scheduled for FastRetransmission. Next destination = "
2634  << chunk->getLastDestination() << endl;
2635  return chunk->getLastDestinationPath();
2636  }
2637  // If this is a retransmission, we should choose another, active path.
2638  SCTPPathVariables *last = chunk->getLastDestinationPath();
2639  next = getNextPath(last);
2640  if ((next == nullptr) || (next->confirmed == false)) {
2641  next = last;
2642  }
2643  }
2644 
2645  EV_INFO << "getNextDestination(): chunk was last sent to " << chunk->getLastDestination()
2646  << ", will next be sent to path " << next->remoteAddress << endl;
2647  return next;
2648 }
SCTPPathVariables * getPrimaryPath() const
Definition: SCTPAssociation.h:558
SCTPPathVariables * getNextPath(const SCTPPathVariables *oldPath) const
Definition: SCTPAssociationUtil.cc:2594
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPPathVariables * inet::sctp::SCTPAssociation::getNextPath ( const SCTPPathVariables oldPath) const
protected

Referenced by getNextDestination(), process_TIMEOUT_HEARTBEAT(), process_TIMEOUT_RTX(), and updateCounters().

2595 {
2596  int32 hit = 0;
2597  if (sctpPathMap.size() > 1) {
2598  for (const auto & elem : sctpPathMap) {
2599  SCTPPathVariables *newPath = elem.second;
2600  if (newPath == oldPath) {
2601  if (++hit == 1) {
2602  continue;
2603  }
2604  else {
2605  break;
2606  }
2607  }
2608  if ((newPath->activePath) &&
2609  ((state->allowCMT == false) || (newPath->blockingTimeout <= 0.0) ||
2610  (simTime() > newPath->blockingTimeout))) {
2611  return newPath;
2612  }
2613  }
2614  }
2615  return nullptr;
2616 }
bool allowCMT
Definition: SCTPAssociation.h:705
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
int32_t int32
Definition: Compat.h:31
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPDataVariables * inet::sctp::SCTPAssociation::getOutboundDataChunk ( const SCTPPathVariables path,
const int32  availableSpace,
const int32  availableCwnd 
)
protected

Referenced by sendOnPath().

2226 {
2227  /* are there chunks in the transmission queue ? If Yes -> dequeue and return it */
2228  EV_INFO << "getOutboundDataChunk(" << path->remoteAddress << "):"
2229  << " availableSpace=" << availableSpace
2230  << " availableCwnd=" << availableCwnd
2231  << endl;
2232  if (!transmissionQ->payloadQueue.empty()) {
2233  for (auto it = transmissionQ->payloadQueue.begin();
2234  it != transmissionQ->payloadQueue.end(); it++)
2235  {
2236  SCTPDataVariables *chunk = it->second;
2237  if ((chunkHasBeenAcked(chunk) == false) && !chunk->hasBeenAbandoned &&
2238  (chunk->getNextDestinationPath() == path))
2239  {
2240  const int32 len = ADD_PADDING(chunk->len / 8 + SCTP_DATA_CHUNK_LENGTH);
2241  EV_DETAIL << "getOutboundDataChunk() found chunk " << chunk->tsn
2242  << " in the transmission queue, length=" << len << endl;
2243  if ((len <= availableSpace) &&
2244  ((int32)chunk->booksize <= availableCwnd))
2245  {
2246  // T.D. 05.01.2010: The bookkeeping counters may only be decreased when
2247  // this chunk is actually dequeued. Therefore, the check
2248  // for "chunkHasBeenAcked==false" has been moved into the
2249  // "if" statement above!
2250  transmissionQ->payloadQueue.erase(it);
2251  chunk->enqueuedInTransmissionQ = false;
2252  auto i = qCounter.roomTransQ.find(path->remoteAddress);
2253  i->second -= ADD_PADDING(chunk->len / 8 + SCTP_DATA_CHUNK_LENGTH);
2254  auto ib = qCounter.bookedTransQ.find(path->remoteAddress);
2255  ib->second -= chunk->booksize;
2256  return chunk;
2257  }
2258  }
2259  }
2260  }
2261  EV_INFO << "no chunk found in transmissionQ\n";
2262  return nullptr;
2263 }
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
uint16_t len
Definition: TCP_NSC.cc:85
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
QueueCounter qCounter
Definition: SCTPAssociation.h:965
int32_t int32
Definition: Compat.h:31
bool chunkHasBeenAcked(const SCTPDataVariables *chunk) const
Definition: SCTPAssociation.h:1448
int32 inet::sctp::SCTPAssociation::getOutstandingBytes ( ) const
protected

Referenced by process_CLOSE(), process_RCV_Message(), processPacketDropArrived(), processSackArrived(), and sendShutdownAck().

2722 {
2723  int32 osb = 0;
2724  for (const auto & elem : sctpPathMap) {
2725  osb += elem.second->outstandingBytes;
2726  }
2727  return osb;
2728 }
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
int32_t int32
Definition: Compat.h:31
SCTPQueue* inet::sctp::SCTPAssociation::getRetransmissionQueue ( ) const
inline

Referenced by inet::sctp::SCTP::removeAssociation(), and inet::sctp::SCTPAlgorithm::setAssociation().

1020 { return retransmissionQ; };
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
cMessage* inet::sctp::SCTPAssociation::getSackTimer ( ) const
inline
1026 { return SackTimer; };
cMessage * SackTimer
Definition: SCTPAssociation.h:922
SCTPAlgorithm* inet::sctp::SCTPAssociation::getSctpAlgorithm ( ) const
inline
1021 { return sctpAlgorithm; };
SCTPAlgorithm * sctpAlgorithm
Definition: SCTPAssociation.h:970
SCTP* inet::sctp::SCTPAssociation::getSctpMain ( ) const
inline

Referenced by inet::sctp::SCTPPathVariables::SCTPPathVariables().

1022 { return sctpMain; };
SCTP * sctpMain
Definition: SCTPAssociation.h:962
cMessage* inet::sctp::SCTPAssociation::getShutdownTimer ( ) const
inline
1025 { return T2_ShutdownTimer; };
cMessage * T2_ShutdownTimer
Definition: SCTPAssociation.h:920
std::vector< SCTPPathVariables * > inet::sctp::SCTPAssociation::getSortedPathMap ( )
private

Referenced by sendOnAllPaths().

129 {
130  std::vector<SCTPPathVariables *> sortedPaths;
131  for (auto & elem : sctpPathMap) {
132  SCTPPathVariables *path = elem.second;
133  sortedPaths.insert(sortedPaths.end(), path);
134  }
135  if (state->cmtSendAllComparisonFunction != nullptr) {
136  std::stable_sort(sortedPaths.begin(), sortedPaths.end(), state->cmtSendAllComparisonFunction);
137  }
138 
139  EV << "SORTED PATH MAP:" << endl;
140  for (auto path : sortedPaths) {
141  EV << " - " << path->remoteAddress
142  << " cwnd=" << path->cwnd
143  << " ssthresh=" << path->ssthresh
144  << " outstanding=" << path->outstandingBytes
145  << " bytesToRetransmit=" << state->bytesToRetransmit << endl;
146  }
147  return sortedPaths;
148 }
uint32 bytesToRetransmit
Definition: SCTPAssociation.h:632
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
bool(* cmtSendAllComparisonFunction)(const SCTPPathVariables *left, const SCTPPathVariables *right)
Definition: SCTPAssociation.h:706
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
uint32 inet::sctp::SCTPAssociation::getSsnOfStream ( uint16  id)
protected

Referenced by processIncomingResetRequestArrived().

870 {
871  auto iterator = sendStreams.find(id);
872  return (iterator->second->getNextStreamSeqNum());
873 }
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
SCTPStateVariables* inet::sctp::SCTPAssociation::getState ( ) const
inline

Referenced by inet::sctp::SCTP::removeAssociation().

1018 { return state; };
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPQueue* inet::sctp::SCTPAssociation::getTransmissionQueue ( ) const
inline

Referenced by inet::sctp::SCTP::removeAssociation(), and inet::sctp::SCTPAlgorithm::setAssociation().

1019 { return transmissionQ; };
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
void inet::sctp::SCTPAssociation::handleChunkReportedAsAcked ( uint32 highestNewAck,
simtime_t &  rttEstimation,
SCTPDataVariables myChunk,
SCTPPathVariables sackPath,
const bool  sackIsNonRevokable 
)
private

Referenced by processSackArrived().

1616 {
1617  SCTPPathVariables *myChunkLastPath = myChunk->getLastDestinationPath();
1618  // SFR algorithm
1619  if (state->allowCMT == true) {
1620  EV << "TSN " << myChunk->tsn << " on path " << myChunkLastPath->remoteAddress << ":\t"
1621  << "findPseudoCumAck=" << ((myChunkLastPath->findPseudoCumAck == true) ? "true" : "false") << "\t"
1622  << "pseudoCumAck=" << myChunkLastPath->pseudoCumAck << "\t"
1623  << "newPseudoCumAck=" << ((myChunkLastPath->newPseudoCumAck == true) ? "true" : "false") << "\t"
1624  << "findRTXPseudoCumAck=" << ((myChunkLastPath->findRTXPseudoCumAck == true) ? "true" : "false") << "\t"
1625  << "rtxPseudoCumAck=" << myChunkLastPath->rtxPseudoCumAck << "\t"
1626  << "newRTXPseudoCumAck=" << ((myChunkLastPath->newRTXPseudoCumAck == true) ? "true" : "false") << "\t"
1627  << endl;
1628 
1629  // This chunk has not been acked before -> new ack on its myChunkLastPath.
1630  if (myChunkLastPath->sawNewAck == false) {
1631  EV << "TSN " << myChunk->tsn << " on path " << myChunkLastPath->remoteAddress << ":\t"
1632  << "Saw new ack -> setting highestNewAckInSack!" << endl;
1633  myChunkLastPath->sawNewAck = true;
1634  }
1635 
1636  // Smart Fast RTX
1637  // If chunk has already been transmitted on another path, do not consider it
1638  // for fast RTX handling!
1639  if ((!myChunk->hasBeenTimerBasedRtxed) ||
1640  (state->cmtSmartFastRTX == false))
1641  {
1642  if (myChunkLastPath->lowestNewAckInSack == 0) {
1643  myChunkLastPath->lowestNewAckInSack = myChunk->tsn; // The lowest TSN acked
1644  }
1645  if (myChunkLastPath->highestNewAckInSack == 0) {
1646  myChunkLastPath->highestNewAckInSack = myChunk->tsn; // The highest TSN acked so far
1647  }
1648  else if (tsnLt(myChunkLastPath->highestNewAckInSack, myChunk->tsn)) {
1649  myChunkLastPath->highestNewAckInSack = myChunk->tsn; // The highest TSN acked so far
1650  }
1651  }
1652  }
1653  if ((myChunk->numberOfTransmissions == 1) &&
1654  (myChunk->hasBeenMoved == false) &&
1655  (myChunk->hasBeenReneged == false))
1656  {
1657  if (myChunkLastPath == sackPath) {
1658  const simtime_t timeDifference = simTime() - myChunk->sendTime;
1659  if ((timeDifference < rttEstimation) || (rttEstimation == -1.0)) {
1660  rttEstimation = timeDifference;
1661  }
1662  EV_DETAIL << simTime() << " processSackArrived: computed rtt time diff == "
1663  << timeDifference << " for TSN " << myChunk->tsn << endl;
1664  }
1665  else {
1666  if ((state->allowCMT == true) &&
1667  (state->cmtSlowPathRTTUpdate == true) &&
1668  (myChunkLastPath->waitingForRTTCalculaton == false))
1669  {
1670  // numberOfTransmissions==1, hasBeenReneged==false
1671  // T.D. 25.02.2010: Slow Path Update
1672  // Remember this chunk's TSN and send time in order to update the
1673  // path's RTT using a stale SACK on its own path.
1674  myChunkLastPath->tsnForRTTCalculation = myChunk->tsn;
1675  myChunkLastPath->txTimeForRTTCalculation = myChunk->sendTime;
1676  myChunkLastPath->waitingForRTTCalculaton = true;
1677  }
1678  }
1679  }
1680  if ((myChunk->hasBeenAbandoned == false) &&
1681  (myChunk->hasBeenReneged == false) &&
1682  (myChunk->hasBeenAcked == false))
1683  {
1684  EV_DETAIL << simTime() << ": GapAcked TSN " << myChunk->tsn
1685  << " on path " << myChunkLastPath->remoteAddress << endl;
1686 
1687  if (myChunk->tsn > highestNewAck) {
1688  highestNewAck = myChunk->tsn;
1689  }
1690 
1691  if (sackIsNonRevokable == true) {
1692  myChunkLastPath->gapAckedChunksInLastSACK++;
1693  myChunkLastPath->gapNRAckedChunksInLastSACK++;
1694  }
1695  else {
1696  myChunkLastPath->gapAckedChunksInLastSACK++;
1697  }
1698  }
1699 
1700  // ====== Non-Renegable SACK =============================================
1701  if (sackIsNonRevokable == true) {
1702  // NOTE: nonRenegablyAckChunk() will only work with ChunkMap,
1703  // since the actual chunk object will be gone ...
1704  nonRenegablyAckChunk(myChunk, sackPath, rttEstimation,
1706  }
1707  // ====== Renegable SACK =================================================
1708  else {
1709  renegablyAckChunk(myChunk, sackPath);
1710  }
1711 }
void renegablyAckChunk(SCTPDataVariables *chunk, SCTPPathVariables *sackPath)
Definition: SCTPAssociationRcvMessage.cc:1979
bool allowCMT
Definition: SCTPAssociation.h:705
static int32 tsnLt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1083
bool cmtSlowPathRTTUpdate
Definition: SCTPAssociation.h:738
SCTP * sctpMain
Definition: SCTPAssociation.h:962
bool cmtSmartFastRTX
Definition: SCTPAssociation.h:736
void nonRenegablyAckChunk(SCTPDataVariables *chunk, SCTPPathVariables *sackPath, simtime_t &rttEstimation, SCTP::AssocStat *assocStat)
Definition: SCTPAssociationRcvMessage.cc:1877
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
int32 assocId
Definition: SCTPAssociation.h:908
AssocStat * getAssocStat(uint32 assocId)
Definition: SCTP.h:225
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::handleChunkReportedAsMissing ( const SCTPSackChunk sackChunk,
const uint32  highestNewAck,
SCTPDataVariables myChunk,
SCTPPathVariables sackPath 
)
private

Referenced by processSackArrived().

1717 {
1718  SCTPPathVariables *myChunkLastPath = myChunk->getLastDestinationPath();
1719  EV_INFO << "TSN " << myChunk->tsn << " is missing in gap reports (last "
1720  << myChunkLastPath->remoteAddress << ") ";
1721  if (!chunkHasBeenAcked(myChunk)) {
1722  EV_DETAIL << "has not been acked, highestNewAck=" << highestNewAck
1723  << " countsAsOutstanding=" << myChunk->countsAsOutstanding << endl;
1724 
1725  // ===== Check whether a Fast Retransmission is necessary =============
1726  // Non-CMT behaviour: check for highest TSN
1727  uint32 chunkReportedAsMissing = (highestNewAck > myChunk->tsn) ? 1 : 0;
1728 
1729  // Split Fast Retransmission (SFR) algorithm for CMT
1730  if ((state->allowCMT == true) && (state->cmtUseSFR == true)) {
1731  chunkReportedAsMissing = 0; // Default: do not assume chunk as missing.
1732 
1733  // If there has been another chunk with highest TSN acked on this path,
1734  // the current one is missing.
1735  if ((myChunkLastPath->sawNewAck) &&
1736  (tsnGt(myChunkLastPath->highestNewAckInSack, myChunk->tsn)))
1737  {
1738  if (state->cmtUseDAC == false) {
1739  chunkReportedAsMissing = 1;
1740  }
1741  else {
1742  // ------ DAC algorithm at sender side -----------
1743  // Is there a newly acked TSN on another path?
1744  bool sawNewAckOnlyOnThisPath = true;
1745  for (auto & elem : sctpPathMap) {
1746  const SCTPPathVariables *otherPath = elem.second;
1747  if ((otherPath != myChunkLastPath) && (otherPath->sawNewAck)) {
1748  sawNewAckOnlyOnThisPath = false;
1749  break;
1750  }
1751  }
1752  if (sawNewAckOnlyOnThisPath == true) {
1753  // All newly acked TSNs were sent on the same path
1754  EV << "SplitFastRTX + DAC: all on same path: "
1755  << "TSN=" << myChunk->tsn
1756  << " lowestNewAckInSack=" << myChunkLastPath->lowestNewAckInSack
1757  << " highestNewAckInSack=" << myChunkLastPath->highestNewAckInSack
1758  << " (on path " << myChunkLastPath->remoteAddress << ")" << endl;
1759  // Are there newly acked TSNs ta, tb, so that ta < myChunk->tsn < tb?
1760  // myChunkLastPath->highestNewAckInSack is highest newly acked TSN on the current path
1761  // -> since all TSNs were on this path, this value can be used as tb
1762  // lowestNewAckInSack is the lowest newly acked TSN of this SACK
1763  // -> since all TSNs were on the same path, this value can be used as ta
1764  if (tsnLt(myChunkLastPath->lowestNewAckInSack, myChunk->tsn) &&
1765  tsnLt(myChunk->tsn, myChunkLastPath->highestNewAckInSack))
1766  {
1767  EV << " => conservative increment of 1" << endl;
1768  chunkReportedAsMissing = 1;
1769  }
1770  else if (tsnGt(myChunkLastPath->lowestNewAckInSack, myChunk->tsn)) { // All newly acked TSNs are larger than myChunk->tsn
1771  EV << " => reported increment of dacPacketsRcvd=" << (unsigned int)sackChunk->getDacPacketsRcvd() << endl;
1772  chunkReportedAsMissing = sackChunk->getDacPacketsRcvd();
1773  }
1774  }
1775  else {
1776  // Mixed SACKS: newly acked TSNs were sent to multiple paths
1777  EV << "SplitFastRTX + DAC: mixed acks, increment is 1" << endl;
1778  chunkReportedAsMissing = 1;
1779  }
1780  }
1781  } // else: There is no need to increment the missing count.
1782 
1783  EV << "SplitFastRTX: chunkReportedAsMissing="
1784  << chunkReportedAsMissing << ", "
1785  << "sawNewAck=" << myChunkLastPath->sawNewAck << ", "
1786  << "lowestNewAckInSack=" << myChunkLastPath->lowestNewAckInSack
1787  << "highestNewAckInSack=" << myChunkLastPath->highestNewAckInSack << ", "
1788  << "TSN=" << myChunk->tsn << endl;
1789  }
1790  if (chunkReportedAsMissing > 0) {
1791  myChunk->gapReports += chunkReportedAsMissing;
1792  myChunkLastPath->gapUnackedChunksInLastSACK++;
1793 
1794  if (myChunk->gapReports >= state->numGapReports) {
1795  bool fastRtx = false;
1796  switch (state->rtxMethod) {
1797  case 0: // Only one Fast RTX after 3 Gap reports
1798  fastRtx = ((myChunk->hasBeenFastRetransmitted == false) &&
1799  ((myChunk->numberOfRetransmissions == 0) ||
1800  ((myChunk->hasBeenMoved) &&
1801  (myChunk->countsAsOutstanding) &&
1802  (state->movedChunkFastRTXFactor > 0) &&
1803  ((simTime() - myChunk->sendTime) > state->movedChunkFastRTXFactor * myChunkLastPath->srtt))
1804  ));
1805  break;
1806 
1807  case 1: // Just 1 Fast RTX per RTT
1808  fastRtx = ((myChunk->hasBeenFastRetransmitted == false) &&
1809  (myChunk->numberOfRetransmissions == 0 ||
1810  (simTime() - myChunk->sendTime) > myChunkLastPath->srtt));
1811  break;
1812 
1813  case 2: // Switch off Fast RTX
1814  fastRtx = false;
1815  break;
1816 
1817  case 3: // Always Fast RTX
1818  fastRtx = true;
1819  break;
1820  }
1821  if (fastRtx) {
1822  if (myChunk->hasBeenMoved) {
1823  EV << simTime() << ": MovedFastRTX for TSN " << myChunk->tsn << endl;
1824  }
1825  myChunk->hasBeenMoved = false; // Just trigger *one* fast RTX ...
1826  // ====== Add chunk to transmission queue ========
1827  if (transmissionQ->getChunk(myChunk->tsn) == nullptr) {
1828  if (!chunkMustBeAbandoned(myChunk, sackPath)) {
1829  SCTP::AssocStat *assocStat = sctpMain->getAssocStat(assocId);
1830  if (assocStat) {
1831  assocStat->numFastRtx++;
1832  }
1833  }
1834  myChunk->hasBeenFastRetransmitted = true;
1835  myChunk->sendForwardIfAbandoned = true;
1836 
1837  EV_DETAIL << simTime() << ": Fast RTX for TSN "
1838  << myChunk->tsn << " on path " << myChunk->getLastDestination() << endl;
1839  myChunkLastPath->numberOfFastRetransmissions++;
1840 
1841  myChunk->setNextDestination(getNextDestination(myChunk));
1842  SCTPPathVariables *myChunkNextPath = myChunk->getNextDestinationPath();
1843  assert(myChunkNextPath != nullptr);
1844 
1845  if (myChunk->countsAsOutstanding) {
1846  decreaseOutstandingBytes(myChunk);
1847  }
1848  if (!transmissionQ->checkAndInsertChunk(myChunk->tsn, myChunk)) {
1849  EV_DETAIL << "Fast RTX: cannot add message/chunk (TSN="
1850  << myChunk->tsn << ") to the transmissionQ" << endl;
1851  }
1852  else {
1853  myChunk->enqueuedInTransmissionQ = true;
1854  auto q = qCounter.roomTransQ.find(myChunk->getNextDestination());
1855  q->second += ADD_PADDING(myChunk->len / 8 + SCTP_DATA_CHUNK_LENGTH);
1856  auto qb = qCounter.bookedTransQ.find(myChunk->getNextDestination());
1857  qb->second += myChunk->booksize;
1858  }
1859  myChunkNextPath->requiresRtx = true;
1860  if (myChunkNextPath->findLowestTSN == true) {
1861  // TD 08.12.09: fixed detection of lowest TSN retransmitted
1862  myChunkNextPath->lowestTSNRetransmitted = true;
1863  }
1864  }
1865  }
1866  }
1867  }
1868  myChunkLastPath->findLowestTSN = false;
1869  }
1870  else {
1871  // Reneging, type 1:
1872  // A chunk in the gap blocks has been un-acked => reneg it.
1873  tsnWasReneged(myChunk, sackPath, 1);
1874  }
1875 }
void tsnWasReneged(SCTPDataVariables *chunk, const SCTPPathVariables *sackPath, const int type)
Definition: SCTPAssociationRcvMessage.cc:938
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
SCTPPathVariables * getNextDestination(SCTPDataVariables *chunk) const
Definition: SCTPAssociationUtil.cc:2618
void decreaseOutstandingBytes(SCTPDataVariables *chunk)
Definition: SCTPAssociationRcvMessage.cc:41
bool allowCMT
Definition: SCTPAssociation.h:705
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
static int32 tsnLt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1083
bool cmtUseDAC
Definition: SCTPAssociation.h:740
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
SCTP * sctpMain
Definition: SCTPAssociation.h:962
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
bool cmtUseSFR
Definition: SCTPAssociation.h:739
uint32 numGapReports
Definition: SCTPAssociation.h:603
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
SCTPDataVariables * getChunk(const uint32 key) const
Definition: SCTPQueue.cc:123
QueueCounter qCounter
Definition: SCTPAssociation.h:965
bool checkAndInsertChunk(const uint32 key, SCTPDataVariables *chunk)
Definition: SCTPQueue.cc:50
uint32 rtxMethod
Definition: SCTPAssociation.h:690
double movedChunkFastRTXFactor
Definition: SCTPAssociation.h:743
uint32_t uint32
Definition: Compat.h:30
static int32 tsnGt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1081
bool chunkMustBeAbandoned(SCTPDataVariables *chunk, SCTPPathVariables *sackPath)
Definition: SCTPAssociationUtil.cc:2265
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
int32 assocId
Definition: SCTPAssociation.h:908
AssocStat * getAssocStat(uint32 assocId)
Definition: SCTP.h:225
uint32 numFastRtx
Definition: SCTP.h:141
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool chunkHasBeenAcked(const SCTPDataVariables *chunk) const
Definition: SCTPAssociation.h:1448
void inet::sctp::SCTPAssociation::increaseOutstandingBytes ( SCTPDataVariables chunk,
SCTPPathVariables path 
)
private

Referenced by loadPacket(), and sendOnPath().

33 {
34  path->outstandingBytes += chunk->booksize;
35  path->statisticsPathOutstandingBytes->record(path->outstandingBytes);
36  state->outstandingBytes += chunk->booksize;
37  SCTPSendStream *stream = nullptr;
38  auto associter = sendStreams.find(chunk->sid);
39  if (associter != sendStreams.end()) {
40  stream = associter->second;
41  } else {
42  throw cRuntimeError("Stream with id %d not found", chunk->sid);
43  }
44  stream->setBytesInFlight(stream->getBytesInFlight() + chunk->booksize);
46 
47  auto iterator = qCounter.roomRetransQ.find(path->remoteAddress);
49  if (state->osbWithHeader)
50  iterator->second += ADD_PADDING(chunk->booksize);
51  else
52  iterator->second += ADD_PADDING(chunk->booksize + SCTP_DATA_CHUNK_LENGTH);
53 }
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
CounterMap roomRetransQ
Definition: SCTPAssociation.h:880
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
bool osbWithHeader
Definition: SCTPAssociation.h:832
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
uint64 outstandingBytes
Definition: SCTPAssociation.h:622
QueueCounter qCounter
Definition: SCTPAssociation.h:965
uint32 outstandingMessages
Definition: SCTPAssociation.h:843
cOutVector * statisticsOutstandingBytes
Definition: SCTPAssociation.h:973
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
const char * inet::sctp::SCTPAssociation::indicationName ( const int32  code)
static

Utility: returns name of SCTP_I_xxx constants.

Referenced by generateSendQueueAbatedIndication(), inet::SCTPNatServer::handleMessage(), inet::SCTPNatPeer::handleMessage(), sendEstabIndicationToApp(), and sendIndicationToApp().

207 {
208 #define CASE(x) case x: \
209  s = #x + 7; break
210  const char *s = "unknown";
211  switch (code) {
212  CASE(SCTP_I_DATA);
231  }
232  return s;
233 #undef CASE
234 }
Definition: SCTPCommand.h:76
Definition: SCTPCommand.h:80
#define CASE(x)
Definition: SCTPCommand.h:67
Definition: SCTPCommand.h:81
Definition: SCTPCommand.h:77
Definition: SCTPCommand.h:79
Definition: SCTPCommand.h:68
Definition: SCTPCommand.h:63
Definition: SCTPCommand.h:65
Definition: SCTPCommand.h:69
Definition: SCTPCommand.h:75
Definition: SCTPCommand.h:66
Definition: SCTPCommand.h:64
Definition: SCTPCommand.h:72
Definition: SCTPCommand.h:71
Definition: SCTPCommand.h:70
Definition: SCTPCommand.h:78
value< double, units::s > s
Definition: Units.h:1049
Definition: SCTPCommand.h:74
Definition: SCTPCommand.h:82
void inet::sctp::SCTPAssociation::initAssociation ( SCTPOpenCommand openCmd)
protected

Utility: creates send/receive queues and sctpAlgorithm.

Referenced by process_ASSOCIATE(), and process_OPEN_PASSIVE().

463 {
464  EV_INFO << "SCTPAssociationUtil:initAssociation\n";
465  // create send/receive queues
466  const char *queueClass = openCmd->getQueueClass();
467  transmissionQ = check_and_cast<SCTPQueue *>(inet::utils::createOne(queueClass));
468 
469  retransmissionQ = check_and_cast<SCTPQueue *>(inet::utils::createOne(queueClass));
470  inboundStreams = openCmd->getInboundStreams();
471  outboundStreams = openCmd->getOutboundStreams();
472  // create algorithm
473  const char *sctpAlgorithmClass = openCmd->getSctpAlgorithmClass();
474  if (!sctpAlgorithmClass || !sctpAlgorithmClass[0])
475  sctpAlgorithmClass = sctpMain->par("sctpAlgorithmClass");
476  sctpAlgorithm = check_and_cast<SCTPAlgorithm *>(inet::utils::createOne(sctpAlgorithmClass));
479  // create state block
481 
482  if ((bool)sctpMain->par("auth")) {
483  const char *chunks = sctpMain->par("chunks").stringValue();
484  bool asc = false;
485  bool asca = false;
486  char *chunkscopy = (char *)malloc(strlen(chunks) + 1);
487  strcpy(chunkscopy, chunks);
488  char *token;
489  token = strtok((char *)chunkscopy, ",");
490  while (token != nullptr) {
491  if (chunkToInt(token) == ASCONF)
492  asc = true;
493  if (chunkToInt(token) == ASCONF_ACK)
494  asca = true;
495  this->state->chunkList.push_back(chunkToInt(token));
496  token = strtok(nullptr, ",");
497  }
498  if ((bool)sctpMain->par("addIP")) {
499  if (!asc)
500  state->chunkList.push_back(ASCONF);
501  if (!asca)
502  state->chunkList.push_back(ASCONF_ACK);
503  }
504  free(chunkscopy);
505  }
506 }
void setAssociation(SCTPAssociation *_assoc)
Definition: SCTPAlgorithm.h:54
Definition: SCTPAssociation.h:130
uint32 outboundStreams
Definition: SCTPAssociation.h:943
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
uint32 inboundStreams
Definition: SCTPAssociation.h:942
virtual SCTPStateVariables * createStateVariables()=0
virtual void initialize()
Definition: SCTPAlgorithm.h:61
void * malloc(YYSIZE_T)
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
cObject * createOne(const char *className, const char *defaultNamespace)
Like cObjectFactory::createOne(), except it starts searching for the class in the given namespace...
Definition: INETUtils.cc:105
SCTP * sctpMain
Definition: SCTPAssociation.h:962
std::vector< uint16 > chunkList
Definition: SCTPAssociation.h:823
SCTPAlgorithm * sctpAlgorithm
Definition: SCTPAssociation.h:970
void free(void *)
Definition: SCTPAssociation.h:126
static uint16 chunkToInt(const char *type)
Definition: SCTPAssociationUtil.cc:236
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::initCCParameters ( SCTPPathVariables path)
protected

SCTPCCFunctions.

Referenced by pmStartPathManagement(), and stateEntered().

400 {
401  path->cwnd = getInitialCwnd(path);
402  path->ssthresh = state->peerRwnd;
403  recordCwndUpdate(path);
404 
405  EV_DEBUG << simTime() << ":\tCC [initCCParameters]\t" << path->remoteAddress
406  << " (cmtCCGroup=" << path->cmtCCGroup << ")"
407  << "\tsst=" << path->ssthresh << " cwnd=" << path->cwnd << endl;
408  assocBestPaths.clear();
409  assocMaxWndPaths.clear();
410 }
void recordCwndUpdate(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:355
uint64 peerRwnd
Definition: SCTPAssociation.h:610
SCTPPathCollection assocMaxWndPaths
Definition: SCTPAssociation.h:902
uint32 getInitialCwnd(const SCTPPathVariables *path) const
Definition: SCTPCCFunctions.cc:379
SCTPPathCollection assocBestPaths
Definition: SCTPAssociation.h:901
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::initStreams ( uint32  inStreams,
uint32  outStreams 
)
protected

Referenced by SCTPAssociation().

45 {
46  uint32 i;
47 
48  EV_INFO << "initStreams instreams=" << inStreams << " outstream=" << outStreams << "\n";
49  if (receiveStreams.size() == 0 && sendStreams.size() == 0) {
50  for (i = 0; i < inStreams; i++) {
51  SCTPReceiveStream *rcvStream = new SCTPReceiveStream(this);
52 
53  this->receiveStreams[i] = rcvStream;
54  rcvStream->setStreamId(i);
55  this->state->numMsgsReq[i] = 0;
56  }
57  for (i = 0; i < outStreams; i++) {
58  SCTPSendStream *sendStream = new SCTPSendStream(this, i);
59  sendStream->setStreamId(i);
60  this->sendStreams[i] = sendStream;
61  }
62  }
63 }
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
std::vector< int32 > numMsgsReq
Definition: SCTPAssociation.h:646
uint32_t uint32
Definition: Compat.h:30
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::listOrderedQ ( )
protected
70 {
71  for (auto & elem : receiveStreams) {
72  EV_DEBUG << "stream " << elem.second->getStreamId() << ":\n";
73  elem.second->getOrderedQ()->printQueue();
74  EV_DEBUG << "\n";
75  }
76 }
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
void inet::sctp::SCTPAssociation::loadPacket ( SCTPPathVariables pathVar,
SCTPMessage **  sctpMsg,
uint16 chunksAdded,
uint16 dataChunksAdded,
bool *  authAdded 
)
private

Referenced by sendOnPath().

97 {
98  *sctpMsg = state->sctpMsg;
99  state->sctpMsg = nullptr;
100  *chunksAdded = state->chunksAdded;
101  *dataChunksAdded = state->dataChunksAdded;
102  *authAdded = state->authAdded;
103  EV_INFO << "loadPacket: path=" << pathVar->remoteAddress << " osb=" << pathVar->outstandingBytes << " -> " << pathVar->outstandingBytes + state->packetBytes << endl;
104  if (state->osbWithHeader) {
106  }
107  else {
109  }
111 
112  for (uint16 i = 0; i < (*sctpMsg)->getChunksArraySize(); i++) {
113  cPacketPtr& chunkPtr = (*sctpMsg)->getChunks(i);
114  SCTPDataChunk* dataChunk = dynamic_cast<SCTPDataChunk*>(chunkPtr);
115  if(dataChunk != nullptr) {
116  const uint32_t tsn = dataChunk->getTsn();
117  SCTPDataVariables* chunk = retransmissionQ->payloadQueue.find(tsn)->second;
118  assert(chunk != nullptr);
119  chunk->queuedOnPath = pathVar;
120  chunk->queuedOnPath->queuedBytes += chunk->booksize;
121  chunk->setLastDestination(pathVar);
122  increaseOutstandingBytes(chunk, pathVar);
123  chunk->countsAsOutstanding = true;
124  }
125  }
126 }
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
void increaseOutstandingBytes(SCTPDataVariables *chunk, SCTPPathVariables *path)
Definition: SCTPAssociationSendAll.cc:31
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
cPacket * cPacketPtr
Definition: SCTPMessage_m.h:39
uint16 chunksAdded
Definition: SCTPAssociation.h:669
bool osbWithHeader
Definition: SCTPAssociation.h:832
SCTPMessage * sctpMsg
Definition: SCTPAssociation.h:668
uint64 bookedSumSendStreams
Definition: SCTPAssociation.h:876
QueueCounter qCounter
Definition: SCTPAssociation.h:965
bool authAdded
Definition: SCTPAssociation.h:674
uint16_t uint16
Definition: Compat.h:32
uint32 packetBytes
Definition: SCTPAssociation.h:671
uint16 dataChunksAdded
Definition: SCTPAssociation.h:670
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPParameter * inet::sctp::SCTPAssociation::makeAddStreamsRequestParameter ( uint32  srsn,
SCTPResetInfo info 
)
protected

Referenced by sendStreamResetRequest().

352 {
353  SCTPAddStreamsRequestParameter *addStreams = new SCTPAddStreamsRequestParameter("Add_Streams");
354  if (info->getInstreams() > 0) {
355  addStreams->setParameterType(ADD_INCOMING_STREAMS_REQUEST_PARAMETER);
356  addStreams->setNumberOfStreams(info->getInstreams());
359  state->numAddedInStreams = addStreams->getNumberOfStreams();
360  } else if (info->getOutstreams() > 0) {
361  addStreams->setParameterType(ADD_OUTGOING_STREAMS_REQUEST_PARAMETER);
362  addStreams->setNumberOfStreams(info->getOutstreams());
365  state->numAddedOutStreams = addStreams->getNumberOfStreams();
366  }
367  addStreams->setSrReqSn(srsn);
368  addStreams->setByteLength(SCTP_ADD_STREAMS_REQUEST_PARAMETER_LENGTH);
369  return addStreams;
370 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
#define SCTP_ADD_STREAMS_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:229
Definition: SCTPAssociation.h:155
uint16 localRequestType
Definition: SCTPAssociation.h:810
uint16 numAddedOutStreams
Definition: SCTPAssociation.h:672
uint16 numAddedInStreams
Definition: SCTPAssociation.h:673
Definition: SCTPAssociation.h:154
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPDataVariables * inet::sctp::SCTPAssociation::makeDataVarFromDataMsg ( SCTPDataMsg datMsg,
SCTPPathVariables path 
)
private

Referenced by sendOnPath().

185 {
186  SCTPDataVariables *datVar = new SCTPDataVariables();
187 
188  datMsg->setInitialDestination(path->remoteAddress);
189  datVar->setInitialDestination(path);
190 
191  datVar->bbit = datMsg->getBBit();
192  datVar->ebit = datMsg->getEBit();
193  datVar->ibit = datMsg->getSackNow();
194  datVar->enqueuingTime = datMsg->getEnqueuingTime();
195  datVar->expiryTime = datMsg->getExpiryTime();
196  datVar->ppid = datMsg->getPpid();
197  datVar->len = datMsg->getBitLength();
198  datVar->sid = datMsg->getSid();
199  datVar->allowedNoRetransmissions = datMsg->getRtx();
200  datVar->booksize = datMsg->getBooksize();
201  datVar->prMethod = datMsg->getPrMethod();
202  datVar->priority = datMsg->getPriority();
203  datVar->strReset = datMsg->getStrReset();
204 
205  // ------ Stream handling ---------------------------------------
206  auto iterator = sendStreams.find(datMsg->getSid());
207  SCTPSendStream *stream = iterator->second;
208  uint32 nextSSN = stream->getNextStreamSeqNum();
209  datVar->userData = datMsg->decapsulate();
210  if (datMsg->getOrdered()) {
211  // ------ Ordered mode: assign SSN ---------
212  if (datMsg->getEBit()) {
213  datVar->ssn = nextSSN++;
214  }
215  else {
216  datVar->ssn = nextSSN;
217  }
218 
219  datVar->ordered = true;
220  if (nextSSN > 65535) {
221  stream->setNextStreamSeqNum(0);
222  }
223  else {
224  stream->setNextStreamSeqNum(nextSSN);
225  }
226  }
227  else {
228  // ------ Ordered mode: no SSN needed ------
229  datVar->ssn = 0;
230  datVar->ordered = false;
231  }
232 
234  return datVar;
235 }
bool ssLastDataChunkSizeSet
Definition: SCTPAssociation.h:854
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
uint32_t uint32
Definition: Compat.h:30
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPParameter * inet::sctp::SCTPAssociation::makeIncomingStreamResetParameter ( uint32  srsn,
SCTPResetInfo info 
)
protected

Referenced by sendStreamResetRequest().

333 {
334  SCTPIncomingSSNResetRequestParameter *inResetParam;
335  inResetParam = new SCTPIncomingSSNResetRequestParameter("Incoming_Request_Param");
336  inResetParam->setParameterType(INCOMING_RESET_REQUEST_PARAMETER);
337  inResetParam->setSrReqSn(srsn);
338  if (info->getStreamsArraySize() > 0) {
339  inResetParam->setStreamNumbersArraySize(info->getStreamsArraySize());
340  for (uint i = 0; i < info->getStreamsArraySize(); i++) {
341  inResetParam->setStreamNumbers(i, info->getStreams(i));
342  state->requests[srsn].streams.push_back(inResetParam->getStreamNumbers(i));
343  state->resetInStreams.push_back(inResetParam->getStreamNumbers(i));
344  }
345  }
347  inResetParam->setByteLength(SCTP_INCOMING_RESET_REQUEST_PARAMETER_LENGTH + (info->getStreamsArraySize() * 2));
348  return inResetParam;
349 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
#define SCTP_INCOMING_RESET_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:226
unsigned int uint
Definition: INETDefs.h:63
uint16 localRequestType
Definition: SCTPAssociation.h:810
Definition: SCTPAssociation.h:151
Definition: SCTPAssociation.h:157
std::list< uint16 > resetInStreams
Definition: SCTPAssociation.h:802
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPParameter * inet::sctp::SCTPAssociation::makeOutgoingStreamResetParameter ( uint32  srsn,
SCTPResetInfo info 
)
protected

Referenced by sendStreamResetRequest().

299 {
300  SCTPOutgoingSSNResetRequestParameter *outResetParam;
301  outResetParam = new SCTPOutgoingSSNResetRequestParameter("Outgoing_Request_Param");
302  outResetParam->setParameterType(OUTGOING_RESET_REQUEST_PARAMETER);
303  outResetParam->setSrReqSn(srsn);
304  outResetParam->setSrResSn(state->expectedStreamResetSequenceNumber - 1);
305  outResetParam->setLastTsn(state->nextTSN - 1);
306  state->requests[srsn].lastTsn = outResetParam->getLastTsn();
307  if (state->outstandingBytes == 0 && state->streamsToReset.size() == 0) {
308  if (info->getStreamsArraySize() > 0) {
309  outResetParam->setStreamNumbersArraySize(info->getStreamsArraySize());
310  for (uint i = 0; i < info->getStreamsArraySize(); i++) {
311  outResetParam->setStreamNumbers(i, (uint16)info->getStreams(i));
312  state->resetOutStreams.push_back(outResetParam->getStreamNumbers(i));
313  state->requests[srsn].streams.push_back(outResetParam->getStreamNumbers(i));
314  }
315  }
316  } else if (state->streamsToReset.size() > 0) {
317  outResetParam->setStreamNumbersArraySize(state->streamsToReset.size());
318  uint16 i = 0;
319  for (std::list<uint16>::iterator it = state->streamsToReset.begin(); it != state->streamsToReset.end(); ++it) {
320  outResetParam->setStreamNumbers(i, *it);
321  state->resetOutStreams.push_back(outResetParam->getStreamNumbers(i));
322  state->requests[srsn].streams.push_back(outResetParam->getStreamNumbers(i));
323  i++;
324  }
325  state->streamsToReset.clear();
326  }
328  outResetParam->setByteLength(SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH + (outResetParam->getStreamNumbersArraySize() * 2));
329  return outResetParam;
330 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
unsigned int uint
Definition: INETDefs.h:63
uint16 localRequestType
Definition: SCTPAssociation.h:810
uint32 expectedStreamResetSequenceNumber
Definition: SCTPAssociation.h:794
Definition: SCTPAssociation.h:150
Definition: SCTPAssociation.h:156
uint64 outstandingBytes
Definition: SCTPAssociation.h:622
#define SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:225
std::list< uint16 > resetOutStreams
Definition: SCTPAssociation.h:801
std::list< uint16 > streamsToReset
Definition: SCTPAssociation.h:804
uint32 nextTSN
Definition: SCTPAssociation.h:613
uint16_t uint16
Definition: Compat.h:32
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::makeRoomForTsn ( const uint32  tsn,
const uint32  length,
const bool  uBit 
)
protected

Referenced by processDataArrived().

2080 {
2081  EV_INFO << simTime() << ":\tmakeRoomForTsn:"
2082  << " tsn=" << tsn
2083  << " length=" << length
2084  << " highestTSN=" << state->gapList.getHighestTSNReceived() << endl;
2086 
2087  // Reneging may not happen when it is turned off!
2088  assert(state->disableReneging == false);
2089 
2090  // Get the highest TSN of the GapAck blocks.
2092  uint32 sum = 0;
2093  while ((sum < length) &&
2094  (tryTSN > state->gapList.getCumAckTSN()))
2095  {
2096  // ====== New TSN is larger than highest one in GapList? ==============
2097  if (tsnGt(tsn, tryTSN)) {
2098  // There is no space for a TSN that high!
2099  EV_DETAIL << "makeRoomForTsn:"
2100  << " tsn=" << tryTSN
2101  << " tryTSN=" << tryTSN << " -> no space" << endl;
2102  return false;
2103  }
2104 
2105  const uint32 oldSum = sum;
2106  // ====== Iterate all streams to find chunk with TSN "tryTSN" =========
2107  for (auto & elem : receiveStreams) {
2108  SCTPReceiveStream *receiveStream = elem.second;
2109 
2110  // ====== Get chunk to drop ========================================
2111  SCTPQueue *queue;
2112  if (uBit) {
2113  queue = receiveStream->getUnorderedQ(); // Look in unordered queue
2114  } else {
2115  queue = receiveStream->getOrderedQ(); // Look in ordered queue
2116  }
2117  SCTPDataVariables *chunk = queue->getChunk(tryTSN);
2118  if (chunk == nullptr) { // 12.06.08
2119  EV_DETAIL << tryTSN << " not found in orderedQ. Try deliveryQ" << endl;
2120  // Chunk is already in delivery queue.
2121  queue = receiveStream->getDeliveryQ();
2122  chunk = queue->getChunk(tryTSN);
2123  }
2124 
2125  // ====== A chunk has been found -> drop it ========================
2126  if (chunk != nullptr) {
2127  sum += chunk->len;
2128  if (queue->deleteMsg(tryTSN)) {
2129  EV_INFO << tryTSN << " found and deleted" << endl;
2131  state->queuedReceivedBytes -= chunk->len / 8;
2132  if (ssnGt(receiveStream->getExpectedStreamSeqNum(), chunk->ssn)) {
2133  receiveStream->setExpectedStreamSeqNum(chunk->ssn);
2134  }
2135 
2136  auto iter = sctpMain->assocStatMap.find(assocId);
2137  iter->second.numChunksReneged++;
2138  }
2140  state->gapList.removeFromGapList(tryTSN);
2141 
2142  break;
2143  } else {
2144  EV_INFO << "TSN " << tryTSN << " not found in stream "
2145  << receiveStream->getStreamId() << endl;
2146  }
2147  }
2148  if (sum == oldSum) {
2149  EV_INFO << tryTSN << " not found in any stream" << endl;
2150  }
2151  tryTSN--;
2152  }
2153 
2154  return true;
2155 }
uint32 bufferedMessages
Definition: SCTPAssociation.h:842
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
void calculateRcvBuffer()
Definition: SCTPAssociationUtil.cc:49
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
uint64 roomSumRcvStreams
Definition: SCTPAssociation.h:877
bool disableReneging
Definition: SCTPAssociation.h:687
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
SCTP * sctpMain
Definition: SCTPAssociation.h:962
SCTPGapList gapList
Definition: SCTPAssociation.h:619
AssocStatMap assocStatMap
Definition: SCTP.h:171
QueueCounter qCounter
Definition: SCTPAssociation.h:965
uint32_t uint32
Definition: Compat.h:30
static int16 ssnGt(const uint16 ssn1, const uint16 ssn2)
Definition: SCTPAssociation.h:1085
uint32 getHighestTSNReceived() const
Definition: SCTPGapList.h:96
static int32 tsnGt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1081
int32 assocId
Definition: SCTPAssociation.h:908
uint64 queuedReceivedBytes
Definition: SCTPAssociation.h:625
uint32 getCumAckTSN() const
Definition: SCTPGapList.h:91
void removeFromGapList(const uint32 removedTSN)
Definition: SCTPGapList.cc:359
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPParameter * inet::sctp::SCTPAssociation::makeSSNTSNResetParameter ( uint32  srsn)
protected

Referenced by sendStreamResetRequest().

373 {
374  SCTPSSNTSNResetRequestParameter *resetParam;
375  resetParam = new SCTPSSNTSNResetRequestParameter("SSN_TSN_Request_Param");
376  resetParam->setParameterType(SSN_TSN_RESET_REQUEST_PARAMETER);
377  resetParam->setSrReqSn(srsn);
378  resetParam->setByteLength(SCTP_SSN_TSN_RESET_REQUEST_PARAMETER_LENGTH);
380  return resetParam;
381 }
#define SCTP_SSN_TSN_RESET_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:227
uint16 localRequestType
Definition: SCTPAssociation.h:810
Definition: SCTPAssociation.h:158
Definition: SCTPAssociation.h:153
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPDataVariables * inet::sctp::SCTPAssociation::makeVarFromMsg ( SCTPDataChunk datachunk)
protected

Referenced by processDataArrived().

2169 {
2170  SCTPDataVariables *chunk = new SCTPDataVariables();
2171 
2172  chunk->bbit = dataChunk->getBBit();
2173  chunk->ebit = dataChunk->getEBit();
2174  chunk->ibit = dataChunk->getIBit();
2175  chunk->sid = dataChunk->getSid();
2176  chunk->ssn = dataChunk->getSsn();
2177  chunk->ppid = dataChunk->getPpid();
2178  chunk->tsn = dataChunk->getTsn();
2179  if (!dataChunk->getUBit()) {
2180  chunk->ordered = true;
2181  }
2182  else {
2183  chunk->ordered = false;
2184  }
2185  SCTPSimpleMessage *smsg = check_and_cast<SCTPSimpleMessage *>(dataChunk->decapsulate());
2186 
2187  chunk->userData = smsg;
2188  EV_INFO << "smsg encapsulate? " << smsg->getEncaps() << endl;
2189  if (smsg->getEncaps())
2190  chunk->len = smsg->getBitLength();
2191  else
2192  chunk->len = smsg->getDataLen() * 8;
2193  chunk->firstSendTime = dataChunk->getFirstSendTime();
2195 
2196  EV_INFO << "makeVarFromMsg: queuedBytes has been increased to "
2197  << state->queuedReceivedBytes << endl;
2198  return chunk;
2199 }
void calculateRcvBuffer()
Definition: SCTPAssociationUtil.cc:49
uint64 queuedReceivedBytes
Definition: SCTPAssociation.h:625
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
static int32 inet::sctp::SCTPAssociation::midGt ( const uint32  mid1,
const uint32  mid2 
)
inlinestatic
1086 { return SCTP_TSN_GT(mid1, mid2); }
#define SCTP_TSN_GT(a, b)
Definition: SCTPAssociation.h:1076
void inet::sctp::SCTPAssociation::moveChunkToOtherPath ( SCTPDataVariables chunk,
SCTPPathVariables newPath 
)
private

Referenced by chunkReschedulingControl(), and process_TIMEOUT_RTX().

3860 {
3861  // ======= Remove chunk from outstanding bytes ===========================
3862  if (chunk->countsAsOutstanding) {
3863  decreaseOutstandingBytes(chunk);
3864  }
3865 
3866  // ====== Prepare next destination =======================================
3867  chunk->hasBeenFastRetransmitted = false;
3868  chunk->gapReports = 0;
3869  chunk->setNextDestination(newPath);
3870 
3871  // ====== Rebook chunk on new path =======================================
3872  assert(chunk->queuedOnPath->queuedBytes >= chunk->booksize);
3873  chunk->queuedOnPath->queuedBytes -= chunk->booksize;
3874  chunk->queuedOnPath->statisticsPathQueuedSentBytes->record(chunk->queuedOnPath->queuedBytes);
3875 
3876  chunk->queuedOnPath = chunk->getNextDestinationPath();
3877  chunk->queuedOnPath->queuedBytes += chunk->booksize;
3878  chunk->queuedOnPath->statisticsPathQueuedSentBytes->record(chunk->queuedOnPath->queuedBytes);
3879 
3880  // ====== Perform bookkeeping ============================================
3881  // Check, if chunk_ptr->tsn is already in transmission queue.
3882  // This can happen in case multiple timeouts occur in succession.
3883  if (!transmissionQ->checkAndInsertChunk(chunk->tsn, chunk)) {
3884  EV_DETAIL << "TSN " << chunk->tsn << " already in transmissionQ" << endl;
3885  return;
3886  }
3887  else {
3888  chunk->enqueuedInTransmissionQ = true;
3889  EV_DETAIL << "Inserting TSN " << chunk->tsn << " into transmissionQ" << endl;
3890  auto q = qCounter.roomTransQ.find(chunk->getNextDestination());
3891  q->second += ADD_PADDING(chunk->len / 8 + SCTP_DATA_CHUNK_LENGTH);
3892  auto qb = qCounter.bookedTransQ.find(chunk->getNextDestination());
3893  qb->second += chunk->booksize;
3894  state->peerRwnd += (chunk->booksize + state->bytesToAddPerPeerChunk);
3895  if (state->peerAllowsChunks) {
3896  state->peerMsgRwnd++;
3897  }
3898  }
3899  if (state->peerRwnd > state->initialPeerRwnd) {
3901  }
3904  }
3905 
3906  // T.D. 02.08.2011: The peer window may not be full anymore!
3907  if ((state->peerWindowFull) && (state->peerRwnd > 0)) {
3908  state->peerWindowFull = false;
3909  }
3910 
3911  statisticsPeerRwnd->record(state->peerRwnd);
3912 }
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
uint64 peerRwnd
Definition: SCTPAssociation.h:610
void decreaseOutstandingBytes(SCTPDataVariables *chunk)
Definition: SCTPAssociationRcvMessage.cc:41
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
uint64 initialPeerRwnd
Definition: SCTPAssociation.h:611
uint32 peerMsgRwnd
Definition: SCTPAssociation.h:841
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
bool peerAllowsChunks
Definition: SCTPAssociation.h:838
uint32 bytesToAddPerPeerChunk
Definition: SCTPAssociation.h:845
QueueCounter qCounter
Definition: SCTPAssociation.h:965
bool checkAndInsertChunk(const uint32 key, SCTPDataVariables *chunk)
Definition: SCTPQueue.cc:50
cOutVector * statisticsPeerRwnd
Definition: SCTPAssociation.h:983
bool peerWindowFull
Definition: SCTPAssociation.h:595
uint32 initialPeerMsgRwnd
Definition: SCTPAssociation.h:839
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::msgMustBeAbandoned ( SCTPDataMsg msg,
int32  stream,
bool  ordered 
)
protected
bool inet::sctp::SCTPAssociation::nextChunkFitsIntoPacket ( SCTPPathVariables path,
int32  bytes 
)
protected

Referenced by sendOnPath().

2548 {
2549  int32 nextStream = -1;
2550  SCTPSendStream *stream;
2551 
2552  /* Only change stream if we don't have to finish a fragmented message */
2554  nextStream = state->lastStreamScheduled;
2555  else
2556  nextStream = (this->*ssFunctions.ssGetNextSid)(path, true);
2557 
2558  if (nextStream == -1)
2559  return false;
2560 
2561  stream = sendStreams.find(nextStream)->second;
2562 
2563  if (stream) {
2564  cPacketQueue *streamQ = nullptr;
2565 
2566  if (!stream->getUnorderedStreamQ()->isEmpty())
2567  streamQ = stream->getUnorderedStreamQ();
2568  else if (!stream->getStreamQ()->isEmpty())
2569  streamQ = stream->getStreamQ();
2570 
2571  if (streamQ) {
2572  int32 b = ADD_PADDING(((SCTPDataMsg *)streamQ->front())->getEncapsulatedPacket()->getByteLength() + SCTP_DATA_CHUNK_LENGTH);
2573 
2574  /* Check if next message would be fragmented */
2576  /* Test if fragment fits */
2577  if (bytes >= (int32)state->fragPoint)
2578  return true;
2579  else
2580  return false;
2581  }
2582 
2583  /* Message doesn't need to be fragmented, just try if it fits */
2584  if (b <= bytes)
2585  return true;
2586  else
2587  return false;
2588  }
2589  }
2590 
2591  return false;
2592 }
bool lastMsgWasFragment
Definition: SCTPAssociation.h:665
uint32 lastStreamScheduled
Definition: SCTPAssociation.h:626
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
BytesToBeSent bytes
Definition: SCTPAssociation.h:961
uint32 fragPoint
Definition: SCTPAssociation.h:628
int32(SCTPAssociation::* ssGetNextSid)(SCTPPathVariables *path, bool peek)
Definition: SCTPAssociation.h:1291
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
int32_t int32
Definition: Compat.h:31
SSFunctions ssFunctions
Definition: SCTPAssociation.h:1294
value< double, units::m > b
Definition: Units.h:1054
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::nonRenegablyAckChunk ( SCTPDataVariables chunk,
SCTPPathVariables sackPath,
simtime_t &  rttEstimation,
SCTP::AssocStat assocStat 
)
private

Referenced by dequeueAckedChunks(), and handleChunkReportedAsAcked().

1881 {
1882  SCTPPathVariables *lastPath = chunk->getLastDestinationPath();
1883  assert(lastPath != nullptr);
1884 
1885  // ====== Bookkeeping ====================================================
1886  // Subtract chunk size from sender buffer size
1887  state->sendBuffer -= chunk->len / 8;
1888 
1889  // Subtract chunk size from the queue size of its stream
1890  auto streamIterator = sendStreams.find(chunk->sid);
1891  assert(streamIterator != sendStreams.end());
1892  SCTPSendStream *stream = streamIterator->second;
1893  assert(stream != nullptr);
1894  cPacketQueue *streamQ = (chunk->ordered == false) ? stream->getUnorderedStreamQ() : stream->getStreamQ();
1895  assert(streamQ != nullptr);
1896 
1897  if (chunk->priority > 0) {
1898  state->queuedDroppableBytes -= chunk->len / 8;
1899  }
1900 
1901  if ((chunk->hasBeenCountedAsNewlyAcked == false) &&
1902  (chunk->hasBeenAcked == false))
1903  {
1904  if ((state->cmtMovedChunksReduceCwnd == false) ||
1905  (chunk->hasBeenMoved == false))
1906  {
1907  chunk->hasBeenCountedAsNewlyAcked = true;
1908  // The chunk has not been acked before.
1909  // Therefore, its size may *once* be counted as newly acked.
1910  lastPath->newlyAckedBytes += chunk->booksize;
1911  }
1912  }
1913 
1914  assert(chunk->queuedOnPath->queuedBytes >= chunk->booksize);
1915  chunk->queuedOnPath->queuedBytes -= chunk->booksize;
1916  chunk->queuedOnPath->statisticsPathQueuedSentBytes->record(chunk->queuedOnPath->queuedBytes);
1917  chunk->queuedOnPath = nullptr;
1918 
1919  assert(state->queuedSentBytes >= chunk->booksize);
1920  state->queuedSentBytes -= chunk->booksize;
1922  if (assocStat) {
1923  assocStat->ackedBytes += chunk->len / 8;
1924  }
1925  if ((assocStat) && (fairTimer)) {
1926  assocStat->fairAckedBytes += chunk->len / 8;
1927  }
1928 
1929  if ((state->allowCMT == true) &&
1930  (state->cmtSlowPathRTTUpdate == true) &&
1931  (lastPath->waitingForRTTCalculaton == false) &&
1932  (lastPath != sackPath) &&
1933  (chunk->numberOfTransmissions == 1) &&
1934  (chunk->hasBeenMoved == false) &&
1935  (chunk->hasBeenReneged == false))
1936  {
1937  // Slow Path Update
1938  // Remember this chunk's TSN and send time in order to update the
1939  // path's RTT using a stale SACK on its own path.
1940  lastPath->tsnForRTTCalculation = chunk->tsn;
1941  lastPath->txTimeForRTTCalculation = chunk->sendTime;
1942  lastPath->waitingForRTTCalculaton = true;
1943  }
1944 
1945  // ====== RTT calculation ================================================
1946  if ((chunkHasBeenAcked(chunk) == false) && (chunk->countsAsOutstanding)) {
1947  if ((chunk->numberOfTransmissions == 1) && (lastPath == sackPath) && (chunk->hasBeenMoved == false)) {
1948  const simtime_t timeDifference = simTime() - chunk->sendTime;
1949  if ((timeDifference < rttEstimation) || (rttEstimation == SIMTIME_MAX)) {
1950  rttEstimation = timeDifference;
1951  }
1952  }
1953  decreaseOutstandingBytes(chunk);
1954  }
1955 
1956  // ====== Remove chunk pointer from ChunkMap =============================
1957  // The chunk still has to be remembered as acknowledged!
1958  ackChunk(chunk, sackPath);
1959 
1960  // ====== Remove chunk from transmission queue ===========================
1961  // Dequeue chunk, cause it has been acked
1962  if (transmissionQ->getChunk(chunk->tsn)) {
1963  transmissionQ->removeMsg(chunk->tsn);
1964  chunk->enqueuedInTransmissionQ = false;
1965  auto q = qCounter.roomTransQ.find(chunk->getNextDestination());
1966  q->second -= ADD_PADDING(chunk->len / 8 + SCTP_DATA_CHUNK_LENGTH);
1967  auto qb = qCounter.bookedTransQ.find(chunk->getNextDestination());
1968  qb->second -= chunk->booksize;
1969  }
1970 
1971  // ====== Remove chunk from retransmission queue =========================
1972  chunk = retransmissionQ->getAndExtractChunk(chunk->tsn);
1973  if (chunk->userData != nullptr) {
1974  delete chunk->userData;
1975  }
1976  delete chunk;
1977 }
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
bool cmtMovedChunksReduceCwnd
Definition: SCTPAssociation.h:742
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
void decreaseOutstandingBytes(SCTPDataVariables *chunk)
Definition: SCTPAssociationRcvMessage.cc:41
bool allowCMT
Definition: SCTPAssociation.h:705
uint64 sendBuffer
Definition: SCTPAssociation.h:660
void removeMsg(const uint32 key)
Definition: SCTPQueue.cc:157
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
cPacket * userData
Definition: SCTPAssociation.h:482
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
bool cmtSlowPathRTTUpdate
Definition: SCTPAssociation.h:738
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
void ackChunk(SCTPDataVariables *chunk, SCTPPathVariables *sackPath)
Definition: SCTPAssociation.h:1437
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
SCTPDataVariables * getAndExtractChunk(const uint32 tsn)
Definition: SCTPQueue.cc:76
SCTPDataVariables * getChunk(const uint32 key) const
Definition: SCTPQueue.cc:123
QueueCounter qCounter
Definition: SCTPAssociation.h:965
bool fairTimer
Definition: SCTPAssociation.h:927
cOutVector * statisticsQueuedSentBytes
Definition: SCTPAssociation.h:975
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
uint64 queuedSentBytes
Definition: SCTPAssociation.h:623
uint64 queuedDroppableBytes
Definition: SCTPAssociation.h:624
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool chunkHasBeenAcked(const SCTPDataVariables *chunk) const
Definition: SCTPAssociation.h:1448
int32 inet::sctp::SCTPAssociation::numUsableStreams ( void  )
protected

Referenced by SCTPAssociation().

144 {
145  int32 count = 0;
146 
147  for (auto & elem : sendStreams)
148  if (elem.second->getStreamQ()->getLength() > 0 || elem.second->getUnorderedStreamQ()->getLength() > 0) {
149  count++;
150  }
151  return count;
152 }
int count(const std::vector< T > &v, const T &a)
Definition: stlutils.h:58
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
int32_t int32
Definition: Compat.h:31
bool inet::sctp::SCTPAssociation::orderedQueueEmptyOfStream ( uint16  sid)
protected

Referenced by process_STREAM_RESET().

86 {
87  auto streamIterator = sendStreams.find(sid);
88  assert(streamIterator != sendStreams.end());
89  return (streamIterator->second)->getStreamQ()->isEmpty();
90 }
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
bool inet::sctp::SCTPAssociation::pathMapLargestSpace ( const SCTPPathVariables left,
const SCTPPathVariables right 
)
staticprivate
166 {
167  const int l = (left->cwnd - left->outstandingBytes);
168  const int r = (right->cwnd - right->outstandingBytes);
169  return l > r;
170 }
bool inet::sctp::SCTPAssociation::pathMapLargestSpaceAndSSThreshold ( const SCTPPathVariables left,
const SCTPPathVariables right 
)
staticprivate
173 {
174  if (left->ssthresh != right->ssthresh) {
175  return left->ssthresh > right->ssthresh;
176  }
177 
178  const int l = (left->cwnd - left->outstandingBytes);
179  const int r = (right->cwnd - right->outstandingBytes);
180  return l > r;
181 }
bool inet::sctp::SCTPAssociation::pathMapLargestSSThreshold ( const SCTPPathVariables left,
const SCTPPathVariables right 
)
staticprivate
161 {
162  return left->ssthresh > right->ssthresh;
163 }
bool inet::sctp::SCTPAssociation::pathMapRandomized ( const SCTPPathVariables left,
const SCTPPathVariables right 
)
staticprivate
151 {
152  return left->sendAllRandomizer < right->sendAllRandomizer;
153 }
bool inet::sctp::SCTPAssociation::pathMapSmallestLastTransmission ( const SCTPPathVariables left,
const SCTPPathVariables right 
)
staticprivate
156 {
157  return left->lastTransmission < right->lastTransmission;
158 }
void inet::sctp::SCTPAssociation::pathStatusIndication ( const SCTPPathVariables path,
const bool  status 
)
protected

Referenced by pmClearPathCounter(), process_TIMEOUT_HEARTBEAT(), process_TIMEOUT_RTX(), and updateCounters().

2745 {
2746  cPacket *msg = new cPacket("StatusInfo");
2747  msg->setKind(SCTP_I_STATUS);
2748  SCTPStatusInfo *cmd = new SCTPStatusInfo();
2749  cmd->setPathId(path->remoteAddress);
2750  cmd->setAssocId(assocId);
2751  cmd->setActive(status);
2752  msg->setControlInfo(cmd);
2753  if (!status) {
2754  auto iter = sctpMain->assocStatMap.find(assocId);
2755  iter->second.numPathFailures++;
2756  }
2757  sendToApp(msg);
2758 }
int32 status
Definition: SCTPAssociation.h:946
SCTP * sctpMain
Definition: SCTPAssociation.h:962
AssocStatMap assocStatMap
Definition: SCTP.h:171
Definition: SCTPCommand.h:71
int32 assocId
Definition: SCTPAssociation.h:908
void sendToApp(cMessage *msg)
Utility: sends packet to application.
Definition: SCTPAssociationUtil.cc:457
int32 inet::sctp::SCTPAssociation::pathStreamSchedulerManual ( SCTPPathVariables path,
bool  peek 
)
protected

Referenced by SCTPAssociation().

449 {
450  uint32 pathNo = 0;
451  int32 testsid, sid = -1;
452  uint32 lastsid = state->lastStreamScheduled;
453 
454  EV_INFO << "Stream Scheduler: path-aware Manual (peek: " << peek << ")" << endl;
455 
456  if (state->ssStreamToPathMap.empty()) {
457  for (uint16 str = 0; str < outboundStreams; str++) {
458  state->ssStreamToPathMap[str] = 0;
459  }
460 
461  // Fill Stream to Path map
462  uint16 streamNum = 0;
463  cStringTokenizer prioTokenizer(sctpMain->par("streamsToPaths").stringValue());
464  while (prioTokenizer.hasMoreTokens()) {
465  const char *token = prioTokenizer.nextToken();
466  state->ssStreamToPathMap[streamNum] = (uint32)atoi(token);
467  streamNum++;
468  }
469  if (state->ssStreamToPathMap.empty())
470  throw cRuntimeError("streamsToPaths not defined");
471  }
472 
473  for (SCTPPathMap::const_iterator iterator = sctpPathMap.begin(); iterator != sctpPathMap.end(); ++iterator) {
474  if (path == iterator->second)
475  break;
476  pathNo++;
477  }
478  EV_INFO << "Stream Scheduler: about to send on " << pathNo + 1 << ". path" << endl;
479 
480  testsid = state->lastStreamScheduled;
481 
482  do {
483  testsid = (testsid + 1) % outboundStreams;
484 
485  if (state->ssStreamToPathMap[testsid] == (int32)pathNo) {
486  sid = testsid;
487  EV_DETAIL << "Stream Scheduler: chose sid " << sid << ".\n";
488  if (!peek)
489  state->lastStreamScheduled = sid;
490  }
491  } while (sid == -1 && testsid != (int32)state->lastStreamScheduled);
492 
493  EV_INFO << "streamScheduler sid=" << sid << " lastStream=" << lastsid << " outboundStreams=" << outboundStreams << " next=" << state->ssNextStream << "\n";
494 
495  return sid;
496 }
uint32 lastStreamScheduled
Definition: SCTPAssociation.h:626
std::map< uint16, int32 > ssStreamToPathMap
Definition: SCTPAssociation.h:858
bool ssNextStream
Definition: SCTPAssociation.h:853
uint32 outboundStreams
Definition: SCTPAssociation.h:943
SCTP * sctpMain
Definition: SCTPAssociation.h:962
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
uint16_t uint16
Definition: Compat.h:32
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int32 inet::sctp::SCTPAssociation::pathStreamSchedulerMapToPath ( SCTPPathVariables path,
bool  peek 
)
protected

Referenced by SCTPAssociation().

499 {
500  int32 thisPath = -1;
501  int32 workingPaths = 0;
502  for (auto & elem : sctpPathMap) {
503  SCTPPathVariables *myPath = elem.second;
504  if (myPath->activePath) {
505  if (myPath == path) {
506  thisPath = workingPaths;
507  }
508  workingPaths++;
509  }
510  }
511  if (thisPath == -1) {
512  std::cout << "THIS PATH IS NOT WORKING???" << endl;
513  return -1;
514  }
515 
516  int32 sid = -1;
517  for (SCTPSendStreamMap::const_iterator iterator = sendStreams.begin();
518  iterator != sendStreams.end(); iterator++)
519  {
520  SCTPSendStream *stream = iterator->second;
521  if ((stream->getStreamId() % workingPaths) == thisPath) { // Maps to "path" ...
522  if ((stream->getUnorderedStreamQ()->getLength() > 0) || // Stream has something to send ...
523  (stream->getStreamQ()->getLength() > 0))
524  {
525  assert(sid == -1);
526  sid = stream->getStreamId();
527  break;
528  }
529  }
530  }
531 
532  EV_INFO << "pathStreamSchedulerMapToPath sid=" << sid
533  << " path=" << path->remoteAddress
534  << " (path " << (1 + thisPath)
535  << " of " << workingPaths << ")" << endl;
536  return sid;
537 }
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
int32_t int32
Definition: Compat.h:31
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
SCTPDataVariables * inet::sctp::SCTPAssociation::peekAbandonedChunk ( const SCTPPathVariables path)
protected

Referenced by processPacketDropArrived(), and sendOnPath().

2303 {
2304  SCTPDataVariables *retChunk = nullptr;
2305 
2306  if (state->prMethod != 0 && !retransmissionQ->payloadQueue.empty()) {
2307  for (auto & elem : retransmissionQ->payloadQueue) {
2308  SCTPDataVariables *chunk = elem.second;
2309 
2310  if (chunk->getLastDestinationPath() == path) {
2311  /* Apply policies if necessary */
2312  if (!chunk->hasBeenAbandoned && !chunk->hasBeenAcked &&
2313  (chunk->hasBeenFastRetransmitted || chunk->hasBeenTimerBasedRtxed))
2314  {
2315  switch (chunk->prMethod) {
2316  case PR_TTL:
2317  if (chunk->expiryTime > 0 && chunk->expiryTime <= simTime()) {
2318  if (!chunk->hasBeenAbandoned) {
2319  EV_DETAIL << "TSN " << chunk->tsn << " will be abandoned"
2320  << " (expiryTime=" << chunk->expiryTime
2321  << " sendTime=" << chunk->sendTime << ")" << endl;
2322  chunk->hasBeenAbandoned = true;
2324  }
2325  }
2326  break;
2327 
2328  case PR_RTX:
2329  if (chunk->hasBeenFastRetransmitted && chunk->numberOfRetransmissions >= chunk->allowedNoRetransmissions) {
2330  if (!chunk->hasBeenAbandoned) {
2331  EV_DETAIL << "peekAbandonedChunk: TSN " << chunk->tsn << " will be abandoned"
2332  << " (maxRetransmissions=" << chunk->allowedNoRetransmissions << ")" << endl;
2333  chunk->hasBeenAbandoned = true;
2335  }
2336  }
2337  break;
2338  }
2339  }
2340 
2341  if (chunk->hasBeenAbandoned && chunk->sendForwardIfAbandoned) {
2342  retChunk = chunk;
2343  }
2344  }
2345  }
2346  }
2347  return retChunk;
2348 }
Definition: SCTPAssociation.h:137
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
uint32 prMethod
Definition: SCTPAssociation.h:837
Definition: SCTPAssociation.h:136
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
Definition: SCTPCommand.h:78
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPDataMsg* inet::sctp::SCTPAssociation::peekOutboundDataMsg ( )
protected
bool inet::sctp::SCTPAssociation::performStateTransition ( const SCTPEventCode event)
protected

Implemements the pure SCTP state machine.

Referenced by process_RCV_Message(), processCookieAckArrived(), processCookieEchoArrived(), processInitAckArrived(), processInitArrived(), pushUlp(), sendShutdown(), and sendShutdownAck().

1183 {
1184  EV_TRACE << "performStateTransition\n";
1185 
1186  if (event == SCTP_E_IGNORE) { // e.g. discarded segment
1187  EV_DETAIL << "Staying in state: " << stateName(fsm->getState()) << " (no FSM event)\n";
1188  return true;
1189  }
1190 
1191  // state machine
1192  int32 oldState = fsm->getState();
1193 
1194  switch (fsm->getState()) {
1195  case SCTP_S_CLOSED:
1196  switch (event) {
1197  case SCTP_E_ABORT:
1198  FSM_Goto((*fsm), SCTP_S_CLOSED);
1199  break;
1200 
1201  case SCTP_E_OPEN_PASSIVE:
1202  FSM_Goto((*fsm), SCTP_S_CLOSED);
1203  break;
1204 
1205  case SCTP_E_ASSOCIATE:
1206  FSM_Goto((*fsm), SCTP_S_COOKIE_WAIT);
1207  break;
1208 
1209  case SCTP_E_RCV_INIT:
1210  FSM_Goto((*fsm), SCTP_S_CLOSED);
1211  break;
1212 
1213  case SCTP_E_RCV_ABORT:
1214  FSM_Goto((*fsm), SCTP_S_CLOSED);
1215  break;
1216 
1218  FSM_Goto((*fsm), SCTP_S_ESTABLISHED);
1219  break;
1220 
1221  case SCTP_E_CLOSE:
1222  FSM_Goto((*fsm), SCTP_S_CLOSED);
1223  break;
1224 
1225  default:
1226  break;
1227  }
1228  break;
1229 
1230  case SCTP_S_COOKIE_WAIT:
1231  switch (event) {
1232  case SCTP_E_RCV_ABORT:
1233  FSM_Goto((*fsm), SCTP_S_CLOSED);
1234  break;
1235 
1236  case SCTP_E_ABORT:
1237  FSM_Goto((*fsm), SCTP_S_CLOSED);
1238  break;
1239 
1240  case SCTP_E_RCV_INIT_ACK:
1241  FSM_Goto((*fsm), SCTP_S_COOKIE_ECHOED);
1242  break;
1243 
1245  FSM_Goto((*fsm), SCTP_S_ESTABLISHED);
1246  break;
1247 
1248  default:
1249  break;
1250  }
1251  break;
1252 
1253  case SCTP_S_COOKIE_ECHOED:
1254  switch (event) {
1255  case SCTP_E_RCV_ABORT:
1256  FSM_Goto((*fsm), SCTP_S_CLOSED);
1257  break;
1258 
1259  case SCTP_E_ABORT:
1260  FSM_Goto((*fsm), SCTP_S_CLOSED);
1261  break;
1262 
1263  case SCTP_E_RCV_COOKIE_ACK:
1264  FSM_Goto((*fsm), SCTP_S_ESTABLISHED);
1265  break;
1266 
1267  default:
1268  break;
1269  }
1270  break;
1271 
1272  case SCTP_S_ESTABLISHED:
1273  switch (event) {
1274  case SCTP_E_SEND:
1275  FSM_Goto((*fsm), SCTP_S_ESTABLISHED);
1276  break;
1277 
1278  case SCTP_E_ABORT:
1279  FSM_Goto((*fsm), SCTP_S_CLOSED);
1280  break;
1281 
1282  case SCTP_E_RCV_ABORT:
1283  FSM_Goto((*fsm), SCTP_S_CLOSED);
1284  break;
1285 
1286  case SCTP_E_CLOSE:
1287  case SCTP_E_SHUTDOWN:
1288  FSM_Goto((*fsm), SCTP_S_SHUTDOWN_PENDING);
1289  break;
1290 
1291  case SCTP_E_STOP_SENDING:
1292  FSM_Goto((*fsm), SCTP_S_SHUTDOWN_PENDING);
1293  state->stopSending = true;
1294  state->lastTSN = state->nextTSN - 1;
1295  break;
1296 
1297  case SCTP_E_RCV_SHUTDOWN:
1298  FSM_Goto((*fsm), SCTP_S_SHUTDOWN_RECEIVED);
1299  break;
1300 
1301  default:
1302  break;
1303  }
1304  break;
1305 
1307  switch (event) {
1308  case SCTP_E_RCV_ABORT:
1309  FSM_Goto((*fsm), SCTP_S_CLOSED);
1310  break;
1311 
1312  case SCTP_E_ABORT:
1313  FSM_Goto((*fsm), SCTP_S_CLOSED);
1314  break;
1315 
1317  FSM_Goto((*fsm), SCTP_S_SHUTDOWN_SENT);
1318  break;
1319 
1320  case SCTP_E_RCV_SHUTDOWN:
1321  FSM_Goto((*fsm), SCTP_S_SHUTDOWN_RECEIVED);
1322  break;
1323 
1325  FSM_Goto((*fsm), SCTP_S_CLOSED);
1326  break;
1327 
1328  default:
1329  break;
1330  }
1331  break;
1332 
1334  switch (event) {
1335  case SCTP_E_ABORT:
1336  FSM_Goto((*fsm), SCTP_S_CLOSED);
1337  break;
1338 
1339  case SCTP_E_RCV_ABORT:
1340  FSM_Goto((*fsm), SCTP_S_CLOSED);
1341  break;
1342 
1344  FSM_Goto((*fsm), SCTP_S_SHUTDOWN_ACK_SENT);
1345  break;
1346 
1347  case SCTP_E_SHUTDOWN:
1349  break;
1350 
1351  default:
1352  break;
1353  }
1354  break;
1355 
1356  case SCTP_S_SHUTDOWN_SENT:
1357  switch (event) {
1358  case SCTP_E_ABORT:
1359  FSM_Goto((*fsm), SCTP_S_CLOSED);
1360  break;
1361 
1362  case SCTP_E_RCV_ABORT:
1363  FSM_Goto((*fsm), SCTP_S_CLOSED);
1364  break;
1365 
1367  FSM_Goto((*fsm), SCTP_S_CLOSED);
1368  break;
1369 
1370  case SCTP_E_RCV_SHUTDOWN:
1372  FSM_Goto((*fsm), SCTP_S_SHUTDOWN_ACK_SENT);
1373  break;
1374 
1375  default:
1376  break;
1377  }
1378  break;
1379 
1381  switch (event) {
1382  case SCTP_E_ABORT:
1383  FSM_Goto((*fsm), SCTP_S_CLOSED);
1384  break;
1385 
1386  case SCTP_E_RCV_ABORT:
1387  FSM_Goto((*fsm), SCTP_S_CLOSED);
1388  break;
1389 
1391  FSM_Goto((*fsm), SCTP_S_CLOSED);
1392  break;
1393 
1394  default:
1395  break;
1396  }
1397  break;
1398  }
1399 
1400  if (oldState != fsm->getState()) {
1401  EV_DETAIL << "Transition: " << stateName(oldState) << " --> " << stateName(fsm->getState())
1402  << " (event was: " << eventName(event) << ")\n";
1403  EV_DETAIL << sctpMain->getName() << ": " << stateName(oldState) << " --> "
1404  << stateName(fsm->getState()) << " (on " << eventName(event) << ")\n";
1405  stateEntered(fsm->getState());
1406  }
1407  else {
1408  EV << "Staying in state: " << stateName(fsm->getState())
1409  << " (event was: " << eventName(event) << ")\n";
1410  }
1411 
1412  if (event == SCTP_E_ABORT && oldState == fsm->getState() && fsm->getState() == SCTP_S_CLOSED)
1413  return true;
1414 
1415  if (oldState != fsm->getState() && fsm->getState() == SCTP_S_CLOSED) {
1416  EV_DETAIL << "return false because oldState=" << oldState << " and new state is closed\n";
1417  return false;
1418  }
1419  else
1420  return true;
1421 }
static const char * stateName(const int32 state)
Utility: returns name of SCTP_S_xxx constants.
Definition: SCTPAssociationUtil.cc:141
Definition: SCTPAssociation.h:63
Definition: SCTPAssociation.h:78
uint32 lastTSN
Definition: SCTPAssociation.h:617
Definition: SCTPAssociation.h:77
Definition: SCTPAssociation.h:85
Definition: SCTPAssociation.h:75
Definition: SCTPAssociation.h:60
Definition: SCTPAssociation.h:64
Definition: SCTPAssociation.h:58
Definition: SCTPAssociation.h:74
Definition: SCTPAssociation.h:81
SCTP * sctpMain
Definition: SCTPAssociation.h:962
Definition: SCTPAssociation.h:73
Definition: SCTPAssociation.h:62
Definition: SCTPAssociation.h:80
L3Address remoteAddr
Definition: SCTPAssociation.h:911
Definition: SCTPAssociation.h:76
Definition: SCTPAssociation.h:86
Definition: SCTPAssociation.h:84
Definition: SCTPAssociation.h:83
int32_t int32
Definition: Compat.h:31
Definition: SCTPAssociation.h:59
Definition: SCTPAssociation.h:61
Definition: SCTPAssociation.h:79
Definition: SCTPAssociation.h:100
uint32 nextTSN
Definition: SCTPAssociation.h:613
bool stopSending
Definition: SCTPAssociation.h:597
cFSM * fsm
Definition: SCTPAssociation.h:963
static const char * eventName(const int32 event)
Utility: returns name of SCTP_E_xxx constants.
Definition: SCTPAssociationUtil.cc:160
Definition: SCTPAssociation.h:57
Definition: SCTPAssociation.h:82
Definition: SCTPAssociation.h:91
void stateEntered(int32 state)
Definition: SCTPAssociationBase.cc:1423
Definition: SCTPAssociation.h:72
void sendShutdownAck(const L3Address &dest)
Definition: SCTPAssociationUtil.cc:1057
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::pmClearPathCounter ( SCTPPathVariables path)
protected

Referenced by processHeartbeatAckArrived(), and processSackArrived().

2731 {
2732  state->errorCount = 0;
2733  path->pathErrorCount = 0;
2734  if (path->activePath == false) {
2735  /* notify the application */
2736  pathStatusIndication(path, true);
2737  EV_INFO << "Path " << path->remoteAddress
2738  << " state changes from INACTIVE to ACTIVE !!!" << endl;
2739  path->activePath = true; // Mark path as active!
2740  }
2741 }
uint32 errorCount
Definition: SCTPAssociation.h:609
void pathStatusIndication(const SCTPPathVariables *path, const bool status)
Definition: SCTPAssociationUtil.cc:2743
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::pmDataIsSentOn ( SCTPPathVariables path)
protected

Referenced by sendOnPath().

2651 {
2653  /* restart hb_timer on this path */
2654  stopTimer(path->HeartbeatTimer);
2655  if (sctpMain->getEnableHeartbeats()) {
2656  path->heartbeatTimeout = path->pathRto + (double)sctpMain->getHbInterval();
2657  startTimer(path->HeartbeatTimer, path->heartbeatTimeout);
2658  EV_DETAIL << "Restarting HB timer on path " << path->remoteAddress
2659  << " to expire at time " << path->heartbeatTimeout << endl;
2660  }
2661  }
2662 
2663  path->cwndTimeout = path->pathRto;
2664  stopTimer(path->CwndTimer);
2665  startTimer(path->CwndTimer, path->cwndTimeout);
2666 
2667  EV_INFO << "Restarting CWND timer on path " << path->remoteAddress
2668  << " to expire at time " << path->cwndTimeout << endl;
2669 }
bool sendHeartbeatsOnActivePaths
Definition: SCTPAssociation.h:667
bool getEnableHeartbeats()
Definition: SCTP.h:277
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
double getHbInterval()
Definition: SCTP.h:280
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
SCTP * sctpMain
Definition: SCTPAssociation.h:962
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::pmRttMeasurement ( SCTPPathVariables path,
const simtime_t &  rttEstimation 
)
protected

Referenced by processHeartbeatAckArrived(), and processSackArrived().

2762 {
2763  if (rttEstimation < SIMTIME_MAX) {
2764  if (simTime() > path->rttUpdateTime) {
2765  if (path->rttUpdateTime == SIMTIME_ZERO) {
2766  path->rttvar = rttEstimation.dbl() / 2;
2767  path->srtt = rttEstimation;
2768  path->pathRto = 3.0 * rttEstimation.dbl();
2769  path->pathRto = max(min(path->pathRto.dbl(), (double)sctpMain->getRtoMax()),
2770  (double)sctpMain->getRtoMin());
2771  }
2772  else {
2773  path->rttvar = (1.0 - (double)sctpMain->par("rtoBeta")) * path->rttvar.dbl()
2774  + (double)sctpMain->par("rtoBeta") * fabs(path->srtt.dbl() - rttEstimation.dbl());
2775  path->srtt = (1.0 - (double)sctpMain->par("rtoAlpha")) * path->srtt.dbl()
2776  + (double)sctpMain->par("rtoAlpha") * rttEstimation.dbl();
2777  path->pathRto = path->srtt.dbl() + 4.0 * path->rttvar.dbl();
2778  path->pathRto = max(min(path->pathRto.dbl(), (double)sctpMain->getRtoMax()),
2779  (double)sctpMain->getRtoMin());
2780  }
2781  // RFC 2960, sect. 6.3.1: new RTT measurements SHOULD be made no more
2782  // than once per round-trip.
2783  path->rttUpdateTime = simTime() + path->srtt;
2784  path->statisticsPathRTO->record(path->pathRto);
2785  path->statisticsPathRTT->record(rttEstimation);
2786  }
2787  }
2788 }
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
SCTP * sctpMain
Definition: SCTPAssociation.h:962
double getRtoMax()
Definition: SCTP.h:271
double max(const double a, const double b)
Returns the maximum of a and b.
Definition: SCTPAssociation.h:275
void inet::sctp::SCTPAssociation::pmStartPathManagement ( )
protected

Flow control.

2672 {
2673  SCTPPathVariables *path;
2674  const InterfaceEntry *rtie;
2675  int32 i = 0;
2676  /* populate path structures !!! */
2677  /* set a high start value...this is appropriately decreased later (below) */
2679  for (auto & elem : sctpPathMap) {
2680  path = elem.second;
2681  path->pathErrorCount = 0;
2682  rtie = rt->getOutputInterfaceForDestination(path->remoteAddress);
2683  path->pmtu = rtie->getMTU();
2684  EV_DETAIL << "Path MTU of Interface " << i << " = " << path->pmtu << "\n";
2685  if (path->pmtu < state->assocPmtu) {
2686  state->assocPmtu = path->pmtu;
2687  }
2690  }
2691  initCCParameters(path);
2692  path->pathRto = (double)sctpMain->getRtoInitial();
2693  path->srtt = path->pathRto;
2694  path->rttvar = SIMTIME_ZERO;
2695  /* from now on we may have one update per RTO/SRTT */
2696  path->rttUpdateTime = SIMTIME_ZERO;
2697 
2698  path->partialBytesAcked = 0;
2699  path->outstandingBytes = 0;
2700  path->activePath = true;
2701  // Timer probably not running, but stop it anyway I.R.
2702  stopTimer(path->T3_RtxTimer);
2703 
2704  if (path->remoteAddress == state->initialPrimaryPath && !path->confirmed) {
2705  path->confirmed = true;
2706  }
2707  EV_DETAIL << getFullPath() << " numberOfLocalAddresses=" << state->localAddresses.size() << "\n";
2708  if (sctpMain->getEnableHeartbeats()) {
2709  path->heartbeatTimeout = (double)sctpMain->getHbInterval() + i * path->pathRto;
2710  stopTimer(path->HeartbeatTimer);
2711  if (!path->confirmed)
2712  sendHeartbeat(path);
2713  startTimer(path->HeartbeatTimer, path->heartbeatTimeout);
2714  startTimer(path->HeartbeatIntervalTimer, path->heartbeatIntervalTimeout);
2715  }
2716  path->statisticsPathRTO->record(path->pathRto);
2717  i++;
2718  }
2719 }
bool getEnableHeartbeats()
Definition: SCTP.h:277
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
double getHbInterval()
Definition: SCTP.h:280
int getMTU() const
Definition: InterfaceEntry.h:190
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
uint32 fragPoint
Definition: SCTPAssociation.h:628
uint64 localRwnd
Definition: SCTPAssociation.h:612
#define IP_HEADER_LENGTH
Definition: SCTPAssociation.h:236
virtual InterfaceEntry * getOutputInterfaceForDestination(const L3Address &dest) const =0
Convenience function based on findBestMatchingRoute().
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void sendHeartbeat(const SCTPPathVariables *path)
Definition: SCTPAssociationUtil.cc:977
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
L3Address initialPrimaryPath
Definition: SCTPAssociation.h:604
void initCCParameters(SCTPPathVariables *path)
SCTPCCFunctions.
Definition: SCTPCCFunctions.cc:399
IRoutingTable * rt
Definition: SCTPAssociation.h:936
int32_t int32
Definition: Compat.h:31
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
uint32 assocPmtu
Definition: SCTPAssociation.h:627
double getRtoInitial()
Definition: SCTP.h:269
AddressVector localAddresses
Definition: SCTPAssociation.h:607
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPEventCode inet::sctp::SCTPAssociation::preanalyseAppCommandEvent ( int32  commandCode)
protected

Maps app command codes (msg kind of app command msgs) to SCTP_E_xxx event codes.

1011 {
1012  switch (commandCode) {
1013  case SCTP_C_ASSOCIATE:
1014  return SCTP_E_ASSOCIATE;
1015 
1016  case SCTP_C_OPEN_PASSIVE:
1017  return SCTP_E_OPEN_PASSIVE;
1018 
1019  case SCTP_C_SEND:
1020  return SCTP_E_SEND;
1021 
1022  case SCTP_C_CLOSE:
1023  return SCTP_E_CLOSE;
1024 
1025  case SCTP_C_ABORT:
1026  return SCTP_E_ABORT;
1027 
1028  case SCTP_C_RECEIVE:
1029  return SCTP_E_RECEIVE;
1030 
1031  case SCTP_C_SEND_UNORDERED:
1032  return SCTP_E_SEND;
1033 
1034  case SCTP_C_SEND_ORDERED:
1035  return SCTP_E_SEND;
1036 
1037  case SCTP_C_PRIMARY:
1038  return SCTP_E_PRIMARY;
1039 
1041  return SCTP_E_QUEUE_MSGS_LIMIT;
1042 
1044  return SCTP_E_QUEUE_BYTES_LIMIT;
1045 
1046  case SCTP_C_SHUTDOWN:
1047  return SCTP_E_SHUTDOWN;
1048 
1049  case SCTP_C_NO_OUTSTANDING:
1050  return SCTP_E_SEND_SHUTDOWN_ACK;
1051 
1052  case SCTP_C_STREAM_RESET:
1053  return SCTP_E_STREAM_RESET;
1054 
1055  case SCTP_C_RESET_ASSOC:
1056  return SCTP_E_RESET_ASSOC;
1057 
1058  case SCTP_C_ADD_STREAMS:
1059  return SCTP_E_ADD_STREAMS;
1060 
1061  case SCTP_C_SEND_ASCONF:
1062  return SCTP_E_SEND_ASCONF; // Needed for multihomed NAT
1063 
1065  return SCTP_E_SET_STREAM_PRIO;
1066 
1067  case SCTP_C_ACCEPT:
1068  return SCTP_E_ACCEPT;
1069 
1070  case SCTP_C_SET_RTO_INFO:
1071  return SCTP_E_SET_RTO_INFO;
1072 
1073  default:
1074  EV_DETAIL << "commandCode=" << commandCode << "\n";
1075  throw cRuntimeError("Unknown message kind in app command");
1076  }
1077 }
Definition: SCTPAssociation.h:96
Definition: SCTPAssociation.h:97
Definition: SCTPAssociation.h:77
Definition: SCTPCommand.h:32
Definition: SCTPCommand.h:40
Definition: SCTPCommand.h:33
Definition: SCTPAssociation.h:75
Definition: SCTPCommand.h:43
Definition: SCTPAssociation.h:107
Definition: SCTPAssociation.h:101
Definition: SCTPCommand.h:46
Definition: SCTPAssociation.h:74
Definition: SCTPAssociation.h:105
Definition: SCTPCommand.h:38
Definition: SCTPCommand.h:35
Definition: SCTPCommand.h:37
Definition: SCTPAssociation.h:106
Definition: SCTPAssociation.h:73
Definition: SCTPCommand.h:41
Definition: SCTPCommand.h:42
Definition: SCTPAssociation.h:76
Definition: SCTPCommand.h:44
Definition: SCTPCommand.h:31
Definition: SCTPCommand.h:53
Definition: SCTPCommand.h:50
Definition: SCTPAssociation.h:104
Definition: SCTPAssociation.h:103
Definition: SCTPCommand.h:52
Definition: SCTPCommand.h:34
Definition: SCTPAssociation.h:102
Definition: SCTPAssociation.h:92
Definition: SCTPCommand.h:47
Definition: SCTPAssociation.h:99
Definition: SCTPCommand.h:45
Definition: SCTPAssociation.h:94
Definition: SCTPCommand.h:39
Definition: SCTPCommand.h:49
Definition: SCTPAssociation.h:72
void inet::sctp::SCTPAssociation::printAssocBrief ( )
protected

Utility: prints local/remote addr/port and app gate index/assocId.

285 {
286  EV_DETAIL << "Connection " << this << " "
287  << localAddr << ":" << localPort << " to " << remoteAddr << ":" << remotePort
288  << " on app[" << appGateIndex << "],assocId=" << assocId
289  << " in " << stateName(fsm->getState()) << "\n";
290 }
static const char * stateName(const int32 state)
Utility: returns name of SCTP_S_xxx constants.
Definition: SCTPAssociationUtil.cc:141
uint16 remotePort
Definition: SCTPAssociation.h:914
L3Address remoteAddr
Definition: SCTPAssociation.h:911
L3Address localAddr
Definition: SCTPAssociation.h:912
int32 assocId
Definition: SCTPAssociation.h:908
int32 appGateIndex
Definition: SCTPAssociation.h:907
cFSM * fsm
Definition: SCTPAssociation.h:963
uint16 localPort
Definition: SCTPAssociation.h:913
void inet::sctp::SCTPAssociation::printOutstandingTsns ( )
protected
void inet::sctp::SCTPAssociation::printSctpPathMap ( ) const

Referenced by processInitAckArrived(), processInitArrived(), sendInit(), and sendInitAck().

132 {
133  EV_DEBUG << "SCTP PathMap:" << endl;
134  for (const auto & elem : sctpPathMap) {
135  const SCTPPathVariables *path = elem.second;
136  EV_DEBUG << " - " << path->remoteAddress << ": osb=" << path->outstandingBytes
137  << " cwnd=" << path->cwnd << endl;
138  }
139 }
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
void inet::sctp::SCTPAssociation::printSegmentBrief ( SCTPMessage sctpmsg)
staticprotected

Utility: prints important header fields.

293 {
294  EV_STATICCONTEXT;
295 
296  EV_DETAIL << "." << sctpmsg->getSrcPort() << " > "
297  << "." << sctpmsg->getDestPort() << ": "
298  << "initTag " << sctpmsg->getTag() << "\n";
299 }
void inet::sctp::SCTPAssociation::process_ABORT ( SCTPEventCode event)
protected
412 {
413  EV_DEBUG << "SCTPAssociationEventProc:process_ABORT; assoc=" << assocId << endl;
414  switch (fsm->getState()) {
415  case SCTP_S_ESTABLISHED:
417  sendAbort();
418  break;
419  }
420 }
Definition: SCTPAssociation.h:60
SCTPPathVariables * getPrimaryPath() const
Definition: SCTPAssociation.h:558
void sendAbort(uint16 tBit=0)
Definition: SCTPAssociationUtil.cc:1101
int32 assocId
Definition: SCTPAssociation.h:908
cFSM * fsm
Definition: SCTPAssociation.h:963
void sendOnAllPaths(SCTPPathVariables *firstPath)
Definition: SCTPAssociationSendAll.cc:275
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_ASSOCIATE ( SCTPEventCode event,
SCTPCommand sctpCommand,
cMessage *  msg 
)
protected
34 {
35  L3Address lAddr, rAddr;
36 
37  SCTPOpenCommand *openCmd = check_and_cast<SCTPOpenCommand *>(sctpCommand);
38 
39  EV_INFO << "SCTPAssociationEventProc:process_ASSOCIATE\n";
40 
41  switch (fsm->getState()) {
42  case SCTP_S_CLOSED:
43  if (msg->getContextPointer() != NULL) {
44  sctpMain->setSocketOptions((SocketOptions*) (msg->getContextPointer()));
45  }
46  initAssociation(openCmd);
47  state->active = true;
48  localAddressList = openCmd->getLocalAddresses();
49  lAddr = openCmd->getLocalAddresses().front();
50  if (!(openCmd->getRemoteAddresses().empty())) {
51  remoteAddressList = openCmd->getRemoteAddresses();
52  rAddr = openCmd->getRemoteAddresses().front();
53  }
54  else
55  rAddr = openCmd->getRemoteAddr();
56  localPort = openCmd->getLocalPort();
57  remotePort = openCmd->getRemotePort();
58  EV_DETAIL << "open active with fd=" << fd << " and assocId=" << assocId << endl;
59  fd = openCmd->getFd();
60  state->streamReset = openCmd->getStreamReset();
61  state->prMethod = openCmd->getPrMethod();
62  state->numRequests = openCmd->getNumRequests();
63  state->appLimited = openCmd->getAppLimited();
64  if (rAddr.isUnspecified() || remotePort == 0)
65  throw cRuntimeError("Error processing command OPEN_ACTIVE: remote address and port must be specified");
66 
67  if (localPort == 0) {
69  }
70  EV_INFO << "OPEN: " << lAddr << ":" << localPort << " --> " << rAddr << ":" << remotePort << "\n";
71 
72  sctpMain->updateSockPair(this, lAddr, rAddr, localPort, remotePort);
73  state->localRwnd = (long)sctpMain->par("arwnd");
74  sendInit();
76  break;
77 
78  default:
79  throw cRuntimeError("Error processing command OPEN_ACTIVE: connection already exists");
80  }
81 }
void sendInit()
Methods for creating and sending chunks.
Definition: SCTPAssociationUtil.cc:508
bool appLimited
Definition: SCTPAssociation.h:791
uint16 getEphemeralPort()
To be called from SCTPAssociation: reserves an ephemeral port for the connection. ...
Definition: SCTP.cc:591
AddressVector remoteAddressList
Definition: SCTPAssociation.h:940
void setSocketOptions(SocketOptions *options)
Definition: SCTP.h:266
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
AddressVector localAddressList
Definition: SCTPAssociation.h:939
bool active
Definition: SCTPAssociation.h:572
uint64 localRwnd
Definition: SCTPAssociation.h:612
uint32 prMethod
Definition: SCTPAssociation.h:837
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void initAssociation(SCTPOpenCommand *openCmd)
Utility: creates send/receive queues and sctpAlgorithm.
Definition: SCTPAssociationUtil.cc:462
simtime_t initRexmitTimeout
Definition: SCTPAssociation.h:650
int32 fd
Definition: SCTPAssociation.h:909
uint32 numRequests
Definition: SCTPAssociation.h:631
int32 assocId
Definition: SCTPAssociation.h:908
cFSM * fsm
Definition: SCTPAssociation.h:963
Definition: SCTPAssociation.h:57
uint16 localPort
Definition: SCTPAssociation.h:913
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
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
bool streamReset
Definition: SCTPAssociation.h:785
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_CLOSE ( SCTPEventCode event)
protected
395 {
396  EV_DEBUG << "SCTPAssociationEventProc:process_CLOSE; assoc=" << assocId << endl;
397  switch (fsm->getState()) {
398  case SCTP_S_ESTABLISHED:
400  sendShutdown();
401  break;
402 
404  if (getOutstandingBytes() == 0) {
406  }
407  break;
408  }
409 }
Definition: SCTPAssociation.h:63
int32 getOutstandingBytes() const
Definition: SCTPAssociationUtil.cc:2721
void sendShutdown()
Definition: SCTPAssociationUtil.cc:1128
Definition: SCTPAssociation.h:60
SCTPPathVariables * getPrimaryPath() const
Definition: SCTPAssociation.h:558
L3Address remoteAddr
Definition: SCTPAssociation.h:911
int32 assocId
Definition: SCTPAssociation.h:908
cFSM * fsm
Definition: SCTPAssociation.h:963
void sendOnAllPaths(SCTPPathVariables *firstPath)
Definition: SCTPAssociationSendAll.cc:275
void sendShutdownAck(const L3Address &dest)
Definition: SCTPAssociationUtil.cc:1057
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_OPEN_PASSIVE ( SCTPEventCode event,
SCTPCommand sctpCommand,
cMessage *  msg 
)
protected
84 {
85  L3Address lAddr;
87 
88  SCTPOpenCommand *openCmd = check_and_cast<SCTPOpenCommand *>(sctpCommand);
89 
90  EV_DEBUG << "SCTPAssociationEventProc:process_OPEN_PASSIVE\n";
91 
92  switch (fsm->getState()) {
93  case SCTP_S_CLOSED:
94  if (msg->getContextPointer() != NULL)
95  sctpMain->setSocketOptions((SocketOptions*) (msg->getContextPointer()));
96  initAssociation(openCmd);
97  state->fork = openCmd->getFork();
98  localAddressList = openCmd->getLocalAddresses();
99  EV_DEBUG << "process_OPEN_PASSIVE: number of local addresses=" << localAddressList.size() << "\n";
100  lAddr = openCmd->getLocalAddresses().front();
101  localPort = openCmd->getLocalPort();
102  inboundStreams = openCmd->getInboundStreams();
103  outboundStreams = openCmd->getOutboundStreams();
104  listening = true;
105  fd = openCmd->getFd();
106  EV_DETAIL << "open listening socket with fd=" << fd << " and assocId=" << assocId << endl;
107  state->localRwnd = (long)sctpMain->par("arwnd");
108  state->localMsgRwnd = sctpMain->par("messageAcceptLimit");
109  state->streamReset = openCmd->getStreamReset();
110  state->numRequests = openCmd->getNumRequests();
111  state->messagesToPush = openCmd->getMessagesToPush();
112 
113  if (localPort == 0)
114  throw cRuntimeError("Error processing command OPEN_PASSIVE: local port must be specified");
115 
116  EV_DEBUG << "Assoc " << assocId << "::Starting to listen on: " << lAddr << ":" << localPort << "\n";
117 
118  sctpMain->updateSockPair(this, lAddr, L3Address(), localPort, 0);
119  break;
120 
121  default:
122  throw cRuntimeError("Error processing command OPEN_PASSIVE: connection already exists");
123  }
124 }
void setSocketOptions(SocketOptions *options)
Definition: SCTP.h:266
AddressVector localAddressList
Definition: SCTPAssociation.h:939
uint64 localRwnd
Definition: SCTPAssociation.h:612
uint32 outboundStreams
Definition: SCTPAssociation.h:943
uint32 localMsgRwnd
Definition: SCTPAssociation.h:840
int16_t int16
Definition: Compat.h:33
uint32 inboundStreams
Definition: SCTPAssociation.h:942
SCTP * sctpMain
Definition: SCTPAssociation.h:962
bool fork
Definition: SCTPAssociation.h:573
void initAssociation(SCTPOpenCommand *openCmd)
Utility: creates send/receive queues and sctpAlgorithm.
Definition: SCTPAssociationUtil.cc:462
int32 fd
Definition: SCTPAssociation.h:909
uint32 numRequests
Definition: SCTPAssociation.h:631
uint32 messagesToPush
Definition: SCTPAssociation.h:633
int32 assocId
Definition: SCTPAssociation.h:908
bool listening
Definition: SCTPAssociation.h:910
cFSM * fsm
Definition: SCTPAssociation.h:963
Definition: SCTPAssociation.h:57
uint16 localPort
Definition: SCTPAssociation.h:913
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
bool streamReset
Definition: SCTPAssociation.h:785
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_PRIMARY ( SCTPEventCode event,
SCTPCommand sctpCommand 
)
protected
315 {
316  SCTPPathInfo *pinfo = check_and_cast<SCTPPathInfo *>(sctpCommand);
317  state->setPrimaryPath(getPath(pinfo->getRemoteAddress()));
318 }
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
void setPrimaryPath(SCTPPathVariables *path)
Definition: SCTPAssociation.h:545
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_QUEUE_BYTES_LIMIT ( const SCTPCommand sctpCommand)
protected
389 {
390  const SCTPInfo *qinfo = check_and_cast<const SCTPInfo *>(sctpCommand);
391  state->sendQueueLimit = qinfo->getText();
392 }
uint64 sendQueueLimit
Definition: SCTPAssociation.h:659
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_QUEUE_MSGS_LIMIT ( const SCTPCommand sctpCommand)
protected

Queue Management.

382 {
383  const SCTPInfo *qinfo = check_and_cast<const SCTPInfo *>(sctpCommand);
384  state->queueLimit = qinfo->getText();
385  EV_DEBUG << "state->queueLimit set to " << state->queueLimit << "\n";
386 }
uint32 queueLimit
Definition: SCTPAssociation.h:640
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::process_RCV_Message ( SCTPMessage sctpseg,
const L3Address src,
const L3Address dest 
)
protected
75 {
76  // ====== Header checks ==================================================
77  EV_DEBUG << getFullPath() << " SCTPAssociationRcvMessage:process_RCV_Message"
78  << " localAddr=" << localAddr
79  << " remoteAddr=" << remoteAddr << endl;
80  state->pktDropSent = false;
81  if ((sctpmsg->hasBitError() || !sctpmsg->getChecksumOk())) {
82  if (((SCTPChunk *)(sctpmsg->getChunks(0)))->getChunkType() == INIT_ACK) {
84  EV_WARN << "InitAck with bit-error. Retransmit Init" << endl;
87  }
88  if (((SCTPChunk *)(sctpmsg->getChunks(0)))->getChunkType() == COOKIE_ACK) {
90  EV_WARN << "CookieAck with bit-error. Retransmit CookieEcho" << endl;
93  }
94  if (!(sctpMain->pktdrop) || !state->peerPktDrop) {
95  EV_WARN << "Packet has bit-error. Return\n";
96  return true;
97  }
98  }
99 
100  SCTPPathVariables *path = getPath(src);
101  const uint16 srcPort = sctpmsg->getDestPort();
102  const uint16 destPort = sctpmsg->getSrcPort();
103  const uint32 numberOfChunks = sctpmsg->getChunksArraySize();
104  EV_DETAIL << "numberOfChunks=" << numberOfChunks << endl;
105 
106  state->sctpmsg = sctpmsg->dup();
107  bool authenticationNecessary = state->peerAuth;
108  state->sackAlreadySent = false;
109  if ((sctpmsg->getChecksumOk() == false || sctpmsg->hasBitError()) &&
110  (sctpMain->pktdrop) &&
111  (state->peerPktDrop))
112  {
113  sendPacketDrop(true);
114  return true;
115  }
116 
117  if (fsm->getState() != SCTP_S_CLOSED &&
118  fsm->getState() != SCTP_S_COOKIE_WAIT &&
119  fsm->getState() != SCTP_S_COOKIE_ECHOED &&
120  fsm->getState() != SCTP_S_SHUTDOWN_ACK_SENT &&
122  assocThroughputVector != nullptr)
123  {
124  assocThroughputVector->record(state->assocThroughput / (simTime() - state->lastAssocThroughputTime) / 1000);
125  state->lastAssocThroughputTime = simTime();
126  state->assocThroughput = 0;
127  }
128  state->assocThroughput += sctpmsg->getByteLength();
129 
130  // ====== Handle chunks ==================================================
131  bool trans = true;
132  bool sendAllowed = false;
133  bool dupReceived = false;
134  bool dataChunkReceived = false;
135  bool shutdownCalled = false;
136  bool sackWasReceived = false;
137  for (uint32 i = 0; i < numberOfChunks; i++) {
138  SCTPChunk *header = (SCTPChunk *)(sctpmsg->removeChunk());
139  const uint8 type = header->getChunkType();
140 
141  if ((type != INIT) &&
142  (type != ABORT) &&
143  (type != ERRORTYPE) &&
144  (sctpmsg->getTag() != peerVTag))
145  {
146  EV_WARN << " VTag " << sctpmsg->getTag() << " incorrect. Should be "
147  << peerVTag << " localVTag=" << localVTag << endl;
148  return true;
149  }
150 
151  if (authenticationNecessary) {
152  if (type == AUTH) {
153  EV_INFO << "AUTH received" << endl;
154  SCTPAuthenticationChunk *authChunk;
155  authChunk = check_and_cast<SCTPAuthenticationChunk *>(header);
156  if (authChunk->getHMacIdentifier() != 1) {
157  sendHMacError(authChunk->getHMacIdentifier());
158  auto it = sctpMain->assocStatMap.find(assocId);
159  it->second.numAuthChunksRejected++;
160  delete authChunk;
161  return true;
162  }
163  if (authChunk->getHMacOk() == false) {
164  delete authChunk;
165  auto it = sctpMain->assocStatMap.find(assocId);
166  it->second.numAuthChunksRejected++;
167  return true;
168  }
169  authenticationNecessary = false;
170  auto it = sctpMain->assocStatMap.find(assocId);
171  it->second.numAuthChunksAccepted++;
172  delete authChunk;
173  continue;
174  }
175  else {
176  if (typeInChunkList(type)) {
177  return true;
178  }
179  }
180  }
181 
182  switch (type) {
183  case INIT:
184  EV_INFO << "INIT received" << endl;
185  SCTPInitChunk *initChunk;
186  initChunk = check_and_cast<SCTPInitChunk *>(header);
187  if ((initChunk->getNoInStreams() != 0) &&
188  (initChunk->getNoOutStreams() != 0) &&
189  (initChunk->getInitTag() != 0))
190  {
191  trans = processInitArrived(initChunk, srcPort, destPort);
192  }
193  i = numberOfChunks - 1;
194  delete initChunk;
195  break;
196 
197  case INIT_ACK:
198  EV_INFO << "INIT_ACK received" << endl;
199  if (fsm->getState() == SCTP_S_COOKIE_WAIT) {
200  SCTPInitAckChunk *initAckChunk;
201  initAckChunk = check_and_cast<SCTPInitAckChunk *>(header);
202  if ((initAckChunk->getNoInStreams() != 0) &&
203  (initAckChunk->getNoOutStreams() != 0) &&
204  (initAckChunk->getInitTag() != 0))
205  {
206  trans = processInitAckArrived(initAckChunk);
207  }
208  else if (initAckChunk->getInitTag() == 0) {
209  sendAbort();
211  return true;
212  }
213  i = numberOfChunks - 1;
214  delete initAckChunk;
215  }
216  else {
217  EV_INFO << "INIT_ACK will be ignored" << endl;
218  }
219  break;
220 
221  case COOKIE_ECHO:
222  EV_INFO << "COOKIE_ECHO received" << endl;
223  SCTPCookieEchoChunk *cookieEchoChunk;
224  cookieEchoChunk = check_and_cast<SCTPCookieEchoChunk *>(header);
225  trans = processCookieEchoArrived(cookieEchoChunk, src);
226  delete cookieEchoChunk;
227  break;
228 
229  case COOKIE_ACK:
230  EV_INFO << "COOKIE_ACK received" << endl;
231  if (fsm->getState() == SCTP_S_COOKIE_ECHOED) {
232  SCTPCookieAckChunk *cookieAckChunk;
233  cookieAckChunk = check_and_cast<SCTPCookieAckChunk *>(header);
234  trans = processCookieAckArrived();
235  delete cookieAckChunk;
236  }
237  break;
238 
239  case DATA:
240  EV_INFO << "DATA received" << endl;
241  if (fsm->getState() == SCTP_S_CLOSED) {
242  sendAbort(1);
244  return true;
245  }
246  if (fsm->getState() == SCTP_S_COOKIE_ECHOED) {
248  }
249  if (state->stopReading) {
250  if (state->shutdownChunk) {
251  delete state->shutdownChunk;
252  state->shutdownChunk = nullptr;
253  }
254  delete header;
255  sendAbort();
256  if (state->sctpmsg) {
257  delete state->sctpmsg;
258  state->sctpmsg = nullptr;
259  }
261  return true;
262  }
263  if (!(fsm->getState() == SCTP_S_SHUTDOWN_RECEIVED || fsm->getState() == SCTP_S_SHUTDOWN_ACK_SENT)) {
264  SCTPDataChunk *dataChunk;
265  dataChunk = check_and_cast<SCTPDataChunk *>(header);
266  if ((dataChunk->getByteLength() - SCTP_DATA_CHUNK_LENGTH) > 0) {
267  dacPacketsRcvd++;
268  const SCTPEventCode event = processDataArrived(dataChunk);
269  if (event == SCTP_E_DELIVERED) {
270  if ((state->streamReset) && (state->incomingRequest != nullptr || state->resetRequested) &&
273  {
275  if (state->inOut) {
277  }
278  else {
280  }
281  }
282  dataChunkReceived = true;
283  state->sackAllowed = true;
284  } else if (event == SCTP_E_SEND) {
285  dataChunkReceived = true;
286  state->sackAllowed = true;
287  } else if (event == SCTP_E_DUP_RECEIVED) {
288  dupReceived = true;
289  } else if (event == SCTP_E_ABORT) {
290  sendAbort();
292  return true;
293  } else {
294  dataChunkReceived = false;
295  state->sackAllowed = false;
296  }
297  } else {
298  sendAbort();
300  return true;
301  }
302  delete dataChunk;
303  }
304  trans = true;
305  break;
306 
307  case SACK:
308  case NR_SACK: {
309  EV_INFO << "SACK received" << endl;
310  const int32 scount = qCounter.roomSumSendStreams;
311  SCTPSackChunk *sackChunk;
312  sackChunk = check_and_cast<SCTPSackChunk *>(header);
313  processSackArrived(sackChunk);
314  trans = true;
315  sendAllowed = true;
316  delete sackChunk;
317  if (getOutstandingBytes() == 0 && transmissionQ->getQueueSize() == 0 && scount == 0) {
318  if (fsm->getState() == SCTP_S_SHUTDOWN_PENDING) {
319  EV_DETAIL << "No more packets: send SHUTDOWN" << endl;
320  sendShutdown();
322  shutdownCalled = true;
323  }
324  else if (fsm->getState() == SCTP_S_SHUTDOWN_RECEIVED) {
325  EV_DETAIL << "No more outstanding" << endl;
327  }
328  }
329  sackWasReceived = true;
330  break;
331  }
332 
333  case ABORT:
334  SCTPAbortChunk *abortChunk;
335  abortChunk = check_and_cast<SCTPAbortChunk *>(header);
336  EV_INFO << "ABORT with T-Bit "
337  << abortChunk->getT_Bit() << " received" << endl;
338  if (sctpmsg->getTag() == localVTag || sctpmsg->getTag() == peerVTag) {
341  }
342  delete abortChunk;
343  break;
344 
345  case HEARTBEAT:
346  EV_INFO << "HEARTBEAT received" << endl;
347  SCTPHeartbeatChunk *heartbeatChunk;
348  heartbeatChunk = check_and_cast<SCTPHeartbeatChunk *>(header);
349  if (!(fsm->getState() == SCTP_S_CLOSED)) {
350  sendHeartbeatAck(heartbeatChunk, dest, src);
351  }
352  trans = true;
353  delete heartbeatChunk;
354  if (path) {
355  path->numberOfHeartbeatsRcvd++;
356  path->vectorPathRcvdHb->record(path->numberOfHeartbeatsRcvd);
357  }
358  break;
359 
360  case HEARTBEAT_ACK:
361  EV_INFO << "HEARTBEAT_ACK received" << endl;
362  if (fsm->getState() == SCTP_S_COOKIE_ECHOED) {
364  }
365  SCTPHeartbeatAckChunk *heartbeatAckChunk;
366  heartbeatAckChunk = check_and_cast<SCTPHeartbeatAckChunk *>(header);
367  if (path) {
368  processHeartbeatAckArrived(heartbeatAckChunk, path);
369  }
370  trans = true;
371  delete heartbeatAckChunk;
372  break;
373 
374  case SHUTDOWN:
375  EV_INFO << "SHUTDOWN received" << endl;
376  SCTPShutdownChunk *shutdownChunk;
377  shutdownChunk = check_and_cast<SCTPShutdownChunk *>(header);
378  if (shutdownChunk->getCumTsnAck() > state->lastTsnAck) {
379  simtime_t rttEstimation = SIMTIME_MAX;
380  dequeueAckedChunks(shutdownChunk->getCumTsnAck(),
381  getPath(remoteAddr), rttEstimation);
382  state->lastTsnAck = shutdownChunk->getCumTsnAck();
383  }
386  trans = true;
387  delete shutdownChunk;
388  if (state->resetChunk != nullptr) {
389  delete state->resetChunk;
390  }
391  break;
392 
393  case SHUTDOWN_ACK:
394  EV_INFO << "SHUTDOWN_ACK received" << endl;
395  if (fsm->getState() != SCTP_S_ESTABLISHED) {
396  SCTPShutdownAckChunk *shutdownAckChunk;
397  shutdownAckChunk = check_and_cast<SCTPShutdownAckChunk *>(header);
399  stopTimers();
402  EV_DETAIL << "state=" << stateName(fsm->getState()) << endl;
403  if ((fsm->getState() == SCTP_S_SHUTDOWN_SENT) ||
404  (fsm->getState() == SCTP_S_SHUTDOWN_ACK_SENT))
405  {
408  if (state->shutdownChunk) {
409  delete state->shutdownChunk;
410  state->shutdownChunk = nullptr;
411  }
412  }
413  delete shutdownAckChunk;
414  if (state->resetChunk != nullptr) {
415  delete state->resetChunk;
416  }
417  }
418  break;
419 
420  case SHUTDOWN_COMPLETE:
421  EV_INFO << "Shutdown Complete arrived" << endl;
422  SCTPShutdownCompleteChunk *shutdownCompleteChunk;
423  shutdownCompleteChunk = check_and_cast<SCTPShutdownCompleteChunk *>(header);
425  sendIndicationToApp(SCTP_I_PEER_CLOSED); // necessary for NAT-Rendezvous
426  if (trans == true) {
427  stopTimers();
428  }
431  delete state->shutdownAckChunk;
432  delete shutdownCompleteChunk;
433  break;
434 
435  case FORWARD_TSN:
436  EV_INFO << "FORWARD_TSN received" << endl;
437  SCTPForwardTsnChunk *forwChunk;
438  forwChunk = check_and_cast<SCTPForwardTsnChunk *>(header);
439  processForwardTsnArrived(forwChunk);
440  trans = true;
441  sendAllowed = true;
442  dataChunkReceived = true;
443  delete forwChunk;
444  break;
445 
446  case RE_CONFIG:
447  EV_INFO << "StreamReset received" << endl;
448  if (fsm->getState() != SCTP_S_ESTABLISHED) {
449  delete header;
450  break;
451  }
452  SCTPStreamResetChunk *strResChunk;
453  strResChunk = check_and_cast<SCTPStreamResetChunk *>(header);
454  processStreamResetArrived(strResChunk);
455  trans = true;
456  sendAllowed = true;
457  delete strResChunk;
458  break;
459 
460  case ASCONF:
461  EV_INFO << "ASCONF received" << endl;
462  if (fsm->getState() == SCTP_S_COOKIE_ECHOED) {
464  }
465  SCTPAsconfChunk *asconfChunk;
466  asconfChunk = check_and_cast<SCTPAsconfChunk *>(header);
467  processAsconfArrived(asconfChunk);
468  trans = true;
469  delete asconfChunk;
470  break;
471 
472  case ASCONF_ACK:
473  EV_INFO << "ASCONF_ACK received" << endl;
474  SCTPAsconfAckChunk *asconfAckChunk;
475  asconfAckChunk = check_and_cast<SCTPAsconfAckChunk *>(header);
476  processAsconfAckArrived(asconfAckChunk);
477  trans = true;
478  delete state->asconfChunk;
479  delete asconfAckChunk;
480  break;
481 
482  case PKTDROP:
483  EV_INFO << "PKTDROP received" << endl;
484  if (sctpMain->pktdrop) {
485  SCTPPacketDropChunk *packetDropChunk;
486  packetDropChunk = check_and_cast<SCTPPacketDropChunk *>(header);
487  if (packetDropChunk->getBFlag() && !packetDropChunk->getMFlag())
488  processPacketDropArrived(packetDropChunk);
489 
490  trans = true;
491  sendAllowed = true;
492  delete packetDropChunk;
493  }
494  break;
495 
496  case ERRORTYPE:
497  EV_INFO << "ERROR received" << endl;
498  SCTPErrorChunk *errorChunk;
499  errorChunk = check_and_cast<SCTPErrorChunk *>(header);
500  processErrorArrived(errorChunk);
501  trans = true;
502  delete errorChunk;
503  break;
504 
505  default:
506  EV_ERROR << "different type" << endl; // TODO
507  break;
508  }
509 
510  if (i == numberOfChunks - 1 && ((dataChunkReceived && !state->sackAlreadySent) || dupReceived)) {
511  sendAllowed = true;
512  EV_DEBUG << "i=" << i << " sendAllowed=true; scheduleSack" << endl;
513  scheduleSack();
514  if (fsm->getState() == SCTP_S_SHUTDOWN_SENT && state->ackState >= sackFrequency) {
515  sendSack();
516  }
517  }
518 
519  // Send any new DATA chunks, SACK chunks, HEARTBEAT chunks etc.
520  EV_DETAIL << "SCTPAssociationRcvMessage: send new data? state=" << stateName(fsm->getState())
521  << " sendAllowed=" << sendAllowed
522  << " shutdownCalled=" << shutdownCalled << endl;
523  if (((fsm->getState() == SCTP_S_ESTABLISHED) ||
524  (fsm->getState() == SCTP_S_SHUTDOWN_PENDING) ||
525  (fsm->getState() == SCTP_S_SHUTDOWN_RECEIVED)) &&
526  (sendAllowed) &&
527  (!shutdownCalled))
528  {
530  }
531  }
532  if (state->sendResponse > 0) {
535  if (state->incomingRequest != nullptr)
536  sendStreamResetResponse((SCTPSSNTSNResetRequestParameter *)state->incomingRequest, PERFORMED, true);
537  } else if (state->sendResponse == PERFORMED_WITH_ADDOUT) {
538  sendAddOutgoingStreamsRequest(((SCTPAddStreamsRequestParameter *)state->incomingRequest)->getNumberOfStreams());
540  sendStreamResetResponse(((SCTPAddStreamsRequestParameter *)state->incomingRequest)->getSrReqSn(), PERFORMED);
541  } else {
543  }
544  state->sendResponse = 0;
545  state->responseSn = 0;
546  }
547  if (sackWasReceived) {
549  sackWasReceived = false;
550  }
551 
552  // ====== Clean-up =======================================================
553  if (!state->pktDropSent) {
555  EV_DEBUG << "state->sctpmsg was disposed" << endl;
556  }
557  return trans;
558 }
static const char * stateName(const int32 state)
Utility: returns name of SCTP_S_xxx constants.
Definition: SCTPAssociationUtil.cc:141
uint8_t uint8
Definition: Compat.h:34
bool peerPktDrop
Definition: SCTPAssociation.h:835
uint32 lastTsnAck
Definition: SCTPAssociation.h:614
bool inOut
Definition: SCTPAssociation.h:599
bool resetRequested
Definition: SCTPAssociation.h:590
uint32 sackFrequency
Definition: SCTPAssociation.h:949
Definition: SCTPAssociation.h:63
uint32 localVTag
Definition: SCTPAssociation.h:915
Definition: SCTPAssociation.h:111
int32 getOutstandingBytes() const
Definition: SCTPAssociationUtil.cc:2721
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
void sendShutdown()
Definition: SCTPAssociationUtil.cc:1128
SCTPMessage * sctpmsg
Definition: SCTPAssociation.h:658
uint32 lastTsnReceived
Definition: SCTPAssociation.h:616
Definition: SCTPAssociation.h:77
void stopTimers()
Definition: SCTPAssociationRcvMessage.cc:3623
Definition: SCTPAssociation.h:127
Definition: SCTPAssociation.h:118
SCTPEventCode processSackArrived(SCTPSackChunk *sackChunk)
Definition: SCTPAssociationRcvMessage.cc:1003
SCTPEventCode
Definition: SCTPAssociation.h:71
Definition: SCTPAssociation.h:119
SCTPAsconfChunk * asconfChunk
Definition: SCTPAssociation.h:782
void resetExpectedSsns()
Definition: SCTPAssociationStreamReset.cc:845
bool stopReading
Definition: SCTPAssociation.h:598
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
Definition: SCTPAssociation.h:121
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
Definition: SCTPAssociation.h:125
Definition: SCTPCommand.h:67
Definition: SCTPAssociation.h:85
SCTPEventCode processHeartbeatAckArrived(SCTPHeartbeatAckChunk *heartbeatack, SCTPPathVariables *path)
Definition: SCTPAssociationRcvMessage.cc:2297
void checkStreamsToReset()
Definition: SCTPAssociationStreamReset.cc:40
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
bool processPacketDropArrived(SCTPPacketDropChunk *pktdrop)
Definition: SCTPAssociationRcvMessage.cc:3374
Definition: SCTPAssociation.h:122
Definition: SCTPAssociation.h:60
bool pktDropSent
Definition: SCTPAssociation.h:834
void retransmitCookieEcho()
Definition: SCTPAssociationUtil.cc:955
uint32 inRequestSn
Definition: SCTPAssociation.h:796
Definition: SCTPAssociation.h:115
bool sackAllowed
Definition: SCTPAssociation.h:586
bool pktdrop
Definition: SCTP.h:212
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
uint16 sendResponse
Definition: SCTPAssociation.h:642
Definition: SCTPAssociation.h:116
Definition: SCTPAssociation.h:64
Definition: SCTPAssociation.h:58
Definition: SCTPAssociation.h:93
SCTPPathVariables * getPrimaryPath() const
Definition: SCTPAssociation.h:558
void disposeOf(SCTPMessage *sctpmsg)
Definition: SCTPAssociationUtil.cc:2800
void sendHeartbeatAck(const SCTPHeartbeatChunk *heartbeatChunk, const L3Address &src, const L3Address &dest)
Definition: SCTPAssociationUtil.cc:1001
Definition: SCTPAssociation.h:130
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
bool sackAlreadySent
Definition: SCTPAssociation.h:587
void dequeueAckedChunks(const uint32 tsna, SCTPPathVariables *path, simtime_t &rttEstimation)
Definition: SCTPAssociationRcvMessage.cc:2058
void scheduleSack()
Definition: SCTPAssociationUtil.cc:1258
cMessage * T5_ShutdownGuardTimer
Definition: SCTPAssociation.h:921
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
Definition: SCTPAssociation.h:74
SCTPShutdownAckChunk * shutdownAckChunk
Definition: SCTPAssociation.h:657
uint8_t dacPacketsRcvd
Definition: SCTPAssociation.h:933
void sendAddOutgoingStreamsRequest(uint16 numStreams)
Definition: SCTPAssociationStreamReset.cc:614
uint32 lastTsnBeforeReset
Definition: SCTPAssociation.h:798
bool processCookieEchoArrived(SCTPCookieEchoChunk *cookieEcho, L3Address addr)
Definition: SCTPAssociationRcvMessage.cc:844
void sendOutgoingRequestAndResponse(uint32 inRequestSn, uint32 outRequestSn)
Definition: SCTPAssociationStreamReset.cc:383
SCTP * sctpMain
Definition: SCTPAssociation.h:962
uint32 ackState
Definition: SCTPAssociation.h:618
Definition: SCTPAssociation.h:62
Definition: SCTPAssociation.h:124
SCTPEventCode processDataArrived(SCTPDataChunk *dataChunk)
Definition: SCTPAssociationRcvMessage.cc:2139
Definition: SCTPAssociation.h:128
uint32 peerVTag
Definition: SCTPAssociation.h:916
simtime_t initRexmitTimeout
Definition: SCTPAssociation.h:650
bool processInitArrived(SCTPInitChunk *initChunk, int32 sport, int32 dport)
Process incoming SCTP packets.
Definition: SCTPAssociationRcvMessage.cc:560
SCTPGapList gapList
Definition: SCTPAssociation.h:619
L3Address remoteAddr
Definition: SCTPAssociation.h:911
SCTPEventCode processForwardTsnArrived(SCTPForwardTsnChunk *forChunk)
Definition: SCTPAssociationRcvMessage.cc:2098
Definition: SCTPCommand.h:75
void removeAssociation(SCTPAssociation *assoc)
Definition: SCTP.cc:799
Definition: SCTPAssociation.h:112
Definition: SCTPAssociation.h:86
AssocStatMap assocStatMap
Definition: SCTP.h:171
Definition: SCTPAssociation.h:84
Definition: SCTPCommand.h:66
cMessage * T2_ShutdownTimer
Definition: SCTPAssociation.h:920
Definition: SCTPAssociation.h:83
SCTPEventCode processAsconfArrived(SCTPAsconfChunk *asconfChunk)
Definition: SCTPAssociationRcvMessage.cc:3141
QueueCounter qCounter
Definition: SCTPAssociation.h:965
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
void retransmitInit()
Retransmitting chunks.
Definition: SCTPAssociationUtil.cc:712
uint16 numResetRequests
Definition: SCTPAssociation.h:644
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
Definition: SCTPAssociation.h:59
simtime_t lastAssocThroughputTime
Definition: SCTPAssociation.h:850
Definition: SCTPAssociation.h:95
SCTPEventCode processStreamResetArrived(SCTPStreamResetChunk *strResChunk)
Definition: SCTPAssociationRcvMessage.cc:2796
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
SCTPParameter * incomingRequest
Definition: SCTPAssociation.h:800
Definition: SCTPAssociation.h:164
Definition: SCTPAssociation.h:114
Definition: SCTPAssociation.h:61
Definition: SCTPCommand.h:72
void processErrorArrived(SCTPErrorChunk *error)
Definition: SCTPAssociationRcvMessage.cc:3482
void sendPacketDrop(const bool flag)
Definition: SCTPAssociationUtil.cc:1187
L3Address localAddr
Definition: SCTPAssociation.h:912
bool processInitAckArrived(SCTPInitAckChunk *initAckChunk)
Definition: SCTPAssociationRcvMessage.cc:759
uint32 getHighestTSNReceived() const
Definition: SCTPGapList.h:96
void sendSack()
Definition: SCTPAssociationUtil.cc:1764
Definition: SCTPAssociation.h:129
void sendAbort(uint16 tBit=0)
Definition: SCTPAssociationUtil.cc:1101
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
Definition: SCTPAssociation.h:120
int32 assocId
Definition: SCTPAssociation.h:908
Definition: SCTPAssociation.h:117
uint32 getQueueSize() const
Definition: SCTPQueue.cc:60
bool peerAuth
Definition: SCTPAssociation.h:821
SCTPShutdownChunk * shutdownChunk
pointer to the resetChunk (for retransmission)
Definition: SCTPAssociation.h:656
Definition: SCTPAssociation.h:126
uint16_t uint16
Definition: Compat.h:32
cOutVector * assocThroughputVector
Definition: SCTPAssociation.h:929
SCTPEventCode processAsconfAckArrived(SCTPAsconfAckChunk *asconfAckChunk)
Definition: SCTPAssociationRcvMessage.cc:3272
cFSM * fsm
Definition: SCTPAssociation.h:963
void sendHMacError(const uint16 id)
Definition: SCTPAssociationUtil.cc:1832
Definition: SCTPAssociation.h:163
Definition: SCTPAssociation.h:57
Definition: SCTPAssociation.h:144
void sendStreamResetResponse(uint32 srrsn, int result)
Definition: SCTPAssociationStreamReset.cc:763
Definition: SCTPAssociation.h:82
uint32 assocThroughput
Definition: SCTPAssociation.h:851
void sendShutdownComplete()
Definition: SCTPAssociationUtil.cc:1084
Definition: SCTPAssociation.h:113
bool performStateTransition(const SCTPEventCode &event)
Implemements the pure SCTP state machine.
Definition: SCTPAssociationBase.cc:1182
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
bool processCookieAckArrived()
Definition: SCTPAssociationRcvMessage.cc:919
uint32 responseSn
Definition: SCTPAssociation.h:643
uint32 peerRequestSn
Definition: SCTPAssociation.h:795
void sendOnAllPaths(SCTPPathVariables *firstPath)
Definition: SCTPAssociationSendAll.cc:275
Definition: SCTPAssociation.h:123
void sendShutdownAck(const L3Address &dest)
Definition: SCTPAssociationUtil.cc:1057
virtual SCTPMessage * dup() const override
Definition: SCTPMessage.h:49
double throughputInterval
Definition: SCTPAssociation.h:852
bool streamReset
Definition: SCTPAssociation.h:785
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_RECEIVE_REQUEST ( SCTPEventCode event,
SCTPCommand sctpCommand 
)
protected
305 {
306  SCTPSendInfo *sendCommand = check_and_cast<SCTPSendInfo *>(sctpCommand);
307  if ((uint32)sendCommand->getSid() > inboundStreams || sendCommand->getSid() < 0) {
308  EV_DEBUG << "Application tries to read from invalid stream id....\n";
309  }
310  state->numMsgsReq[sendCommand->getSid()] += sendCommand->getNumMsgs();
311  pushUlp();
312 }
uint32 inboundStreams
Definition: SCTPAssociation.h:942
std::vector< int32 > numMsgsReq
Definition: SCTPAssociation.h:646
uint32_t uint32
Definition: Compat.h:30
void pushUlp()
Definition: SCTPAssociationUtil.cc:1887
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_SEND ( SCTPEventCode event,
SCTPCommand sctpCommand,
cMessage *  msg 
)
protected
127 {
128  SCTPSendInfo *sendCommand = check_and_cast<SCTPSendInfo *>(sctpCommand);
129 
130  if (fsm->getState() != SCTP_S_ESTABLISHED) {
131  // TD 12.03.2009: since SCTP_S_ESTABLISHED is the only case, the
132  // switch(...)-block has been removed for enhanced readability.
133  EV_DEBUG << "process_SEND: state is not SCTP_S_ESTABLISHED -> returning" << endl;
134  return;
135  }
136 
137  EV_DEBUG << "process_SEND:"
138  << " assocId=" << assocId
139  << " localAddr=" << localAddr
140  << " remoteAddr=" << remoteAddr
141  << " cmdRemoteAddr=" << sendCommand->getRemoteAddr()
142  << " cmdPrimary=" << (sendCommand->getPrimary() ? "true" : "false")
143  << " appGateIndex=" << appGateIndex
144  << " streamId=" << sendCommand->getSid() << endl;
145 
146  SCTPSimpleMessage *smsg = check_and_cast<SCTPSimpleMessage *>((PK(msg)->decapsulate()));
147  auto iter = sctpMain->assocStatMap.find(assocId);
148  iter->second.sentBytes += smsg->getByteLength();
149 
150  // ------ Prepare SCTPDataMsg -----------------------------------------
151  const uint32 streamId = sendCommand->getSid();
152  const uint32 sendUnordered = sendCommand->getSendUnordered();
153  const uint32 ppid = sendCommand->getPpid();
154  SCTPSendStream *stream = nullptr;
155  auto associter = sendStreams.find(streamId);
156  if (associter != sendStreams.end()) {
157  stream = associter->second;
158  }
159  else {
160  throw cRuntimeError("Stream with id %d not found", streamId);
161  }
162 
163  char name[64];
164  snprintf(name, sizeof(name), "SDATA-%d-%d", streamId, state->msgNum);
165  smsg->setName(name);
166 
167  SCTPDataMsg *datMsg = new SCTPDataMsg();
168  datMsg->encapsulate(smsg);
169  datMsg->setSid(streamId);
170  datMsg->setPpid(ppid);
171  datMsg->setEnqueuingTime(simTime());
172  datMsg->setSackNow(sendCommand->getSackNow());
173 
174  // ------ PR-SCTP & Drop messages to free buffer space ----------------
175  datMsg->setPrMethod(sendCommand->getPrMethod());
176  switch (sendCommand->getPrMethod()) {
177  case PR_TTL:
178  if (sendCommand->getPrValue() > 0) {
179  datMsg->setExpiryTime(simTime() + sendCommand->getPrValue());
180  }
181  break;
182 
183  case PR_RTX:
184  datMsg->setRtx((uint32)sendCommand->getPrValue());
185  break;
186 
187  case PR_PRIO:
188  datMsg->setPriority((uint32)sendCommand->getPrValue());
189  state->queuedDroppableBytes += PK(msg)->getByteLength();
190  break;
191  }
192 
193  if ((state->appSendAllowed) &&
194  (state->sendQueueLimit > 0) &&
195  (state->queuedDroppableBytes > 0) &&
197  {
198  uint32 lowestPriority;
199  cQueue *strq;
200  int64 dropsize = state->sendBuffer - state->sendQueueLimit;
201 
202  if (sendUnordered)
203  strq = stream->getUnorderedStreamQ();
204  else
205  strq = stream->getStreamQ();
206 
207  while (dropsize >= 0 && state->queuedDroppableBytes > 0) {
208  lowestPriority = 0;
209 
210  // Find lowest priority
211  for (cQueue::Iterator iter(*strq); !iter.end(); iter++) {
212  SCTPDataMsg *msg = (SCTPDataMsg *)(*iter);
213 
214  if (msg->getPriority() > lowestPriority)
215  lowestPriority = msg->getPriority();
216  }
217 
218  // If just passed message has the lowest priority,
219  // drop it and we're done.
220  if (datMsg->getPriority() > lowestPriority) {
221  EV_DEBUG << "msg will be abandoned, buffer is full and priority too low ("
222  << datMsg->getPriority() << ")\n";
223  state->queuedDroppableBytes -= PK(msg)->getByteLength();
224  delete smsg;
225  delete msg;
227  return;
228  }
229  }
230  }
231 
232  // ------ Set initial destination address -----------------------------
233  if (sendCommand->getPrimary()) {
234  if (sendCommand->getRemoteAddr().isUnspecified()) {
235  datMsg->setInitialDestination(remoteAddr);
236  }
237  else {
238  datMsg->setInitialDestination(sendCommand->getRemoteAddr());
239  }
240  }
241  else {
242  datMsg->setInitialDestination(state->getPrimaryPathIndex());
243  }
244 
245  // ------ Optional padding and size calculations ----------------------
246  if (state->padding) {
247  datMsg->setBooksize(ADD_PADDING(smsg->getByteLength() + state->header));
248  }
249  else {
250  datMsg->setBooksize(smsg->getByteLength() + state->header);
251  }
252 
254  qCounter.bookedSumSendStreams += datMsg->getBooksize();
255  // Add chunk size to sender buffer size
256  state->sendBuffer += smsg->getByteLength();
257 
258  datMsg->setMsgNum(++state->msgNum);
259 
260  // ------ Ordered/Unordered modes -------------------------------------
261  if (sendUnordered == 1) {
262  datMsg->setOrdered(false);
263  stream->getUnorderedStreamQ()->insert(datMsg);
264  }
265  else {
266  datMsg->setOrdered(true);
267  stream->getStreamQ()->insert(datMsg);
268 
269  sendQueue->record(stream->getStreamQ()->getLength());
270  }
271 
272  // ------ Send buffer full? -------------------------------------------
273  if ((state->appSendAllowed) &&
274  (state->sendQueueLimit > 0) &&
276  // If there are not enough messages that could be dropped,
277  // the buffer is really full and the app has to be notified.
280  state->appSendAllowed = false;
281  }
282  }
283 
285  if ((state->queueLimit > 0) && (state->queuedMessages > state->queueLimit)) {
286  state->queueUpdate = false;
287  }
288  EV_DEBUG << "process_SEND:"
289  << " last=" << sendCommand->getLast()
290  << " queueLimit=" << state->queueLimit << endl;
291 
292  // ------ Call sendCommandInvoked() to send message -------------------
293  // sendCommandInvoked() itself will call sendOnAllPaths() ...
294  if (sendCommand->getLast() == true) {
295  if (sendCommand->getPrimary()) {
297  }
298  else {
299  sctpAlgorithm->sendCommandInvoked(getPath(datMsg->getInitialDestination()));
300  }
301  }
302 }
uint64 sendQueueLimit
Definition: SCTPAssociation.h:659
uint32 queueLimit
Definition: SCTPAssociation.h:640
Definition: SCTPAssociation.h:138
Definition: SCTPCommand.h:76
Definition: SCTPAssociation.h:137
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
Definition: SCTPAssociation.h:60
cOutVector * sendQueue
Definition: SCTPAssociation.h:956
virtual void sendCommandInvoked(SCTPPathVariables *path)=0
bool padding
Definition: SCTPAssociation.h:833
uint64 sendBuffer
Definition: SCTPAssociation.h:660
Definition: SCTPAssociation.h:136
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
bool queueUpdate
Definition: SCTPAssociation.h:593
uint64 queuedMessages
Definition: SCTPAssociation.h:638
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
SCTP * sctpMain
Definition: SCTPAssociation.h:962
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
uint64 bookedSumSendStreams
Definition: SCTPAssociation.h:876
L3Address remoteAddr
Definition: SCTPAssociation.h:911
uint32 msgNum
Definition: SCTPAssociation.h:629
uint64_t uint64
Definition: Compat.h:28
AssocStatMap assocStatMap
Definition: SCTP.h:171
const L3Address & getPrimaryPathIndex() const
Definition: SCTPAssociation.h:550
QueueCounter qCounter
Definition: SCTPAssociation.h:965
uint32_t uint32
Definition: Compat.h:30
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
L3Address localAddr
Definition: SCTPAssociation.h:912
bool appSendAllowed
Definition: SCTPAssociation.h:661
uint16 header
Definition: SCTPAssociation.h:641
Definition: SCTPCommand.h:78
#define PK(msg)
Definition: INETDefs.h:92
int32 assocId
Definition: SCTPAssociation.h:908
SCTPAlgorithm * sctpAlgorithm
Definition: SCTPAssociation.h:970
int32 appGateIndex
Definition: SCTPAssociation.h:907
cFSM * fsm
Definition: SCTPAssociation.h:963
int64_t int64
Definition: Compat.h:29
uint64 queuedDroppableBytes
Definition: SCTPAssociation.h:624
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_STATUS ( SCTPEventCode event,
SCTPCommand sctpCommand,
cMessage *  msg 
)
protected
423 {
424  SCTPStatusInfo *statusInfo = new SCTPStatusInfo();
425  statusInfo->setState(fsm->getState());
426  statusInfo->setStateName(stateName(fsm->getState()));
427  statusInfo->setPathId(remoteAddr);
428  statusInfo->setActive(getPath(remoteAddr)->activePath);
429  msg->setControlInfo(statusInfo);
430  sendToApp(msg);
431 }
static const char * stateName(const int32 state)
Utility: returns name of SCTP_S_xxx constants.
Definition: SCTPAssociationUtil.cc:141
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
L3Address remoteAddr
Definition: SCTPAssociation.h:911
void sendToApp(cMessage *msg)
Utility: sends packet to application.
Definition: SCTPAssociationUtil.cc:457
cFSM * fsm
Definition: SCTPAssociation.h:963
void inet::sctp::SCTPAssociation::process_STREAM_RESET ( SCTPCommand sctpCommand)
protected
321 {
322  EV_DEBUG << "process_STREAM_RESET request arriving from App\n";
323  SCTPResetInfo *rinfo = check_and_cast<SCTPResetInfo *>(sctpCommand);
324  if (!(getPath(remoteAddr)->ResetTimer->isScheduled())) {
325  if (rinfo->getRequestType() == ADD_BOTH) {
327  } else if (!state->fragInProgress && state->outstandingBytes == 0) {
328  sendStreamResetRequest(rinfo);
329  if (rinfo->getRequestType() == RESET_OUTGOING || rinfo->getRequestType() == RESET_BOTH ||
330  rinfo->getRequestType() == SSN_TSN || rinfo->getRequestType() == ADD_INCOMING ||
331  rinfo->getRequestType() == ADD_OUTGOING) {
332  state->resetPending = true;
333  }
334  } else if (state->outstandingBytes > 0) {
335  if (rinfo->getRequestType() == RESET_OUTGOING || rinfo->getRequestType() == RESET_INCOMING) {
336  if (rinfo->getStreamsArraySize() > 0) {
337  for (uint16 i = 0; i < rinfo->getStreamsArraySize(); i++) {
338  if ((getBytesInFlightOfStream(rinfo->getStreams(i)) > 0) ||
339  getFragInProgressOfStream(rinfo->getStreams(i)) ||
340  !orderedQueueEmptyOfStream(rinfo->getStreams(i)) ||
341  !unorderedQueueEmptyOfStream(rinfo->getStreams(i))) {
342  state->streamsPending.push_back(rinfo->getStreams(i));
343  } else {
344  state->streamsToReset.push_back(rinfo->getStreams(i));
345  }
346  }
347  } else {
348  if (rinfo->getRequestType() == RESET_OUTGOING) {
349  for (uint16 i = 0; i < outboundStreams; i++) {
351  state->streamsPending.push_back(i);
352  } else {
353  state->streamsToReset.push_back(i);
354  }
355  }
356  }
357  }
358  if (state->streamsToReset.size() > 0) {
359  sendStreamResetRequest(rinfo);
360  state->resetPending = true;
361  }
362  }
363  if ((rinfo->getRequestType() == SSN_TSN) ||
364  (rinfo->getRequestType() == ADD_INCOMING) ||
365  (rinfo->getRequestType() == ADD_OUTGOING)) {
366  state->resetInfo = rinfo;
367  state->resetInfo->setName("state-resetLater");
369  }
370  if (!state->resetPending || state->streamsPending.size() > 0) {
371  state->resetInfo = rinfo->dup();
372  state->resetInfo->setName("state-resetInfo");
374  }
375  }
376 
377  state->resetRequested = true;
378  }
379 }
bool resetRequested
Definition: SCTPAssociation.h:590
bool fragInProgress
Definition: SCTPAssociation.h:601
bool orderedQueueEmptyOfStream(uint16 sid)
Definition: SCTPAssociationUtil.cc:85
uint32 getBytesInFlightOfStream(uint16 sid)
Definition: SCTPAssociationUtil.cc:78
Definition: SCTPAssociation.h:155
bool unorderedQueueEmptyOfStream(uint16 sid)
Definition: SCTPAssociationUtil.cc:92
bool getFragInProgressOfStream(uint16 sid)
Definition: SCTPAssociationUtil.cc:100
virtual unsigned short getRequestType() const
void sendStreamResetRequest(SCTPResetInfo *info)
Definition: SCTPAssociationStreamReset.cc:483
SCTPResetInfo * resetInfo
Definition: SCTPAssociation.h:808
uint16 localRequestType
Definition: SCTPAssociation.h:810
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
uint32 outboundStreams
Definition: SCTPAssociation.h:943
Definition: SCTPAssociation.h:150
std::list< uint16 > streamsPending
Definition: SCTPAssociation.h:803
L3Address remoteAddr
Definition: SCTPAssociation.h:911
uint64 outstandingBytes
Definition: SCTPAssociation.h:622
Definition: SCTPAssociation.h:152
Definition: SCTPAssociation.h:151
void sendAddInAndOutStreamsRequest(SCTPResetInfo *info)
Definition: SCTPAssociationStreamReset.cc:664
virtual SCTPResetInfo * dup() const override
Definition: SCTPCommand_m.h:657
Definition: SCTPAssociation.h:162
Definition: SCTPAssociation.h:153
std::list< uint16 > streamsToReset
Definition: SCTPAssociation.h:804
bool resetPending
Definition: SCTPAssociation.h:589
uint16_t uint16
Definition: Compat.h:32
Definition: SCTPAssociation.h:154
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_TIMEOUT_ASCONF ( SCTPPathVariables path)
protected
3706 {
3707  int32 value;
3708 
3709  if ((value = updateCounters(path)) == 1) {
3710  retransmitAsconf();
3711 
3712  /* increase the RTO (by doubling it) */
3713  path->pathRto = min(2 * path->pathRto.dbl(), sctpMain->getRtoMax());
3714  path->statisticsPathRTO->record(path->pathRto);
3715 
3716  startTimer(path->AsconfTimer, path->pathRto);
3717  }
3718 }
int32 updateCounters(SCTPPathVariables *path)
Definition: SCTPAssociationRcvMessage.cc:3667
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void retransmitAsconf()
Definition: SCTPAssociationAddIP.cc:167
int32_t int32
Definition: Compat.h:31
double getRtoMax()
Definition: SCTP.h:271
void inet::sctp::SCTPAssociation::process_TIMEOUT_BLOCKING ( SCTPPathVariables path)
protected
3851 {
3852  std::cout << "TIMEOUT_BLOCKING on " << path->remoteAddress
3853  << " cwnd=" << path->cwnd << endl;
3854  path->blockingTimeout = -1.0;
3855  sendOnAllPaths(path);
3856 }
void sendOnAllPaths(SCTPPathVariables *firstPath)
Definition: SCTPAssociationSendAll.cc:275
void inet::sctp::SCTPAssociation::process_TIMEOUT_HEARTBEAT ( SCTPPathVariables path)
protected
3578 {
3579  bool oldState = path->activePath;
3580 
3581  /* check if error counters must be increased */
3582  if (path->activePath) {
3583  state->errorCount++;
3584  path->pathErrorCount++;
3585 
3586  EV_INFO << "HB timeout timer expired for path " << path->remoteAddress << " --> Increase Error Counters (Assoc: " << state->errorCount << ", Path: " << path->pathErrorCount << ")\n";
3587  }
3588 
3589  /* RTO must be doubled for this path ! */
3590  path->pathRto = (simtime_t)min(2 * path->pathRto.dbl(), sctpMain->getRtoMax());
3591  path->statisticsPathRTO->record(path->pathRto);
3592  /* check if any thresholds are exceeded, and if so, check if ULP must be notified */
3595  sendAbort();
3596  sctpMain->removeAssociation(this);
3597  return;
3598  }
3599  else {
3600  /* set path state to INACTIVE, if the path error counter is exceeded */
3601  if (path->pathErrorCount > (uint32)sctpMain->getPathMaxRetrans()) {
3602  oldState = path->activePath;
3603  path->activePath = false;
3604  if (path == state->getPrimaryPath()) {
3606  }
3607  EV_DETAIL << "pathErrorCount now " << path->pathErrorCount
3608  << "; PP now " << state->getPrimaryPathIndex() << endl;
3609  }
3610  /* then: we can check, if all paths are INACTIVE ! */
3611  if (allPathsInactive()) {
3612  EV_DETAIL << "sctp_do_hb_to_timer() : ALL PATHS INACTIVE --> closing ASSOC\n";
3614  return;
3615  }
3616  else if (path->activePath == false && oldState == true) { //FIXME oldState may be uninitialized
3617  /* notify the application, in case the PATH STATE has changed from ACTIVE to INACTIVE */
3618  pathStatusIndication(path, false);
3619  }
3620  }
3621 }
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
int getPathMaxRetrans()
Definition: SCTP.h:278
SCTPPathVariables * getPrimaryPath() const
Definition: SCTPAssociation.h:558
uint32 errorCount
Definition: SCTPAssociation.h:609
Definition: SCTPCommand.h:73
int getAssocMaxRtx()
Definition: SCTP.h:279
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void removeAssociation(SCTPAssociation *assoc)
Definition: SCTP.cc:799
void pathStatusIndication(const SCTPPathVariables *path, const bool status)
Definition: SCTPAssociationUtil.cc:2743
const L3Address & getPrimaryPathIndex() const
Definition: SCTPAssociation.h:550
uint32_t uint32
Definition: Compat.h:30
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
SCTPPathVariables * getNextPath(const SCTPPathVariables *oldPath) const
Definition: SCTPAssociationUtil.cc:2594
void sendAbort(uint16 tBit=0)
Definition: SCTPAssociationUtil.cc:1101
void setPrimaryPath(SCTPPathVariables *path)
Definition: SCTPAssociation.h:545
double getRtoMax()
Definition: SCTP.h:271
bool allPathsInactive() const
Definition: SCTPAssociationUtil.cc:2790
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_TIMEOUT_HEARTBEAT_INTERVAL ( SCTPPathVariables path,
bool  force 
)
protected
3560 {
3561  EV_INFO << "HB Interval timer expired -- sending new HB REQ on path " << path->remoteAddress << "\n";
3562  /* restart hb_send_timer on this path */
3563  stopTimer(path->HeartbeatIntervalTimer);
3564  stopTimer(path->HeartbeatTimer);
3565  path->heartbeatIntervalTimeout = (double)sctpMain->getHbInterval() + path->pathRto;
3566  path->heartbeatTimeout = path->pathRto;
3567  startTimer(path->HeartbeatIntervalTimer, path->heartbeatIntervalTimeout);
3568 
3569  if (sctpMain->getEnableHeartbeats() && (simTime() - path->lastAckTime > path->heartbeatIntervalTimeout / 2 || path->forceHb || state->sendHeartbeatsOnActivePaths)) {
3570  sendHeartbeat(path);
3571  startTimer(path->HeartbeatTimer, path->heartbeatTimeout);
3572 
3573  path->forceHb = false;
3574  }
3575 }
bool sendHeartbeatsOnActivePaths
Definition: SCTPAssociation.h:667
bool getEnableHeartbeats()
Definition: SCTP.h:277
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
double getHbInterval()
Definition: SCTP.h:280
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void sendHeartbeat(const SCTPPathVariables *path)
Definition: SCTPAssociationUtil.cc:977
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_TIMEOUT_INIT_REXMIT ( SCTPEventCode event)
protected
3509 {
3511  EV_INFO << "Retransmission count during connection setup exceeds " << (int32)sctpMain->getMaxInitRetrans() << ", giving up\n";
3513  sendAbort();
3514  return;
3515  }
3516  EV_INFO << "Performing retransmission #" << state->initRetransCounter << "\n";
3517  switch (fsm->getState()) {
3518  case SCTP_S_COOKIE_WAIT:
3519  retransmitInit();
3520  break;
3521 
3522  case SCTP_S_COOKIE_ECHOED:
3524  break;
3525 
3526  default:
3527  throw cRuntimeError("Internal error: INIT-REXMIT timer expired while in state %s",
3528  stateName(fsm->getState()));
3529  }
3530  state->initRexmitTimeout *= 2;
3533  }
3535 }
static const char * stateName(const int32 state)
Utility: returns name of SCTP_S_xxx constants.
Definition: SCTPAssociationUtil.cc:141
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
Definition: SCTPCommand.h:67
void retransmitCookieEcho()
Definition: SCTPAssociationUtil.cc:955
Definition: SCTPAssociation.h:58
int getMaxInitRetransTimeout()
Definition: SCTP.h:268
SCTP * sctpMain
Definition: SCTPAssociation.h:962
int getMaxInitRetrans()
Definition: SCTP.h:267
simtime_t initRexmitTimeout
Definition: SCTPAssociation.h:650
int16 initRetransCounter
Counter for init and cookie retransmissions.
Definition: SCTPAssociation.h:649
void retransmitInit()
Retransmitting chunks.
Definition: SCTPAssociationUtil.cc:712
int32_t int32
Definition: Compat.h:31
Definition: SCTPAssociation.h:59
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
void sendAbort(uint16 tBit=0)
Definition: SCTPAssociationUtil.cc:1101
cFSM * fsm
Definition: SCTPAssociation.h:963
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_TIMEOUT_PROBING ( )
protected
void inet::sctp::SCTPAssociation::process_TIMEOUT_RESET ( SCTPPathVariables path)
protected
3647 {
3648  int32 value;
3649  std::map<uint32, SCTPStateVariables::RequestData>::reverse_iterator rit;
3650  rit = state->requests.rbegin();
3651  if (rit->second.result == DEFERRED) {
3652  value = 1;
3653  } else {
3654  value = updateCounters(path);
3655  }
3656  if (value == 1) {
3657  EV_DETAIL << "Performing timeout reset" << endl;
3658  retransmitReset();
3659 
3660  /* increase the RTO (by doubling it) */
3661  path->pathRto = min(2 * path->pathRto.dbl(), sctpMain->getRtoMax());
3662  path->statisticsPathRTO->record(path->pathRto);
3663  startTimer(path->ResetTimer, path->pathRto);
3664  }
3665 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
int32 updateCounters(SCTPPathVariables *path)
Definition: SCTPAssociationRcvMessage.cc:3667
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
void retransmitReset()
Definition: SCTPAssociationStreamReset.cc:25
SCTP * sctpMain
Definition: SCTPAssociation.h:962
Definition: SCTPAssociation.h:149
int32_t int32
Definition: Compat.h:31
double getRtoMax()
Definition: SCTP.h:271
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::process_TIMEOUT_RTX ( SCTPPathVariables path)
protected
3721 {
3722  EV_DETAIL << "Processing retransmission timeout ..." << endl;
3723 
3724  // Stop blocking!
3725  if (path->BlockingTimer) {
3726  stopTimer(path->BlockingTimer);
3727  }
3728  path->blockingTimeout = -1.0;
3729 
3730  // ====== Increase the RTO (by doubling it) ==============================
3731  path->pathRto = min(2 * path->pathRto.dbl(), sctpMain->getRtoMax());
3732  path->statisticsPathRTO->record(path->pathRto);
3733  EV_DETAIL << "Schedule T3 based retransmission for path " << path->remoteAddress
3734  << " oldest chunk sent " << simTime() - path->oldestChunkSendTime << " ago"
3735  << " (TSN " << path->oldestChunkTSN << ")" << endl;
3736  EV_DEBUG << "Unacked chunks in Retransmission Queue:" << endl;
3737  for (SCTPQueue::PayloadQueue::const_iterator iterator = retransmissionQ->payloadQueue.begin();
3738  iterator != retransmissionQ->payloadQueue.end(); ++iterator)
3739  {
3740  const SCTPDataVariables *myChunk = iterator->second;
3741  if (!myChunk->hasBeenAcked) {
3742  const SCTPPathVariables *myChunkLastPath = myChunk->getLastDestinationPath();
3743  EV_DEBUG << " - " << myChunk->tsn
3744  << "\tsent=now-" << simTime() - myChunk->sendTime
3745  << "\tlast=" << myChunkLastPath->remoteAddress
3746  << "\tmoved=" << ((myChunk->hasBeenMoved == true) ? "YES!" : "no")
3747  << "\tnumTX=" << myChunk->numberOfTransmissions
3748  << "\tnumRTX=" << myChunk->numberOfRetransmissions
3749  << "\tfastRTX=" << ((myChunk->hasBeenFastRetransmitted == true) ? "YES!" : "no")
3750  << endl;
3751  }
3752  }
3753  EV_DEBUG << "----------------------" << endl;
3754 
3755  // ====== Update congestion window =======================================
3756  (this->*ccFunctions.ccUpdateAfterRtxTimeout)(path);
3757 
3758  // ====== Error Counter Handling =========================================
3759  if (!state->zeroWindowProbing) {
3760  state->errorCount++;
3761  path->pathErrorCount++;
3762  EV_DETAIL << "RTX-Timeout: errorCount increased to " << path->pathErrorCount << " state->errorCount=" << state->errorCount << "\n";
3763  }
3765  /* error counter exceeded terminate the association -- create an SCTPC_EV_CLOSE event and send it to myself */
3766 
3767  EV_DETAIL << "process_TIMEOUT_RTX : ASSOC ERROR COUNTER EXCEEDED, closing ASSOC" << endl;
3769  sendAbort();
3770  sctpMain->removeAssociation(this);
3771  return;
3772  }
3773  else {
3774  if (path->pathErrorCount > (uint32)sctpMain->par("pathMaxRetrans")) {
3775  bool notifyUlp = false;
3776 
3777  EV_DETAIL << "pathErrorCount exceeded\n";
3778  if (path->activePath) {
3779  /* tell the source */
3780  notifyUlp = true;
3781  }
3782  path->activePath = false;
3783  if (path->remoteAddress == state->getPrimaryPathIndex()) {
3784  SCTPPathVariables *nextPath = getNextPath(path);
3785  if (nextPath != nullptr) {
3786  state->setPrimaryPath(nextPath);
3787  }
3788  }
3789  EV_DETAIL << "process_TIMEOUT_RTX(" << path->remoteAddress
3790  << ") : PATH ERROR COUNTER EXCEEDED, path status is INACTIVE" << endl;
3791  if (allPathsInactive()) {
3792  EV_WARN << "process_TIMEOUT_RTX: ALL PATHS INACTIVE --> connection LOST!" << endl;
3794  sendAbort();
3795  sctpMain->removeAssociation(this);
3796  return;
3797  }
3798  else if (notifyUlp) {
3799  // Send notification to the application
3800  pathStatusIndication(path, false);
3801  }
3802  }
3803  EV_DETAIL << "process_TIMEOUT_RTX(" << path->remoteAddress
3804  << ") : PATH ERROR COUNTER now " << path->pathErrorCount << endl;
3805  }
3806 
3807  // ====== Do Retransmission ==============================================
3808  // dequeue all chunks not acked so far and put them in the TransmissionQ
3809  if (!retransmissionQ->payloadQueue.empty()) {
3810  EV_DETAIL << "Still " << retransmissionQ->payloadQueue.size()
3811  << " chunks in retransmissionQ" << endl;
3812 
3813  for (auto & elem : retransmissionQ->payloadQueue)
3814  {
3815  SCTPDataVariables *chunk = elem.second;
3816  assert(chunk != nullptr);
3817 
3818  // ====== Insert chunks into TransmissionQ ============================
3819  // Only insert chunks that were sent to the path that has timed out
3820  if (!chunkMustBeAbandoned(chunk, path) && ((chunkHasBeenAcked(chunk) == false && chunk->countsAsOutstanding)
3821  || chunk->hasBeenReneged) && (chunk->getLastDestinationPath() == path))
3822  {
3823  SCTPPathVariables *nextPath = getNextDestination(chunk);
3824  EV_DETAIL << simTime() << ": Timer-Based RTX for TSN " << chunk->tsn
3825  << ": lastDestination=" << chunk->getLastDestination()
3826  << " lastPathRTO=" << chunk->getLastDestinationPath()->pathRto
3827  << " nextDestination=" << nextPath->remoteAddress
3828  << " nextPathRTO=" << nextPath->pathRto
3829  << " waiting=" << simTime() - chunk->sendTime
3830  << endl;
3831  nextPath->numberOfTimerBasedRetransmissions++;
3832  chunk->hasBeenTimerBasedRtxed = true;
3833  chunk->sendForwardIfAbandoned = true;
3834 
3835  if (!chunk->hasBeenAbandoned) {
3836  auto iter = sctpMain->assocStatMap.find(assocId);
3837  iter->second.numT3Rtx++;
3838  }
3839 
3840  moveChunkToOtherPath(chunk, nextPath);
3841  }
3842  }
3843  }
3844 
3845  SCTPPathVariables *nextPath = getNextPath(path);
3846  EV_DETAIL << "TimeoutRTX: sendOnAllPaths()" << endl;
3847  sendOnAllPaths(nextPath);
3848 }
bool zeroWindowProbing
Definition: SCTPAssociation.h:582
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
SCTPPathVariables * getNextDestination(SCTPDataVariables *chunk) const
Definition: SCTPAssociationUtil.cc:2618
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
uint32 errorCount
Definition: SCTPAssociation.h:609
Definition: SCTPCommand.h:73
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
int getAssocMaxRtx()
Definition: SCTP.h:279
SCTP * sctpMain
Definition: SCTPAssociation.h:962
CCFunctions ccFunctions
Definition: SCTPAssociation.h:951
void removeAssociation(SCTPAssociation *assoc)
Definition: SCTP.cc:799
void pathStatusIndication(const SCTPPathVariables *path, const bool status)
Definition: SCTPAssociationUtil.cc:2743
AssocStatMap assocStatMap
Definition: SCTP.h:171
void(SCTPAssociation::* ccUpdateAfterRtxTimeout)(SCTPPathVariables *path)
Definition: SCTPAssociation.h:894
const L3Address & getPrimaryPathIndex() const
Definition: SCTPAssociation.h:550
uint32_t uint32
Definition: Compat.h:30
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
SCTPPathVariables * getNextPath(const SCTPPathVariables *oldPath) const
Definition: SCTPAssociationUtil.cc:2594
void sendAbort(uint16 tBit=0)
Definition: SCTPAssociationUtil.cc:1101
bool chunkMustBeAbandoned(SCTPDataVariables *chunk, SCTPPathVariables *sackPath)
Definition: SCTPAssociationUtil.cc:2265
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
void moveChunkToOtherPath(SCTPDataVariables *chunk, SCTPPathVariables *newPath)
Definition: SCTPAssociationRcvMessage.cc:3858
int32 assocId
Definition: SCTPAssociation.h:908
void setPrimaryPath(SCTPPathVariables *path)
Definition: SCTPAssociation.h:545
double getRtoMax()
Definition: SCTP.h:271
void sendOnAllPaths(SCTPPathVariables *firstPath)
Definition: SCTPAssociationSendAll.cc:275
bool allPathsInactive() const
Definition: SCTPAssociationUtil.cc:2790
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool chunkHasBeenAcked(const SCTPDataVariables *chunk) const
Definition: SCTPAssociation.h:1448
void inet::sctp::SCTPAssociation::process_TIMEOUT_SHUTDOWN ( SCTPEventCode event)
protected
3538 {
3541  sendAbort();
3542  sctpMain->removeAssociation(this);
3543  return;
3544  }
3545 
3546  EV_INFO << "Performing shutdown retransmission. Assoc error count now " << state->errorCount << " \n";
3547  if (fsm->getState() == SCTP_S_SHUTDOWN_SENT) {
3549  }
3550  else if (fsm->getState() == SCTP_S_SHUTDOWN_ACK_SENT)
3552 
3553  state->initRexmitTimeout *= 2;
3557 }
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
Definition: SCTPAssociation.h:64
uint32 errorCount
Definition: SCTPAssociation.h:609
Definition: SCTPCommand.h:73
void retransmitShutdown()
Definition: SCTPAssociationUtil.cc:1161
int getAssocMaxRtx()
Definition: SCTP.h:279
SCTP * sctpMain
Definition: SCTPAssociation.h:962
Definition: SCTPAssociation.h:62
simtime_t initRexmitTimeout
Definition: SCTPAssociation.h:650
void removeAssociation(SCTPAssociation *assoc)
Definition: SCTP.cc:799
#define SCTP_TIMEOUT_INIT_REXMIT_MAX
Definition: SCTPAssociation.h:247
cMessage * T2_ShutdownTimer
Definition: SCTPAssociation.h:920
uint32_t uint32
Definition: Compat.h:30
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
void sendAbort(uint16 tBit=0)
Definition: SCTPAssociationUtil.cc:1101
cFSM * fsm
Definition: SCTPAssociation.h:963
void retransmitShutdownAck()
Definition: SCTPAssociationUtil.cc:1174
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::processAddInAndOutResetRequestArrived ( SCTPAddStreamsRequestParameter addInRequestParam,
SCTPAddStreamsRequestParameter addOutRequestParam 
)
protected

Referenced by processStreamResetArrived().

2698 {
2699  SCTPMessage *msg = new SCTPMessage();
2700  msg->setByteLength(SCTP_COMMON_HEADER);
2701  msg->setSrcPort(localPort);
2702  msg->setDestPort(remotePort);
2703  SCTPStreamResetChunk *resetChunk = new SCTPStreamResetChunk("AddInOut_CONFIG");
2704  resetChunk->setChunkType(RE_CONFIG);
2705  resetChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
2707  SCTPResetTimer *rt = new SCTPResetTimer();
2708  auto it = sctpMain->assocStatMap.find(assocId);
2709  SCTPAddStreamsRequestParameter *addStreams = new SCTPAddStreamsRequestParameter("Add_Streams");
2710  addStreams->setParameterType(ADD_OUTGOING_STREAMS_REQUEST_PARAMETER);
2711  addStreams->setNumberOfStreams(addInRequestParam->getNumberOfStreams());
2712  state->numAddedOutStreams = addStreams->getNumberOfStreams();
2714  addStreams->setSrReqSn(srsn);
2715  state->requests[srsn].result = 100;
2717  addStreams->setByteLength(SCTP_ADD_STREAMS_REQUEST_PARAMETER_LENGTH);
2718  resetChunk->addParameter(addStreams);
2719 
2720  SCTPStreamResetChunk *responseChunk = new SCTPStreamResetChunk("responseRE_CONFIG");
2721  responseChunk->setChunkType(RE_CONFIG);
2722  responseChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
2723  SCTPStreamResetResponseParameter *outResponseParam = new SCTPStreamResetResponseParameter("Out_Response_Param");
2724  outResponseParam->setParameterType(STREAM_RESET_RESPONSE_PARAMETER);
2725  outResponseParam->setSrResSn(addOutRequestParam->getSrReqSn());
2726  outResponseParam->setResult(PERFORMED);
2727  outResponseParam->setByteLength(SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH);
2728  responseChunk->addParameter(outResponseParam);
2729  SCTPStreamResetResponseParameter *inResponseParam = new SCTPStreamResetResponseParameter("In_Response_Param");
2730  inResponseParam->setParameterType(STREAM_RESET_RESPONSE_PARAMETER);
2731  inResponseParam->setSrResSn(addInRequestParam->getSrReqSn());
2732  inResponseParam->setResult(PERFORMED);
2733  state->peerRequests[addInRequestParam->getSrReqSn()].result = PERFORMED;
2734  state->peerRequests[addOutRequestParam->getSrReqSn()].result = PERFORMED;
2735  inResponseParam->setByteLength(SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH);
2736  responseChunk->addParameter(inResponseParam);
2737  msg->addChunk(resetChunk);
2738  msg->addChunk(responseChunk);
2739  rt->setInSN(0);
2740  rt->setInAcked(true);
2741  rt->setOutSN(srsn);
2742  rt->setOutAcked(false);
2743  it->second.numResetRequestsSent++;
2744  state->streamResetSequenceNumber = ++srsn;
2745  if (state->resetChunk != nullptr) {
2746  delete state->resetChunk;
2747  state->resetChunk = nullptr;
2748  }
2749  state->resetChunk = check_and_cast<SCTPStreamResetChunk *>(resetChunk->dup());
2750  state->resetChunk->setName("stateAddResetChunk");
2751  sendToIP(msg, remoteAddr);
2752  PK(getPath(remoteAddr)->ResetTimer)->encapsulate(rt);
2753  startTimer(getPath(remoteAddr)->ResetTimer, getPath(remoteAddr)->pathRto);
2754 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
uint32 streamResetSequenceNumber
Definition: SCTPAssociation.h:793
#define SCTP_ADD_STREAMS_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:229
Definition: SCTPAssociation.h:155
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
uint16 localRequestType
Definition: SCTPAssociation.h:810
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
Definition: SCTPAssociation.h:159
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
uint16 numAddedOutStreams
Definition: SCTPAssociation.h:672
std::map< uint32, RequestData > peerRequests
Definition: SCTPAssociation.h:807
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
#define SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH
Definition: SCTPAssociation.h:228
Definition: SCTPAssociation.h:128
L3Address remoteAddr
Definition: SCTPAssociation.h:911
AssocStatMap assocStatMap
Definition: SCTP.h:171
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
IRoutingTable * rt
Definition: SCTPAssociation.h:936
uint32_t uint32
Definition: Compat.h:30
#define PK(msg)
Definition: INETDefs.h:92
int32 assocId
Definition: SCTPAssociation.h:908
Definition: SCTPAssociation.h:144
uint16 localPort
Definition: SCTPAssociation.h:913
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::processAppCommand ( cMessage *  msg)

Process commands from the application.

Normally returns true. A return value of false means that the connection structure must be deleted by the caller (SCTP).

Referenced by inet::sctp::SCTP::handleMessage().

1080 {
1081  printAssocBrief();
1082 
1083  // first do actions
1084  SCTPCommand *sctpCommand = (SCTPCommand *)(msg->removeControlInfo());
1085  SCTPEventCode event = preanalyseAppCommandEvent(msg->getKind());
1086 
1087  EV_INFO << "App command: " << eventName(event) << "\n";
1088 
1089  switch (event) {
1090  case SCTP_E_ASSOCIATE:
1091  process_ASSOCIATE(event, sctpCommand, msg);
1092  break;
1093 
1094  case SCTP_E_OPEN_PASSIVE:
1095  process_OPEN_PASSIVE(event, sctpCommand, msg);
1096  break;
1097 
1098  case SCTP_E_SEND:
1099  process_SEND(event, sctpCommand, msg);
1100  break;
1101 
1102  case SCTP_E_ABORT:
1103  process_ABORT(event);
1104  break;
1105 
1106  case SCTP_E_RECEIVE:
1107  process_RECEIVE_REQUEST(event, sctpCommand);
1108  break;
1109 
1110  case SCTP_E_PRIMARY:
1111  process_PRIMARY(event, sctpCommand);
1112  break;
1113 
1114  case SCTP_E_STREAM_RESET:
1115  case SCTP_E_RESET_ASSOC:
1116  case SCTP_E_ADD_STREAMS:
1117  if (state->peerStreamReset == true) {
1118  process_STREAM_RESET(sctpCommand);
1119  }
1120  event = SCTP_E_IGNORE;
1121  break;
1122 
1123  case SCTP_E_SEND_ASCONF:
1124  sendAsconf(sctpMain->par("addIpType"));
1125  break;
1126 
1128  state->ssPriorityMap[((SCTPSendInfo *)sctpCommand)->getSid()] =
1129  ((SCTPSendInfo *)sctpCommand)->getPpid();
1130  break;
1131 
1133  process_QUEUE_BYTES_LIMIT(sctpCommand);
1134  break;
1135 
1137  process_QUEUE_MSGS_LIMIT(sctpCommand);
1138  break;
1139 
1140  case SCTP_E_CLOSE:
1141  if (listening) {
1142  event = SCTP_E_IGNORE;
1143  break;
1144  }
1145  state->stopReading = true;
1146  /* fall through */
1147 
1148  case SCTP_E_SHUTDOWN: /*sendShutdown*/
1149  EV_INFO << "SCTP_E_SHUTDOWN in state " << stateName(fsm->getState()) << "\n";
1150 
1151  if (fsm->getState() == SCTP_S_SHUTDOWN_RECEIVED) {
1152  EV_INFO << "send shutdown ack\n";
1154  }
1155  break;
1156 
1157  case SCTP_E_STOP_SENDING:
1158  break;
1159 
1161  break;
1162 
1163  case SCTP_E_ACCEPT:
1164  fd = sctpCommand->getFd();
1165  EV_DETAIL << "Accepted fd " << fd << " for assoc " << assocId << endl;
1166  break;
1167 
1168  case SCTP_E_SET_RTO_INFO:
1169  sctpMain->setRtoInitial(((SCTPRtoInfo *)sctpCommand)->getRtoInitial());
1170  sctpMain->setRtoMin(((SCTPRtoInfo *)sctpCommand)->getRtoMin());
1171  sctpMain->setRtoMax(((SCTPRtoInfo *)sctpCommand)->getRtoMax());
1172  break;
1173  default:
1174  throw cRuntimeError("Wrong event code");
1175  }
1176 
1177  delete sctpCommand;
1178  // then state transitions
1179  return performStateTransition(event);
1180 }
void setRtoMax(double rtoMax)
Definition: SCTP.h:283
static const char * stateName(const int32 state)
Utility: returns name of SCTP_S_xxx constants.
Definition: SCTPAssociationUtil.cc:141
void setRtoInitial(double rtoInitial)
Definition: SCTP.h:281
std::map< uint16, uint32 > ssPriorityMap
Definition: SCTPAssociation.h:856
void process_ASSOCIATE(SCTPEventCode &event, SCTPCommand *sctpCommand, cMessage *msg)
Definition: SCTPAssociationEventProc.cc:33
Definition: SCTPAssociation.h:63
Definition: SCTPAssociation.h:96
Definition: SCTPAssociation.h:97
Definition: SCTPAssociation.h:77
SCTPEventCode
Definition: SCTPAssociation.h:71
bool stopReading
Definition: SCTPAssociation.h:598
Definition: SCTPAssociation.h:75
void process_PRIMARY(SCTPEventCode &event, SCTPCommand *sctpCommand)
Definition: SCTPAssociationEventProc.cc:314
void process_QUEUE_BYTES_LIMIT(const SCTPCommand *sctpCommand)
Definition: SCTPAssociationEventProc.cc:388
void setRtoMin(double rtoMin)
Definition: SCTP.h:282
Definition: SCTPAssociation.h:107
Definition: SCTPAssociation.h:101
void process_ABORT(SCTPEventCode &event)
Definition: SCTPAssociationEventProc.cc:411
Definition: SCTPAssociation.h:74
Definition: SCTPAssociation.h:105
SCTP * sctpMain
Definition: SCTPAssociation.h:962
Definition: SCTPAssociation.h:106
Definition: SCTPAssociation.h:73
int32 fd
Definition: SCTPAssociation.h:909
L3Address remoteAddr
Definition: SCTPAssociation.h:911
Definition: SCTPAssociation.h:76
void sendAsconf(const char *type, const bool remote=false)
Methods for Add-IP and AUTH.
Definition: SCTPAssociationAddIP.cc:25
void process_OPEN_PASSIVE(SCTPEventCode &event, SCTPCommand *sctpCommand, cMessage *msg)
Definition: SCTPAssociationEventProc.cc:83
void process_SEND(SCTPEventCode &event, SCTPCommand *sctpCommand, cMessage *msg)
Definition: SCTPAssociationEventProc.cc:126
void printAssocBrief()
Utility: prints local/remote addr/port and app gate index/assocId.
Definition: SCTPAssociationUtil.cc:284
Definition: SCTPAssociation.h:104
bool peerStreamReset
Definition: SCTPAssociation.h:786
Definition: SCTPAssociation.h:103
Definition: SCTPAssociation.h:100
int32 assocId
Definition: SCTPAssociation.h:908
bool listening
Definition: SCTPAssociation.h:910
cFSM * fsm
Definition: SCTPAssociation.h:963
static const char * eventName(const int32 event)
Utility: returns name of SCTP_E_xxx constants.
Definition: SCTPAssociationUtil.cc:160
void process_STREAM_RESET(SCTPCommand *sctpCommand)
Definition: SCTPAssociationEventProc.cc:320
void process_QUEUE_MSGS_LIMIT(const SCTPCommand *sctpCommand)
Queue Management.
Definition: SCTPAssociationEventProc.cc:381
bool performStateTransition(const SCTPEventCode &event)
Implemements the pure SCTP state machine.
Definition: SCTPAssociationBase.cc:1182
Definition: SCTPAssociation.h:102
Definition: SCTPAssociation.h:92
Definition: SCTPAssociation.h:91
Definition: SCTPAssociation.h:99
Definition: SCTPAssociation.h:94
Definition: SCTPAssociation.h:72
void sendShutdownAck(const L3Address &dest)
Definition: SCTPAssociationUtil.cc:1057
void process_RECEIVE_REQUEST(SCTPEventCode &event, SCTPCommand *sctpCommand)
Definition: SCTPAssociationEventProc.cc:304
SCTPEventCode preanalyseAppCommandEvent(int32 commandCode)
Maps app command codes (msg kind of app command msgs) to SCTP_E_xxx event codes.
Definition: SCTPAssociationBase.cc:1010
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPEventCode inet::sctp::SCTPAssociation::processAsconfAckArrived ( SCTPAsconfAckChunk asconfAckChunk)
protected

Referenced by process_RCV_Message().

3273 {
3274  SCTPParameter *sctpParam;
3275  L3Address addr;
3276  SCTPAsconfChunk *sctpasconf;
3277  std::vector<uint32> errorCorrId;
3278  bool errorFound = false;
3279 
3280  sctpasconf = check_and_cast<SCTPAsconfChunk *>(state->asconfChunk->dup());
3281  if (asconfAckChunk->getSerialNumber() == sctpasconf->getSerialNumber()) {
3282  stopTimer(getPath(remoteAddr)->AsconfTimer);
3283  state->errorCount = 0;
3284  state->asconfOutstanding = false;
3286  std::vector<L3Address> remAddr = (std::vector<L3Address>)remoteAddressList;
3287  for (uint32 j = 0; j < asconfAckChunk->getAsconfResponseArraySize(); j++) {
3288  sctpParam = (SCTPParameter *)(asconfAckChunk->getAsconfResponse(j));
3289  if (sctpParam->getParameterType() == ERROR_CAUSE_INDICATION) {
3290  SCTPErrorCauseParameter *error = check_and_cast<SCTPErrorCauseParameter *>(sctpParam);
3291  errorCorrId.push_back(error->getResponseCorrelationId());
3292  EV_INFO << "error added with id " << error->getResponseCorrelationId() << "\n";
3293  }
3294  }
3295  for (uint32 i = 0; i < sctpasconf->getAsconfParamsArraySize(); i++) {
3296  sctpParam = check_and_cast<SCTPParameter *>(sctpasconf->removeAsconfParam());
3297  errorFound = false;
3298  switch (sctpParam->getParameterType()) {
3299  case ADD_IP_ADDRESS:
3300  SCTPAddIPParameter *ipParam;
3301  ipParam = check_and_cast<SCTPAddIPParameter *>(sctpParam);
3302  if (errorCorrId.size() > 0) {
3303  for (auto & elem : errorCorrId)
3304  if ((elem) == ipParam->getRequestCorrelationId()) {
3305  errorFound = true;
3306  break;
3307  }
3308  }
3309  if (errorFound == true) {
3310  delete ipParam;
3311  break;
3312  }
3313  addr = ipParam->getAddressParam();
3314  if (addr.isUnspecified()) {
3315  addr = localAddr;
3317  }
3318  sctpMain->addLocalAddressToAllRemoteAddresses(this, addr, remAddr);
3319  state->localAddresses.push_back(addr);
3320  delete ipParam;
3321  break;
3322 
3323  case DELETE_IP_ADDRESS:
3324  SCTPDeleteIPParameter *delParam;
3325  delParam = check_and_cast<SCTPDeleteIPParameter *>(sctpParam);
3326  if (errorCorrId.size() > 0) {
3327  for (auto & elem : errorCorrId) {
3328  if ((elem) == delParam->getRequestCorrelationId()) {
3329  errorFound = true;
3330  break;
3331  }
3332  }
3333  }
3334  if (errorFound == true) {
3335  delete delParam;
3336  break;
3337  }
3338  addr = delParam->getAddressParam();
3339  sctpMain->removeLocalAddressFromAllRemoteAddresses(this, addr, remAddr);
3340  for (auto j = state->localAddresses.begin(); j != state->localAddresses.end(); j++) {
3341  if ((*j) == addr) {
3342  EV_DETAIL << "erase address " << (*j) << "\n";
3343  state->localAddresses.erase(j);
3344  break;
3345  }
3346  }
3347  delete delParam;
3348  break;
3349 
3350  case SET_PRIMARY_ADDRESS:
3351  SCTPSetPrimaryIPParameter *priParam;
3352  priParam = check_and_cast<SCTPSetPrimaryIPParameter *>(sctpParam);
3353  if (errorCorrId.size() > 0) {
3354  for (auto & elem : errorCorrId) {
3355  if ((elem) == priParam->getRequestCorrelationId()) {
3356  errorFound = true;
3357  break;
3358  }
3359  }
3360  }
3361  if (errorFound == true) {
3362  delete delParam;
3363  break;
3364  }
3365  delete priParam;
3366  break;
3367  }
3368  }
3369  }
3370  delete sctpasconf;
3371  return SCTP_E_IGNORE;
3372 }
Definition: SCTPAssociation.h:172
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
AddressVector remoteAddressList
Definition: SCTPAssociation.h:940
SCTPAsconfChunk * asconfChunk
Definition: SCTPAssociation.h:782
Definition: SCTPAssociation.h:168
uint32 errorCount
Definition: SCTPAssociation.h:609
void removeLocalAddressFromAllRemoteAddresses(SCTPAssociation *assoc, L3Address address, std::vector< L3Address > remAddresses)
Definition: SCTP.cc:692
uint32 pathErrorCount
Definition: SCTPAssociation.h:299
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
SCTP * sctpMain
Definition: SCTPAssociation.h:962
Definition: SCTPAssociation.h:171
L3Address remoteAddr
Definition: SCTPAssociation.h:911
uint32_t uint32
Definition: Compat.h:30
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
L3Address localAddr
Definition: SCTPAssociation.h:912
bool asconfOutstanding
Definition: SCTPAssociation.h:781
virtual SCTPAsconfChunk * dup() const override
Definition: SCTPMessage.h:168
void addLocalAddressToAllRemoteAddresses(SCTPAssociation *assoc, L3Address address, std::vector< L3Address > remAddresses)
Definition: SCTP.cc:661
Definition: SCTPAssociation.h:91
Definition: SCTPAssociation.h:173
Definition: SCTPCommand.h:82
AddressVector localAddresses
Definition: SCTPAssociation.h:607
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPEventCode inet::sctp::SCTPAssociation::processAsconfArrived ( SCTPAsconfChunk asconfChunk)
protected

Referenced by process_RCV_Message().

3142 {
3143  SCTPParameter *sctpParam;
3144  SCTPPathVariables *path;
3145  L3Address addr;
3146  std::vector<L3Address> locAddr;
3147  SCTPAuthenticationChunk *authChunk;
3148  EV_INFO << "Asconf arrived " << asconfChunk->getName() << "\n";
3149  SCTPMessage *sctpAsconfAck = new SCTPMessage("ASCONF_ACK");
3150  sctpAsconfAck->setBitLength(SCTP_COMMON_HEADER * 8);
3151  sctpAsconfAck->setSrcPort(localPort);
3152  sctpAsconfAck->setDestPort(remotePort);
3153  if (state->auth && state->peerAuth) {
3154  authChunk = createAuthChunk();
3155  sctpAsconfAck->addChunk(authChunk);
3156  auto it = sctpMain->assocStatMap.find(assocId);
3157  it->second.numAuthChunksSent++;
3158  }
3159  if (state->numberAsconfReceived > 0 || (state->numberAsconfReceived == 0 && asconfChunk->getSerialNumber() == initPeerTsn + state->numberAsconfReceived)) {
3160  SCTPAsconfAckChunk *asconfAckChunk = createAsconfAckChunk(asconfChunk->getSerialNumber());
3162  int32 count = asconfChunk->getAsconfParamsArraySize();
3163  EV_DETAIL << "Number of Asconf parameters=" << count << "\n";
3164  for (int32 c = 0; c < count; c++) {
3165  sctpParam = (SCTPParameter *)(asconfChunk->removeAsconfParam());
3166  switch (sctpParam->getParameterType()) {
3167  case ADD_IP_ADDRESS:
3168  EV_INFO << "ADD_IP_PARAMETER\n";
3169  SCTPAddIPParameter *ipParam;
3170  ipParam = check_and_cast<SCTPAddIPParameter *>(sctpParam);
3171  addr = ipParam->getAddressParam();
3172  if (addr.isUnspecified()) {
3173  EV_INFO << "no address specified, add natted address " << remoteAddr << "\n";
3174  addr = remoteAddr;
3176  }
3177  for (auto & elem : state->localAddresses) {
3178  if (sctpMain->addRemoteAddress(this, (elem), addr)) {
3179  addPath(addr);
3180  EV_INFO << "add remote address " << addr << " to local address " << (elem) << "\n";
3181  this->remoteAddressList.push_back(addr);
3182  }
3183  }
3184  path = getPath(addr);
3185  if (sctpMain->getEnableHeartbeats()) {
3186  stopTimer(path->HeartbeatTimer);
3187  stopTimer(path->HeartbeatIntervalTimer);
3188  path->statisticsPathRTO->record(path->pathRto);
3189  startTimer(path->HeartbeatIntervalTimer, path->pathRto);
3190  path->forceHb = true;
3191  }
3192  else
3193  path->confirmed = true;
3194  asconfAckChunk->addAsconfResponse(createSuccessIndication(ipParam->getRequestCorrelationId()));
3195  delete ipParam;
3196  break;
3197 
3198  case DELETE_IP_ADDRESS:
3199  SCTPDeleteIPParameter *delParam;
3200  delParam = check_and_cast<SCTPDeleteIPParameter *>(sctpParam);
3201  addr = delParam->getAddressParam();
3202  if (state->localAddresses.size() == 1) {
3203  SCTPErrorCauseParameter *errorParam;
3204  errorParam = new SCTPErrorCauseParameter("ErrorCause");
3205  errorParam->setParameterType(ERROR_CAUSE_INDICATION);
3206  errorParam->setResponseCorrelationId(delParam->getRequestCorrelationId());
3207  errorParam->setErrorCauseType(ERROR_DELETE_LAST_IP_ADDRESS);
3208  errorParam->setBitLength((SCTP_ADD_IP_PARAMETER_LENGTH + 4) * 8);
3209  errorParam->encapsulate((cPacket *)delParam->dup()); //FIXME is the c-style conversion need here?
3210  asconfAckChunk->addAsconfResponse(errorParam);
3211  }
3212  else if (addr == remoteAddr) {
3213  EV_INFO << "addr=remoteAddr, make Error Parameter\n";
3214  SCTPErrorCauseParameter *errParam;
3215  errParam = new SCTPErrorCauseParameter("ErrorCause");
3216  errParam->setParameterType(ERROR_CAUSE_INDICATION);
3217  errParam->setResponseCorrelationId(delParam->getRequestCorrelationId());
3218  errParam->setErrorCauseType(ERROR_DELETE_SOURCE_ADDRESS);
3219  errParam->setByteLength(SCTP_ADD_IP_PARAMETER_LENGTH + 4);
3220  errParam->encapsulate((cPacket *)delParam->dup()); //FIXME is the c-style conversion need here?
3221  asconfAckChunk->addAsconfResponse(errParam);
3222  }
3223  else {
3224  locAddr = (std::vector<L3Address>)state->localAddresses;
3225  sctpMain->removeRemoteAddressFromAllAssociations(this, addr, locAddr);
3226  removePath(addr);
3227  EV_INFO << "remove path from address " << addr << "\n";
3228  asconfAckChunk->addAsconfResponse(createSuccessIndication(delParam->getRequestCorrelationId()));
3229  }
3230  delete delParam;
3231  break;
3232 
3233  case SET_PRIMARY_ADDRESS:
3234  EV_INFO << "SET_PRIMARY_ADDRESS\n";
3235  SCTPSetPrimaryIPParameter *priParam;
3236  priParam = check_and_cast<SCTPSetPrimaryIPParameter *>(sctpParam);
3237  addr = priParam->getAddressParam();
3238  if (addr.isUnspecified()) {
3239  EV_INFO << "no address specified, add natted address " << remoteAddr << "\n";
3240  addr = remoteAddr;
3241  }
3242  for (auto & elem : remoteAddressList) {
3243  if ((elem) == addr) {
3244  if (getPath(addr)->confirmed == true) {
3245  state->setPrimaryPath(getPath(addr));
3246  EV_INFO << "set primaryPath to " << addr << "\n";
3247  }
3248  else {
3249  getPath(addr)->primaryPathCandidate = true;
3250  sendHeartbeat(getPath(addr));
3251  }
3252  break;
3253  }
3254  }
3255  asconfAckChunk->addAsconfResponse(createSuccessIndication(priParam->getRequestCorrelationId()));
3256  delete priParam;
3257  break;
3258  }
3259  }
3260  sctpAsconfAck->addChunk(asconfAckChunk);
3261  sendToIP(sctpAsconfAck, remoteAddr);
3262  if (StartAddIP->isScheduled()) {
3265  const char *type = (const char *)sctpMain->par("addIpType");
3266  sendAsconf(type, false);
3267  }
3268  }
3269  return SCTP_E_IGNORE;
3270 }
uint32 asconfSn
Definition: SCTPAssociation.h:778
Definition: SCTPAssociation.h:172
uint32 corrIdNum
Definition: SCTPAssociation.h:780
bool getEnableHeartbeats()
Definition: SCTP.h:277
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
AddressVector remoteAddressList
Definition: SCTPAssociation.h:940
bool addRemoteAddress(SCTPAssociation *assoc, L3Address localAddress, L3Address remoteAddress)
Definition: SCTP.cc:738
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
int count(const std::vector< T > &v, const T &a)
Definition: stlutils.h:58
Definition: SCTPAssociation.h:175
SCTPAsconfAckChunk * createAsconfAckChunk(const uint32 serialNumber)
Definition: SCTPAssociationAddIP.cc:209
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
uint32 initPeerTsn
Definition: SCTPAssociation.h:948
Definition: SCTPAssociation.h:168
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
#define SCTP_ADD_IP_PARAMETER_LENGTH
Definition: SCTPAssociation.h:232
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
uint16 numberAsconfReceived
Definition: SCTPAssociation.h:779
bool auth
Definition: SCTPAssociation.h:822
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void sendHeartbeat(const SCTPPathVariables *path)
Definition: SCTPAssociationUtil.cc:977
const value< double, compose< units::m, pow< units::s,-1 > > > c(299792458)
Definition: SCTPAssociation.h:171
L3Address remoteAddr
Definition: SCTPAssociation.h:911
bool confirmed
Definition: SCTPAssociation.h:288
AssocStatMap assocStatMap
Definition: SCTP.h:171
Definition: SCTPAssociation.h:176
void sendAsconf(const char *type, const bool remote=false)
Methods for Add-IP and AUTH.
Definition: SCTPAssociationAddIP.cc:25
void removeRemoteAddressFromAllAssociations(SCTPAssociation *assoc, L3Address address, std::vector< L3Address > locAddresses)
Definition: SCTP.cc:715
int32_t int32
Definition: Compat.h:31
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
SCTPSuccessIndication * createSuccessIndication(uint32 correlationId)
Definition: SCTPAssociationAddIP.cc:305
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
int32 assocId
Definition: SCTPAssociation.h:908
cMessage * StartAddIP
Definition: SCTPAssociation.h:924
bool peerAuth
Definition: SCTPAssociation.h:821
void addPath(const L3Address &addr)
Definition: SCTPAssociationUtil.cc:2037
void setPrimaryPath(SCTPPathVariables *path)
Definition: SCTPAssociation.h:545
bool primaryPathCandidate
Definition: SCTPAssociation.h:290
uint16 localPort
Definition: SCTPAssociation.h:913
void removePath()
Definition: SCTPAssociationBase.cc:1790
Definition: SCTPAssociation.h:91
Definition: SCTPAssociation.h:173
Definition: SCTPCommand.h:82
AddressVector localAddresses
Definition: SCTPAssociation.h:607
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::processCookieAckArrived ( )
protected

Referenced by process_RCV_Message().

920 {
921  bool trans = false;
922 
923  if (fsm->getState() == SCTP_S_COOKIE_ECHOED) {
926  if (state->cookieChunk->getCookieArraySize() == 0) {
927  delete state->cookieChunk->getStateCookie();
928  }
929  delete state->cookieChunk;
930  return trans;
931  }
932  else
933  EV_DETAIL << "State=" << fsm->getState() << "\n";
934 
935  return trans;
936 }
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
Definition: SCTPAssociation.h:59
SCTPCookieEchoChunk * cookieChunk
pointer to the cookie chunk data structure (for retransmissions)
Definition: SCTPAssociation.h:654
cFSM * fsm
Definition: SCTPAssociation.h:963
Definition: SCTPAssociation.h:82
bool performStateTransition(const SCTPEventCode &event)
Implemements the pure SCTP state machine.
Definition: SCTPAssociationBase.cc:1182
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::processCookieEchoArrived ( SCTPCookieEchoChunk cookieEcho,
L3Address  addr 
)
protected

Referenced by process_RCV_Message().

845 {
846  bool trans = false;
847  SCTPCookie *cookie = check_and_cast<SCTPCookie *>(cookieEcho->getStateCookie());
848  if (cookie->getCreationTime() + (int32)sctpMain->par("validCookieLifetime") < simTime()) {
849  EV_INFO << "stale Cookie: sendAbort\n";
850  sendAbort();
851  delete cookie;
852  return trans;
853  }
854  if (fsm->getState() == SCTP_S_CLOSED) {
855  if (cookie->getLocalTag() != localVTag || cookie->getPeerTag() != peerVTag) {
856  bool same = true;
857  for (int32 i = 0; i < 32; i++) {
858  if (cookie->getLocalTieTag(i) != state->localTieTag[i]) {
859  same = false;
860  break;
861  }
862  if (cookie->getPeerTieTag(i) != state->peerTieTag[i]) {
863  same = false;
864  break;
865  }
866  }
867  if (!same) {
868  sendAbort();
869  delete cookie;
870  return trans;
871  }
872  }
873  EV_INFO << "State is CLOSED, Cookie_Ack has to be sent\n";
875  if (trans)
876  sendCookieAck(addr); //send to address
877  }
878  else if (fsm->getState() == SCTP_S_ESTABLISHED || fsm->getState() == SCTP_S_COOKIE_WAIT || fsm->getState() == SCTP_S_COOKIE_ECHOED) {
879  EV_INFO << "State is not CLOSED, but COOKIE_ECHO received. Compare the Tags\n";
880  // case A: Peer restarted, retrieve information from cookie
881  if (cookie->getLocalTag() != localVTag && cookie->getPeerTag() != peerVTag) {
882  bool same = true;
883  for (int32 i = 0; i < 32; i++) {
884  if (cookie->getLocalTieTag(i) != state->localTieTag[i]) {
885  same = false;
886  break;
887  }
888  if (cookie->getPeerTieTag(i) != state->peerTieTag[i]) {
889  same = false;
890  break;
891  }
892  }
893  if (same) {
894  localVTag = cookie->getLocalTag();
895  peerVTag = cookie->getPeerTag();
896  sendCookieAck(addr);
897  }
898  }
899  // case B: Setup collision, retrieve information from cookie
900  else if (cookie->getPeerTag() == peerVTag && (cookie->getLocalTag() != localVTag || cookie->getLocalTag() == 0)) {
901  localVTag = cookie->getLocalTag();
902  peerVTag = cookie->getPeerTag();
904  sendCookieAck(addr);
905  }
906  else if (cookie->getPeerTag() == peerVTag && cookie->getLocalTag() == localVTag) {
907  sendCookieAck(addr); //send to address src
908  }
909  trans = true;
910  }
911  else {
912  EV_DETAIL << "State=" << fsm->getState() << "\n";
913  trans = true;
914  }
915  delete cookie;
916  return trans;
917 }
uint32 localVTag
Definition: SCTPAssociation.h:915
Definition: SCTPAssociation.h:60
Definition: SCTPAssociation.h:58
SCTP * sctpMain
Definition: SCTPAssociation.h:962
uint8 peerTieTag[32]
Definition: SCTPAssociation.h:637
Definition: SCTPAssociation.h:80
uint32 peerVTag
Definition: SCTPAssociation.h:916
int32_t int32
Definition: Compat.h:31
Definition: SCTPAssociation.h:59
uint8 localTieTag[32]
Definition: SCTPAssociation.h:636
void sendAbort(uint16 tBit=0)
Definition: SCTPAssociationUtil.cc:1101
cFSM * fsm
Definition: SCTPAssociation.h:963
void sendCookieAck(const L3Address &dest)
Definition: SCTPAssociationUtil.cc:1034
Definition: SCTPAssociation.h:57
bool performStateTransition(const SCTPEventCode &event)
Implemements the pure SCTP state machine.
Definition: SCTPAssociationBase.cc:1182
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPEventCode inet::sctp::SCTPAssociation::processDataArrived ( SCTPDataChunk dataChunk)
protected

Referenced by process_RCV_Message().

2140 {
2141  const uint32 tsn = dataChunk->getTsn();
2143 
2144  state->newChunkReceived = false;
2145  state->lastTsnReceived = tsn;
2146 
2147  bool found = false;
2148  for (auto & elem : state->lastDataSourceList) {
2149  if (elem == path) {
2150  found = true;
2151  break;
2152  }
2153  }
2154  if (!found) {
2155  state->lastDataSourceList.push_back(path);
2156  }
2157  state->lastDataSourcePath = path;
2158 
2159  EV_DETAIL << simTime() << " SCTPAssociation::processDataArrived TSN=" << tsn << endl;
2160  path->vectorPathReceivedTSN->record(tsn);
2161  if (dataChunk->getIBit()) {
2163  }
2165 
2166  SCTPSimpleMessage *smsg = check_and_cast<SCTPSimpleMessage *>(dataChunk->decapsulate());
2167  dataChunk->setByteLength(SCTP_DATA_CHUNK_LENGTH);
2168  dataChunk->encapsulate(smsg);
2169  const uint32 payloadLength = dataChunk->getByteLength() - SCTP_DATA_CHUNK_LENGTH;
2170  EV_DETAIL << "state->bytesRcvd=" << state->bytesRcvd << endl;
2171  if (payloadLength == 0) {
2172  EV_DETAIL << "No user data. Send ABORT" << endl;
2173  return SCTP_E_ABORT;
2174  }
2175  state->bytesRcvd += payloadLength;
2176  EV_DETAIL << "state->bytesRcvd now=" << state->bytesRcvd << endl;
2177  path->numberOfBytesReceived += payloadLength;
2178  auto iter = sctpMain->assocStatMap.find(assocId);
2179  iter->second.rcvdBytes += dataChunk->getByteLength() - SCTP_DATA_CHUNK_LENGTH;
2180 
2181  if (state->stopReceiving) {
2182  return SCTP_E_SEND;
2183  }
2184 
2185  // ====== Duplicate: tsn < CumAckTSN =====================================
2186  if (tsnLe(tsn, state->gapList.getCumAckTSN())) {
2187  if (state->stopOldData) {
2188  if (tsnGe(tsn, state->peerTsnAfterReset)) {
2189  state->stopOldData = false;
2190  }
2191  return SCTP_E_SEND;
2192  }
2193  else {
2194  EV_DETAIL << simTime() << ": Duplicate TSN " << tsn << " (smaller than CumAck)" << endl;
2195  state->dupList.push_back(tsn);
2196  state->dupList.unique();
2197  path->numberOfDuplicates++;
2198  delete check_and_cast<SCTPSimpleMessage *>(dataChunk->decapsulate());
2199  return SCTP_E_DUP_RECEIVED;
2200  }
2201  }
2202 
2203  // ====== Duplicate ======================================================
2204  if (tsnIsDuplicate(tsn)) {
2205  // TSN value is duplicate within a fragment
2206  EV_DETAIL << "Duplicate TSN " << tsn << " (copy)" << endl;
2207  state->dupList.push_back(tsn);
2208  state->dupList.unique();
2209  path->numberOfDuplicates++;
2210  return SCTP_E_SEND;
2211  }
2212 
2213  // ====== Out of receiver buffer space? ==================================
2215  if (((state->messageAcceptLimit > 0) &&
2216  (state->localMsgRwnd - state->bufferedMessages <= 0)) ||
2217  ((state->messageAcceptLimit == 0) &&
2220  {
2222 
2223  if (tsnGt(tsn, state->gapList.getHighestTSNReceived())) {
2224  EV_DETAIL << "DROP: " << (int)tsn << " high=" << (int)state->gapList.getHighestTSNReceived()
2225  << " Q=" << (int)state->queuedReceivedBytes << " Rwnd=" << (int)state->localRwnd << endl;
2226  if ((!state->pktDropSent) && (sctpMain->pktdrop) && (state->peerPktDrop)) {
2227  EV_DETAIL << "Receive buffer full (case 1): sendPacketDrop" << endl;
2228  sendPacketDrop(false);
2229  }
2230  iter->second.numDropsBecauseNewTSNGreaterThanHighestTSN++;
2231  return SCTP_E_SEND;
2232  // } ????
2233  }
2234  else if ((tsn < state->gapList.getHighestTSNReceived()) &&
2235  (state->disableReneging == false) &&
2236  (!makeRoomForTsn(tsn, dataChunk->getBitLength() - SCTP_DATA_CHUNK_LENGTH * 8, dataChunk->getUBit())))
2237  {
2238  if ((!state->pktDropSent) && (sctpMain->pktdrop) && (state->peerPktDrop)) {
2239  EV_DETAIL << "Receive buffer full (case 2): sendPacketDrop" << endl;
2240  sendPacketDrop(false);
2241  }
2242  iter->second.numDropsBecauseNoRoomInBuffer++;
2243  return SCTP_E_SEND;
2244  }
2245  }
2246 
2247  // ====== Update of CumAckTSN ============================================
2249  (state->disableReneging == false) ? true : false);
2251  EV_DETAIL << "cumAckTSN=" << state->gapList.getCumAckTSN()
2252  << " highestTSNReceived=" << state->gapList.getHighestTSNReceived() << endl;
2253 
2254  // ====== Silly Window Syndrome Avoidance ================================
2255  if (state->swsAvoidanceInvoked) {
2256  // swsAvoidanceInvoked => schedule a SACK to be sent at once in this case
2257  EV_TRACE << "swsAvoidanceInvoked" << endl;
2259  }
2260 
2261  if (dataChunk->getSid() >= inboundStreams) {
2262  sendInvalidStreamError(dataChunk->getSid());
2263  return SCTP_E_IGNORE;
2264  }
2265  // ====== Enqueue new chunk ==============================================
2266  SCTPEventCode event = SCTP_E_SEND;
2267  if (state->newChunkReceived) {
2268  auto iter = receiveStreams.find(dataChunk->getSid());
2269  const int ret = iter->second->enqueueNewDataChunk(makeVarFromMsg(dataChunk));
2270  if (ret > 0) {
2271  state->queuedReceivedBytes += payloadLength;
2273 
2274  event = SCTP_E_DELIVERED;
2275  if (ret < 3) {
2277  sendDataArrivedNotification(dataChunk->getSid());
2278  putInDeliveryQ(dataChunk->getSid());
2279  if (simTime() > state->lastThroughputTime + 1) {
2280  for (uint16 i = 0; i < inboundStreams; i++) {
2282  / (simTime() - state->lastThroughputTime) / 1024);
2283  state->streamThroughput[i] = 0;
2284  }
2285  state->lastThroughputTime = simTime();
2286  }
2287  state->streamThroughput[dataChunk->getSid()] += payloadLength;
2288  }
2290  }
2291  state->newChunkReceived = false;
2292  }
2293 
2294  return event;
2295 }
SCTPPathVariables * lastDataSourcePath
Definition: SCTPAssociation.h:606
bool peerPktDrop
Definition: SCTPAssociation.h:835
bool swsAvoidanceInvoked
Definition: SCTPAssociation.h:580
std::list< SCTPPathVariables * > lastDataSourceList
Definition: SCTPAssociation.h:605
uint32 sackFrequency
Definition: SCTPAssociation.h:949
uint32 bufferedMessages
Definition: SCTPAssociation.h:842
uint32 lastTsnReceived
Definition: SCTPAssociation.h:616
Definition: SCTPAssociation.h:77
SCTPEventCode
Definition: SCTPAssociation.h:71
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
void calculateRcvBuffer()
Definition: SCTPAssociationUtil.cc:49
std::map< uint16, cOutVector * > streamThroughputVectors
Definition: SCTPAssociation.h:928
bool pktDropSent
Definition: SCTPAssociation.h:834
bool pktdrop
Definition: SCTP.h:212
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
uint64 localRwnd
Definition: SCTPAssociation.h:612
Definition: SCTPAssociation.h:93
bool disableReneging
Definition: SCTPAssociation.h:687
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
uint32 localMsgRwnd
Definition: SCTPAssociation.h:840
uint32 inboundStreams
Definition: SCTPAssociation.h:942
Definition: SCTPAssociation.h:74
cOutVector * vectorPathReceivedTSN
Definition: SCTPAssociation.h:403
bool newChunkReceived
Definition: SCTPAssociation.h:578
void sendDataArrivedNotification(uint16 sid)
Definition: SCTPAssociationUtil.cc:1789
SCTPDataVariables * makeVarFromMsg(SCTPDataChunk *datachunk)
Definition: SCTPAssociationUtil.cc:2168
SCTP * sctpMain
Definition: SCTPAssociation.h:962
uint32 ackState
Definition: SCTPAssociation.h:618
bool tryToAdvanceCumAckTSN()
Definition: SCTPGapList.cc:348
bool makeRoomForTsn(const uint32 tsn, const uint32 length, const bool uBit)
Definition: SCTPAssociationUtil.cc:2079
SCTPGapList gapList
Definition: SCTPAssociation.h:619
L3Address remoteAddr
Definition: SCTPAssociation.h:911
static int32 tsnLe(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1082
AssocStatMap assocStatMap
Definition: SCTP.h:171
void sendInvalidStreamError(uint16 sid)
Definition: SCTPAssociationUtil.cc:1804
bool stopReceiving
Definition: SCTPAssociation.h:591
uint32 messageAcceptLimit
Definition: SCTPAssociation.h:639
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
Definition: SCTPAssociation.h:95
uint32 bytesToAddPerRcvdChunk
Definition: SCTPAssociation.h:844
void sendPacketDrop(const bool flag)
Definition: SCTPAssociationUtil.cc:1187
simtime_t lastThroughputTime
Definition: SCTPAssociation.h:848
uint32 getHighestTSNReceived() const
Definition: SCTPGapList.h:96
bool tsnIsDuplicate(const uint32 tsn) const
Methods dealing with the handling of TSNs.
Definition: SCTPAssociationUtil.cc:2157
static int32 tsnGt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1081
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
int32 assocId
Definition: SCTPAssociation.h:908
bool stopOldData
Definition: SCTPAssociation.h:592
bool updateGapList(const uint32 receivedTSN, bool &newChunkReceived, bool tsnIsRevokable=true)
Definition: SCTPGapList.cc:367
uint16_t uint16
Definition: Compat.h:32
void putInDeliveryQ(uint16 sid)
Definition: SCTPAssociationUtil.cc:1847
static int32 tsnGe(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1080
uint64 queuedReceivedBytes
Definition: SCTPAssociation.h:625
uint32 getCumAckTSN() const
Definition: SCTPGapList.h:91
uint64 bytesRcvd
Definition: SCTPAssociation.h:630
Definition: SCTPAssociation.h:91
std::list< uint32 > dupList
Definition: SCTPAssociation.h:608
if(!(yy_init))
Definition: lexer.cc:1644
std::map< uint16, uint32 > streamThroughput
Definition: SCTPAssociation.h:849
uint32 peerTsnAfterReset
Definition: SCTPAssociation.h:797
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::processErrorArrived ( SCTPErrorChunk error)
protected

Referenced by process_RCV_Message().

3483 {
3484  uint32 parameterType;
3485  for (uint32 i = 0; i < errorChunk->getParametersArraySize(); i++) {
3486  SCTPParameter *param = (SCTPParameter *)errorChunk->getParameters(i);
3487  parameterType = param->getParameterType();
3488  switch (parameterType) {
3489  case MISSING_NAT_ENTRY: {
3490  if ((bool)sctpMain->par("addIP")) {
3491  if (StartAddIP->isScheduled())
3494  const char *type = (const char *)sctpMain->par("addIpType");
3495  sendAsconf(type, true);
3496  }
3497  break;
3498  }
3499 
3500  case UNSUPPORTED_HMAC: {
3501  sendAbort();
3502  break;
3503  }
3504  }
3505  }
3506 }
uint32 asconfSn
Definition: SCTPAssociation.h:778
uint32 corrIdNum
Definition: SCTPAssociation.h:780
Definition: SCTPAssociation.h:191
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
Definition: SCTPAssociation.h:192
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void sendAsconf(const char *type, const bool remote=false)
Methods for Add-IP and AUTH.
Definition: SCTPAssociationAddIP.cc:25
uint32_t uint32
Definition: Compat.h:30
void sendAbort(uint16 tBit=0)
Definition: SCTPAssociationUtil.cc:1101
cMessage * StartAddIP
Definition: SCTPAssociation.h:924
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPEventCode inet::sctp::SCTPAssociation::processForwardTsnArrived ( SCTPForwardTsnChunk forChunk)
protected

Referenced by process_RCV_Message().

2099 {
2100  EV_TRACE << "processForwardTsnArrived\n";
2101  EV_INFO << "last state->cTsnAck=" << state->gapList.getCumAckTSN() << " fwCumAck=" << fwChunk->getNewCumTsn() << "\n";
2102 
2103  /* Ignore old FORWARD_TSNs, probably stale retransmits. */
2104  if (state->gapList.getCumAckTSN() >= fwChunk->getNewCumTsn()) {
2105  return SCTP_E_IGNORE;
2106  }
2107 
2108  for (uint32 i = 0; i < fwChunk->getSidArraySize(); i++) {
2109  if (fwChunk->getSsn(i) != -1) {
2110  auto iter = receiveStreams.find(fwChunk->getSid(i));
2111  SCTPReceiveStream *rStream = iter->second;
2112 
2113  /* Uncomment the folloing to drop gap-acknowledged messages
2114  * between two abandonend messages rather then delivering them.
2115  */
2116 
2117  if (rStream->getOrderedQ()->getQueueSize() > 0)
2118  rStream->setExpectedStreamSeqNum(rStream->getOrderedQ()->getFirstSsnInQueue(fwChunk->getSid(i)));
2119  else if (rStream->getExpectedStreamSeqNum() <= fwChunk->getSsn(i))
2120  rStream->setExpectedStreamSeqNum(fwChunk->getSsn(i) + 1);
2121  if (rStream->getExpectedStreamSeqNum() > 65535) {
2122  rStream->setExpectedStreamSeqNum(0);
2123  }
2124  sendDataArrivedNotification(fwChunk->getSid(i));
2126  }
2127  }
2128  /* Update Gap lists with abandoned TSNs and advance CumTSNAck */
2129  for (uint32 i = state->gapList.getCumAckTSN() + 1; i <= fwChunk->getNewCumTsn(); i++) {
2130  if (i > state->gapList.getCumAckTSN() && !state->gapList.tsnInGapList(i)) {
2131  bool dummy;
2132  state->gapList.updateGapList(i, dummy, false);
2134  }
2135  }
2136  return SCTP_E_IGNORE;
2137 }
void calculateRcvBuffer()
Definition: SCTPAssociationUtil.cc:49
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
void sendDataArrivedNotification(uint16 sid)
Definition: SCTPAssociationUtil.cc:1789
bool tryToAdvanceCumAckTSN()
Definition: SCTPGapList.cc:348
SCTPGapList gapList
Definition: SCTPAssociation.h:619
uint32_t uint32
Definition: Compat.h:30
bool tsnInGapList(const uint32 tsn) const
Definition: SCTPGapList.h:125
bool updateGapList(const uint32 receivedTSN, bool &newChunkReceived, bool tsnIsRevokable=true)
Definition: SCTPGapList.cc:367
uint32 getCumAckTSN() const
Definition: SCTPGapList.h:91
Definition: SCTPAssociation.h:91
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPEventCode inet::sctp::SCTPAssociation::processHeartbeatAckArrived ( SCTPHeartbeatAckChunk heartbeatack,
SCTPPathVariables path 
)
protected

Referenced by process_RCV_Message().

2299 {
2300  path->numberOfHeartbeatAcksRcvd++;
2301  path->vectorPathRcvdHbAck->record(path->numberOfHeartbeatAcksRcvd);
2302  /* hb-ack goes to pathmanagement, reset error counters, stop timeout timer */
2303  const L3Address addr = hback->getRemoteAddr();
2304  const simtime_t hbTimeField = hback->getTimeField();
2305  stopTimer(path->HeartbeatTimer);
2306  /* assume a valid RTT measurement on this path */
2307  simtime_t rttEstimation = simTime() - hbTimeField;
2308  pmRttMeasurement(path, rttEstimation);
2309  pmClearPathCounter(path);
2310  path->confirmed = true;
2311  path->lastAckTime = simTime();
2312  if (path->primaryPathCandidate == true) {
2313  state->setPrimaryPath(getPath(addr));
2314  path->primaryPathCandidate = false;
2315  if (path->pmtu < state->assocPmtu) {
2316  state->assocPmtu = path->pmtu;
2317  }
2318  path->ssthresh = state->peerRwnd;
2319  recordCwndUpdate(path);
2320  path->heartbeatTimeout = (double)sctpMain->getHbInterval() + path->pathRto;
2321  }
2322 
2323  if (path->activePath == false) {
2324  EV_INFO << "HB ACK arrived activePath=false. remoteAddress=" << path->remoteAddress
2325  << " initialPP=" << state->initialPrimaryPath << endl;
2326  path->activePath = true;
2327  if (state->reactivatePrimaryPath && path->remoteAddress == state->initialPrimaryPath) {
2328  state->setPrimaryPath(path);
2329  }
2330  EV_DETAIL << "primaryPath now " << state->getPrimaryPathIndex() << endl;
2331  }
2332  EV_INFO << "Received HB ACK chunk...resetting error counters on path " << addr
2333  << ", rttEstimation=" << rttEstimation << endl;
2334  path->pathErrorCount = 0;
2335  return SCTP_E_IGNORE;
2336 }
void recordCwndUpdate(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:355
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
double getHbInterval()
Definition: SCTP.h:280
uint64 peerRwnd
Definition: SCTPAssociation.h:610
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
SCTP * sctpMain
Definition: SCTPAssociation.h:962
L3Address initialPrimaryPath
Definition: SCTPAssociation.h:604
const L3Address & getPrimaryPathIndex() const
Definition: SCTPAssociation.h:550
bool reactivatePrimaryPath
Definition: SCTPAssociation.h:588
uint32 assocPmtu
Definition: SCTPAssociation.h:627
void setPrimaryPath(SCTPPathVariables *path)
Definition: SCTPAssociation.h:545
void pmRttMeasurement(SCTPPathVariables *path, const simtime_t &rttEstimation)
Definition: SCTPAssociationUtil.cc:2760
void pmClearPathCounter(SCTPPathVariables *path)
Definition: SCTPAssociationUtil.cc:2730
Definition: SCTPAssociation.h:91
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPEventCode inet::sctp::SCTPAssociation::processInAndOutResetRequestArrived ( SCTPIncomingSSNResetRequestParameter inRequestParam,
SCTPOutgoingSSNResetRequestParameter outRequestParam 
)
protected

Referenced by processStreamResetArrived().

2641 {
2642  uint32 inSrSn = 0;
2643  uint32 outSrSn = 0;
2644  uint16 inRes = 0;
2645  uint16 outRes = 0;
2646  uint16 num = 0;
2647  if (tsnGt(outRequestParam->getLastTsn(), state->gapList.getHighestTSNReceived())) {
2648  state->lastTsnBeforeReset = outRequestParam->getLastTsn();
2649  state->peerRequestSn = outRequestParam->getSrReqSn();
2650  state->inRequestSn = inRequestParam->getSrReqSn();
2651  state->inOut = true;
2652  } else {
2653  if (outRequestParam->getStreamNumbersArraySize() > 0) {
2654  num = 0;
2655  for (uint16 i = 0; i < outRequestParam->getStreamNumbersArraySize(); i++) {
2656  if (!receiveStreamPresent(outRequestParam->getStreamNumbers(i))) {
2657  outSrSn = outRequestParam->getSrReqSn();
2658  outRes = DENIED;
2659  num++;
2660  break;
2661  }
2662  }
2663  if (num == 0) {
2664  for (uint16 i = 0; i < outRequestParam->getStreamNumbersArraySize(); i++) {
2665  resetExpectedSsn(outRequestParam->getStreamNumbers(i));
2666  }
2667  }
2668  } else {
2670  EV_DETAIL << "processInAndOutResetRequestArrived: resetExpectedSsns\n";
2671  sendOutgoingRequestAndResponse(inRequestParam->getSrReqSn(), outRequestParam->getSrReqSn());
2672  }
2673  if (inRequestParam->getStreamNumbersArraySize() > 0) {
2674  num = 0;
2675  for (uint16 i = 0; i < inRequestParam->getStreamNumbersArraySize(); i++) {
2676  if (!receiveStreamPresent(inRequestParam->getStreamNumbers(i))) {
2677  inSrSn = inRequestParam->getSrReqSn();
2678  inRes = DENIED;
2679  num++;
2680  // sendStreamResetResponse(outRequestParam->getSrReqSn(), DENIED);
2681  break;
2682  }
2683  }
2684  if (num == 0) {
2685  sendOutgoingRequestAndResponse(inRequestParam, outRequestParam);
2686  }
2687  }
2688  }
2689  if (inSrSn > 0 && outSrSn > 0) {
2690  sendDoubleStreamResetResponse(inSrSn, inRes, outSrSn, outRes);
2691  state->resetPending = true;
2692  }
2693  return SCTP_E_IGNORE;
2694 }
bool inOut
Definition: SCTPAssociation.h:599
void sendDoubleStreamResetResponse(uint32 insrrsn, uint16 inresult, uint32 outsrrsn, uint16 outresult)
Definition: SCTPAssociationStreamReset.cc:805
void resetExpectedSsns()
Definition: SCTPAssociationStreamReset.cc:845
void resetExpectedSsn(uint16 id)
Definition: SCTPAssociationStreamReset.cc:853
uint32 inRequestSn
Definition: SCTPAssociation.h:796
uint32 lastTsnBeforeReset
Definition: SCTPAssociation.h:798
void sendOutgoingRequestAndResponse(uint32 inRequestSn, uint32 outRequestSn)
Definition: SCTPAssociationStreamReset.cc:383
Definition: SCTPAssociation.h:145
SCTPGapList gapList
Definition: SCTPAssociation.h:619
bool receiveStreamPresent(uint16 sid)
Definition: SCTPAssociationStreamReset.cc:900
uint32_t uint32
Definition: Compat.h:30
uint32 getHighestTSNReceived() const
Definition: SCTPGapList.h:96
static int32 tsnGt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1081
bool resetPending
Definition: SCTPAssociation.h:589
uint16_t uint16
Definition: Compat.h:32
Definition: SCTPAssociation.h:91
uint32 peerRequestSn
Definition: SCTPAssociation.h:795
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::processIncomingResetRequestArrived ( SCTPIncomingSSNResetRequestParameter requestParam)
protected

Referenced by checkStreamsToReset(), and processStreamResetArrived().

2413 {
2414  uint16 num = 0;
2415  if (!state->firstPeerRequest && (requestParam->getSrReqSn() < (state->peerRequestSn)) ) {
2416  // Retransmission
2417  sendStreamResetResponse(requestParam->getSrReqSn(), NO_RESET);
2418  return;
2419  }
2420  if (!state->fragInProgress && state->outstandingBytes == 0) {
2421  if (requestParam->getStreamNumbersArraySize() > 0) {
2422  for (uint16 i = 0; i < requestParam->getStreamNumbersArraySize(); i++) {
2423  if (!sendStreamPresent(requestParam->getStreamNumbers(i))) {
2424  sendStreamResetResponse(requestParam->getSrReqSn(), DENIED);
2425  return;
2426  }
2427  if (getSsnOfStream(requestParam->getStreamNumbers(i)) == 0 ) {
2428  num++;
2429  }
2430  }
2431  if (num == requestParam->getStreamNumbersArraySize()) {
2432  sendStreamResetResponse(requestParam->getSrReqSn(), NOTHING_TO_DO);
2433  return;
2434  }
2435  for (uint16 i = 0; i < requestParam->getStreamNumbersArraySize(); i++) {
2436  if (!state->findPeerStreamToReset(requestParam->getStreamNumbers(i))) {
2437 
2438  // resetSsn(requestParam->getStreamNumbers(i));
2439  state->peerStreamsToReset.push_back(requestParam->getStreamNumbers(i));
2440  }
2441  }
2442  } else {
2443  resetSsns();
2444  }
2445  sendOutgoingResetRequest(requestParam);
2446  // sendBundledOutgoingResetAndResponse(requestParam);
2447  EV_TRACE << "processIncomingResetRequestArrived: sendOutgoingResetRequestArrived returned\n";
2448  state->resetPending = true;
2449  } else {
2450  if (requestParam->getStreamNumbersArraySize() > 0) {
2451  state->streamsPending.clear();
2452  state->streamsToReset.clear();
2453  for (uint16 i = 0; i < requestParam->getStreamNumbersArraySize(); i++) {
2454  if (!sendStreamPresent(requestParam->getStreamNumbers(i))) {
2455  sendStreamResetResponse(requestParam->getSrReqSn(), DENIED);
2456  return;
2457  }
2458  if ((getBytesInFlightOfStream(requestParam->getStreamNumbers(i)) > 0) || getFragInProgressOfStream(requestParam->getStreamNumbers(i))){
2459  state->streamsPending.push_back(requestParam->getStreamNumbers(i));
2460  } else {
2461  state->streamsToReset.push_back(requestParam->getStreamNumbers(i));
2462  resetSsn(requestParam->getStreamNumbers(i));
2463  }
2464  }
2465  } else {
2466  for (uint16 i = 0; i < outboundStreams; i++) {
2467  if (getBytesInFlightOfStream(i) > 0) {
2468  state->streamsPending.push_back(i);
2469  } else {
2470  state->streamsToReset.push_back(i);
2471  resetSsn(i);
2472  }
2473  }
2474  }
2475  if (state->streamsToReset.size() > 0) {
2476  // sendBundledOutgoingResetAndResponse(requestParam);
2477  sendOutgoingResetRequest(requestParam);
2478  state->resetPending = true;
2479  }
2480  if (!state->resetPending) {
2481  sendStreamResetResponse(requestParam->getSrReqSn(), DEFERRED);
2482  state->resetDeferred = true;
2483  }
2484  state->peerRequestSn = requestParam->getSrReqSn();
2487  if (state->streamsPending.size() == 0 && state->incomingRequestSet && state->incomingRequest != nullptr) {
2488  delete state->incomingRequest;
2489  state->incomingRequest = nullptr;
2490  state->incomingRequestSet = false;
2491  }
2492  state->incomingRequest = ((SCTPParameter *)requestParam)->dup(); //FIXME is the c-style conversion need here?
2493  state->incomingRequest->setName("StateIncoming");
2494  state->incomingRequestSet = true;
2495  }
2496 }
bool sendStreamPresent(uint16 sid)
Definition: SCTPAssociationStreamReset.cc:891
uint16 peerRequestType
Definition: SCTPAssociation.h:809
void sendOutgoingResetRequest(SCTPIncomingSSNResetRequestParameter *requestParam)
Definition: SCTPAssociationStreamReset.cc:98
bool fragInProgress
Definition: SCTPAssociation.h:601
uint32 getBytesInFlightOfStream(uint16 sid)
Definition: SCTPAssociationUtil.cc:78
bool getFragInProgressOfStream(uint16 sid)
Definition: SCTPAssociationUtil.cc:100
bool findPeerStreamToReset(uint16 sn)
Definition: SCTPAssociationBase.cc:525
uint16 localRequestType
Definition: SCTPAssociation.h:810
bool firstPeerRequest
Definition: SCTPAssociation.h:790
uint32 outboundStreams
Definition: SCTPAssociation.h:943
Definition: SCTPAssociation.h:150
std::list< uint16 > streamsPending
Definition: SCTPAssociation.h:803
Definition: SCTPAssociation.h:148
std::list< uint16 > peerStreamsToReset
Definition: SCTPAssociation.h:805
Definition: SCTPAssociation.h:145
uint32 getSsnOfStream(uint16 id)
Definition: SCTPAssociationStreamReset.cc:869
uint64 outstandingBytes
Definition: SCTPAssociation.h:622
Definition: SCTPAssociation.h:151
Definition: SCTPAssociation.h:149
void resetSsn(uint16 id)
Definition: SCTPAssociationStreamReset.cc:884
SCTPParameter * incomingRequest
Definition: SCTPAssociation.h:800
virtual SCTPParameter * dup() const override
Definition: SCTPMessage_m.h:1257
std::list< uint16 > streamsToReset
Definition: SCTPAssociation.h:804
bool resetDeferred
Definition: SCTPAssociation.h:787
bool resetPending
Definition: SCTPAssociation.h:589
uint16_t uint16
Definition: Compat.h:32
Definition: SCTPAssociation.h:143
void sendStreamResetResponse(uint32 srrsn, int result)
Definition: SCTPAssociationStreamReset.cc:763
void resetSsns()
Methods for Stream Reset.
Definition: SCTPAssociationStreamReset.cc:876
uint32 peerRequestSn
Definition: SCTPAssociation.h:795
bool incomingRequestSet
Definition: SCTPAssociation.h:602
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::processInitAckArrived ( SCTPInitAckChunk initAckChunk)
protected

Referenced by process_RCV_Message().

760 {
761  bool trans = false;
762  uint16 type;
763 
764  if (fsm->getState() == SCTP_S_COOKIE_WAIT) {
765  EV_INFO << "State is COOKIE_WAIT, Cookie_Echo has to be sent\n";
769  //delete state->initChunk; will be deleted when state ESTABLISHED is entered
770  if (trans) {
771  initPeerTsn = initAckChunk->getInitTSN();
772  localVTag = initAckChunk->getInitTag();
774  state->initialPeerRwnd = initAckChunk->getA_rwnd();
777  if (initAckChunk->getMsg_rwnd() > 0) {
778  state->peerAllowsChunks = true;
779  state->initialPeerMsgRwnd = initAckChunk->getMsg_rwnd();
781  }
783  remoteAddressList.clear();
784  numberOfRemoteAddresses = initAckChunk->getAddressesArraySize();
785  EV_INFO << "number of remote addresses in initAck=" << numberOfRemoteAddresses << "\n";
786  for (uint32 j = 0; j < numberOfRemoteAddresses; j++) {
787  if (initAckChunk->getAddresses(j).getType() == L3Address::IPv6)
788  continue;
789  for (auto & elem : state->localAddresses) {
790  if (!((elem).isUnspecified())) {
791  EV_INFO << "addPath " << initAckChunk->getAddresses(j) << "\n";
792  if (sctpMain->addRemoteAddress(this, (elem), initAckChunk->getAddresses(j))) {
793  this->remoteAddressList.push_back(initAckChunk->getAddresses(j));
794  addPath(initAckChunk->getAddresses(j));
795  }
796  }
797  }
798  }
799  auto ite = sctpPathMap.find(remoteAddr);
800  if (ite == sctpPathMap.end()) {
801  EV_INFO << " get new path for " << remoteAddr << "\n";
802  SCTPPathVariables *path = new SCTPPathVariables(remoteAddr, this, rt);
803  sctpPathMap[remoteAddr] = path;
807  }
810  inboundStreams = ((initAckChunk->getNoOutStreams() < inboundStreams) ? initAckChunk->getNoOutStreams() : inboundStreams);
811  outboundStreams = ((initAckChunk->getNoInStreams() < outboundStreams) ? initAckChunk->getNoInStreams() : outboundStreams);
813  if (initAckChunk->getHmacTypesArraySize() != 0) {
814  state->peerAuth = true;
815  for (uint32 j = 0; j < initAckChunk->getChunkTypesArraySize(); j++) {
816  type = initAckChunk->getChunkTypes(j);
817  if (type != INIT && type != INIT_ACK && type != AUTH && type != SHUTDOWN_COMPLETE) {
818  state->peerChunkList.push_back(type);
819  }
820  }
821  }
822  if (initAckChunk->getSepChunksArraySize() > 0) {
823  for (uint32 i = 0; i < initAckChunk->getSepChunksArraySize(); i++) {
824  if (initAckChunk->getSepChunks(i) == RE_CONFIG) {
825  state->peerStreamReset = true;
826  continue;
827  }
828  if (initAckChunk->getSepChunks(i) == PKTDROP) {
829  state->peerPktDrop = true;
830  continue;
831  }
832  }
833  }
834  sendCookieEcho(initAckChunk);
835  }
837  }
838  else
839  EV_DETAIL << "State=" << fsm->getState() << "\n";
841  return trans;
842 }
#define SCTP_TIMEOUT_INIT_REXMIT
Definition: SCTPAssociation.h:246
bool peerPktDrop
Definition: SCTPAssociation.h:835
uint32 localVTag
Definition: SCTPAssociation.h:915
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
Definition: L3Address.h:47
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
AddressVector remoteAddressList
Definition: SCTPAssociation.h:940
bool addRemoteAddress(SCTPAssociation *assoc, L3Address localAddress, L3Address remoteAddress)
Definition: SCTP.cc:738
Definition: SCTPAssociation.h:127
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
uint32 numberOfRemoteAddresses
Definition: SCTPAssociation.h:941
uint64 peerRwnd
Definition: SCTPAssociation.h:610
void(SCTPAssociation::* ssInitStreams)(uint32 inStreams, uint32 outStreams)
Definition: SCTPAssociation.h:1288
Definition: SCTPAssociation.h:58
CounterMap roomRetransQ
Definition: SCTPAssociation.h:880
uint32 initPeerTsn
Definition: SCTPAssociation.h:948
uint32 expectedStreamResetSequenceNumber
Definition: SCTPAssociation.h:794
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
uint32 outboundStreams
Definition: SCTPAssociation.h:943
uint32 inboundStreams
Definition: SCTPAssociation.h:942
Definition: SCTPAssociation.h:81
SCTP * sctpMain
Definition: SCTPAssociation.h:962
uint64 initialPeerRwnd
Definition: SCTPAssociation.h:611
uint32 peerMsgRwnd
Definition: SCTPAssociation.h:841
void printSctpPathMap() const
Definition: SCTPAssociationUtil.cc:131
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
Definition: SCTPAssociation.h:124
Definition: SCTPAssociation.h:128
simtime_t initRexmitTimeout
Definition: SCTPAssociation.h:650
SCTPGapList gapList
Definition: SCTPAssociation.h:619
L3Address remoteAddr
Definition: SCTPAssociation.h:911
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
Definition: SCTPAssociation.h:112
L3Address initialPrimaryPath
Definition: SCTPAssociation.h:604
bool peerAllowsChunks
Definition: SCTPAssociation.h:838
QueueCounter qCounter
Definition: SCTPAssociation.h:965
void setInitialCumAckTSN(const uint32 cumAckTSN)
Definition: SCTPGapList.h:85
IRoutingTable * rt
Definition: SCTPAssociation.h:936
uint32_t uint32
Definition: Compat.h:30
bool peerStreamReset
Definition: SCTPAssociation.h:786
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
std::vector< uint16 > peerChunkList
Definition: SCTPAssociation.h:824
bool peerAuth
Definition: SCTPAssociation.h:821
void addPath(const L3Address &addr)
Definition: SCTPAssociationUtil.cc:2037
uint16_t uint16
Definition: Compat.h:32
void setPrimaryPath(SCTPPathVariables *path)
Definition: SCTPAssociation.h:545
cFSM * fsm
Definition: SCTPAssociation.h:963
SSFunctions ssFunctions
Definition: SCTPAssociation.h:1294
cOutVector * statisticsPeerRwnd
Definition: SCTPAssociation.h:983
Definition: SCTPAssociation.h:113
bool performStateTransition(const SCTPEventCode &event)
Implemements the pure SCTP state machine.
Definition: SCTPAssociationBase.cc:1182
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
void sendCookieEcho(SCTPInitAckChunk *initackchunk)
Definition: SCTPAssociationUtil.cc:906
uint32 initialPeerMsgRwnd
Definition: SCTPAssociation.h:839
Definition: SCTPAssociation.h:123
AddressVector localAddresses
Definition: SCTPAssociation.h:607
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::processInitArrived ( SCTPInitChunk initChunk,
int32  sport,
int32  dport 
)
protected

Process incoming SCTP packets.

Invoked from process_RCV_Message

Referenced by process_RCV_Message().

561 {
562  SCTPAssociation *assoc;
563  char timerName[64];
564  bool trans = false;
565  uint16 type;
566  AddressVector adv;
567 
568  EV_TRACE << "processInitArrived\n";
569  if (fsm->getState() == SCTP_S_CLOSED) {
570  EV_INFO << "fork=" << state->fork << " initReceived=" << state->initReceived << "\n";
571  if (state->fork && !state->initReceived) {
572  EV_TRACE << "cloneAssociation\n";
573  assoc = cloneAssociation();
574  EV_TRACE << "addForkedAssociation\n";
575  sctpMain->addForkedAssociation(this, assoc, localAddr, remoteAddr, srcPort, destPort);
576  assoc->listening = true;
577  this->listening = false;
578 
579  EV_INFO << "Connection forked: this connection got new assocId=" << assocId << ", "
580  "spinoff keeps LISTENing with assocId=" << assoc->assocId << "\n";
581  snprintf(timerName, sizeof(timerName), "T2_SHUTDOWN of assoc %d", assocId);
582  T2_ShutdownTimer->setName(timerName);
583  snprintf(timerName, sizeof(timerName), "T5_SHUTDOWN_GUARD of assoc %d", assocId);
584  T5_ShutdownGuardTimer->setName(timerName);
585  snprintf(timerName, sizeof(timerName), "SACK_TIMER of assoc %d", assocId);
586  SackTimer->setName(timerName);
587  snprintf(timerName, sizeof(timerName), "T1_INIT of assoc %d", assocId);
588  T1_InitTimer->setName(timerName);
589  }
590  else {
591  sctpMain->updateSockPair(this, localAddr, remoteAddr, srcPort, destPort);
592  }
593  if (!state->initReceived) {
594  state->initReceived = true;
597  if (initchunk->getAddressesArraySize() == 0) {
598  EV_INFO << " get new path for " << remoteAddr << "\n";
599  SCTPPathVariables *rPath = new SCTPPathVariables(remoteAddr, this, rt);
600  sctpPathMap[rPath->remoteAddress] = rPath;
601  qCounter.roomTransQ[rPath->remoteAddress] = 0;
602  qCounter.bookedTransQ[rPath->remoteAddress] = 0;
603  qCounter.roomRetransQ[rPath->remoteAddress] = 0;
604  }
605  initPeerTsn = initchunk->getInitTSN();
607  state->initialPeerRwnd = initchunk->getA_rwnd();
608  if (initchunk->getMsg_rwnd() > 0) {
609  state->peerAllowsChunks = true;
610  state->initialPeerMsgRwnd = initchunk->getMsg_rwnd();
612  }
615  localVTag = initchunk->getInitTag();
616  numberOfRemoteAddresses = initchunk->getAddressesArraySize();
617  state->localAddresses.clear();
618  if (localAddressList.front().isUnspecified()) {
619  for (int32 i = 0; i < ift->getNumInterfaces(); ++i) {
620  if (ift->getInterface(i)->ipv4Data() != nullptr) {
621 #ifdef WITH_IPv4
622  adv.push_back(ift->getInterface(i)->ipv4Data()->getIPAddress());
623 #else // ifdef WITH_IPv4
624  throw cRuntimeError("INET was compiled without IPv4 support");
625 #endif // ifdef WITH_IPv4
626  }
627  else if (ift->getInterface(i)->ipv6Data() != nullptr) {
628 #ifdef WITH_IPv6
629  adv.push_back(ift->getInterface(i)->ipv6Data()->getAddress(0));
630 #else // ifdef WITH_IPv6
631  throw cRuntimeError("INET was compiled without IPv6 support");
632 #endif // ifdef WITH_IPv6
633  }
634  }
635  }
636  else {
637  adv = localAddressList;
638  }
639  int rlevel = getAddressLevel(remoteAddr);
640  if (adv.size() == 1) {
641  state->localAddresses.push_back((*adv.begin()));
642  }
643  else if (rlevel > 0) {
644  for (auto & elem : adv) {
645  if (getAddressLevel((elem)) >= rlevel) {
646  sctpMain->addLocalAddress(this, (elem));
647  state->localAddresses.push_back((elem));
648  }
649  }
650  }
651  for (uint32 j = 0; j < initchunk->getAddressesArraySize(); j++) {
652  // skip IPv6 because we can't send to them yet
653  if (initchunk->getAddresses(j).getType() == L3Address::IPv6)
654  continue;
655  // set path variables for this pathlocalAddresses
656  if (!getPath(initchunk->getAddresses(j))) {
657  SCTPPathVariables *path = new SCTPPathVariables(initchunk->getAddresses(j), this, rt);
658  EV_INFO << " get new path for " << initchunk->getAddresses(j) << " ptr=" << path << "\n";
659  for (auto & elem : state->localAddresses) {
660  if (sctpMain->addRemoteAddress(this, (elem), initchunk->getAddresses(j))) {
661  this->remoteAddressList.push_back(initchunk->getAddresses(j));
662  }
663  }
664  sctpPathMap[path->remoteAddress] = path;
665  qCounter.roomTransQ[path->remoteAddress] = 0;
666  qCounter.bookedTransQ[path->remoteAddress] = 0;
667  qCounter.roomRetransQ[path->remoteAddress] = 0;
668  }
669  }
670  auto ite = sctpPathMap.find(remoteAddr);
671  if (ite == sctpPathMap.end()) {
672  SCTPPathVariables *path = new SCTPPathVariables(remoteAddr, this, rt);
673  EV_INFO << "Get new path for " << remoteAddr << "\n";
674  sctpPathMap[remoteAddr] = path;
678  }
679  if (initchunk->getHmacTypesArraySize() != 0) {
680  state->peerAuth = true;
681  for (uint32 j = 0; j < initchunk->getChunkTypesArraySize(); j++) {
682  type = initchunk->getChunkTypes(j);
683  if (type != INIT && type != INIT_ACK && type != AUTH && type != SHUTDOWN_COMPLETE) {
684  state->peerChunkList.push_back(type);
685  }
686  }
687  }
688  EV_DETAIL << "number supported extensions:" << initchunk->getSepChunksArraySize() << "\n";
689  if (initchunk->getSepChunksArraySize() > 0) {
690  for (uint32 i = 0; i < initchunk->getSepChunksArraySize(); i++) {
691  if (initchunk->getSepChunks(i) == RE_CONFIG) {
692  state->peerStreamReset = true;
693  continue;
694  }
695  if (initchunk->getSepChunks(i) == PKTDROP) {
696  state->peerPktDrop = true;
697  EV_DEBUG << "set peerPktDrop to true\n";
698  continue;
699  }
700  }
701  }
703  if (trans) {
704  sendInitAck(initchunk);
705  }
706  }
707  else if (fsm->getState() == SCTP_S_CLOSED) {
709  if (trans) {
710  sendInitAck(initchunk);
711  }
712  }
713  else {
714  trans = true;
715  }
716  }
717  else if (fsm->getState() == SCTP_S_COOKIE_WAIT) { //INIT-Collision
718  EV_INFO << "INIT collision: send Init-Ack\n";
719  if (initchunk->getHmacTypesArraySize() != 0) {
720  state->peerAuth = true;
721  if (state->peerChunkList.size() == 0) {
722  for (uint32 j = 0; j < initchunk->getChunkTypesArraySize(); j++) {
723  type = initchunk->getChunkTypes(j);
724  if (type != INIT && type != INIT_ACK && type != AUTH && type != SHUTDOWN_COMPLETE) {
725  state->peerChunkList.push_back(type);
726  }
727  }
728  }
729  }
730  sendInitAck(initchunk);
731  trans = true;
732  }
733  else if (fsm->getState() == SCTP_S_COOKIE_ECHOED || fsm->getState() == SCTP_S_ESTABLISHED) {
734  // check, whether a new address has been added
735  bool addressPresent = false;
736  for (uint32 j = 0; j < initchunk->getAddressesArraySize(); j++) {
737  if (initchunk->getAddresses(j).getType() == L3Address::IPv6)
738  continue;
739  for (auto & elem : remoteAddressList) {
740  if ((elem) == (initchunk->getAddresses(j))) {
741  addressPresent = true;
742  break;
743  }
744  }
745  if (!addressPresent) {
746  sendAbort();
747  return true;
748  }
749  }
750  sendInitAck(initchunk);
751  trans = true;
752  }
753  else if (fsm->getState() == SCTP_S_SHUTDOWN_ACK_SENT)
754  trans = true;
756  return trans;
757 }
void sendInitAck(SCTPInitChunk *initchunk)
Definition: SCTPAssociationUtil.cc:727
IPv4InterfaceData * ipv4Data() const
Definition: InterfaceEntry.h:221
bool peerPktDrop
Definition: SCTPAssociation.h:835
bool initReceived
Definition: SCTPAssociation.h:576
SCTPAssociation * cloneAssociation()
Utility: clone a listening association.
Definition: SCTPAssociationUtil.cc:301
Definition: SCTPAssociation.h:78
uint32 localVTag
Definition: SCTPAssociation.h:915
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
Definition: L3Address.h:47
AddressVector remoteAddressList
Definition: SCTPAssociation.h:940
bool addRemoteAddress(SCTPAssociation *assoc, L3Address localAddress, L3Address remoteAddress)
Definition: SCTP.cc:738
SCTPAssociation(SCTP *mod, int32 appGateIndex, int32 assocId, IRoutingTable *rt, IInterfaceTable *ift)
Constructor.
Definition: SCTPAssociationBase.cc:570
Definition: SCTPAssociation.h:127
uint32 numberOfRemoteAddresses
Definition: SCTPAssociation.h:941
uint64 peerRwnd
Definition: SCTPAssociation.h:610
AddressVector localAddressList
Definition: SCTPAssociation.h:939
Definition: SCTPAssociation.h:60
IInterfaceTable * ift
Definition: SCTPAssociation.h:937
Definition: SCTPAssociation.h:64
Definition: SCTPAssociation.h:58
CounterMap roomRetransQ
Definition: SCTPAssociation.h:880
uint32 initPeerTsn
Definition: SCTPAssociation.h:948
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
cMessage * T5_ShutdownGuardTimer
Definition: SCTPAssociation.h:921
cMessage * SackTimer
Definition: SCTPAssociation.h:922
SCTP * sctpMain
Definition: SCTPAssociation.h:962
bool fork
Definition: SCTPAssociation.h:573
uint64 initialPeerRwnd
Definition: SCTPAssociation.h:611
uint32 peerMsgRwnd
Definition: SCTPAssociation.h:841
const IPv6Address & getAddress(int i) const
Returns ith address of the interface.
Definition: IPv6InterfaceData.cc:290
void printSctpPathMap() const
Definition: SCTPAssociationUtil.cc:131
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
Definition: SCTPAssociation.h:124
std::vector< L3Address > AddressVector
Definition: SCTPAssociation.h:52
Definition: SCTPAssociation.h:128
SCTPGapList gapList
Definition: SCTPAssociation.h:619
L3Address remoteAddr
Definition: SCTPAssociation.h:911
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
Definition: SCTPAssociation.h:112
L3Address initialPrimaryPath
Definition: SCTPAssociation.h:604
bool peerAllowsChunks
Definition: SCTPAssociation.h:838
cMessage * T2_ShutdownTimer
Definition: SCTPAssociation.h:920
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
QueueCounter qCounter
Definition: SCTPAssociation.h:965
void setInitialCumAckTSN(const uint32 cumAckTSN)
Definition: SCTPGapList.h:85
IRoutingTable * rt
Definition: SCTPAssociation.h:936
IPv4Address getIPAddress() const
Definition: IPv4InterfaceData.h:177
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
Definition: SCTPAssociation.h:59
void addForkedAssociation(SCTPAssociation *assoc, SCTPAssociation *newAssoc, L3Address localAddr, L3Address remoteAddr, int32 localPort, int32 remotePort)
Update assocs socket pair, and register newAssoc (which&#39;ll keep LISTENing).
Definition: SCTP.cc:762
L3Address localAddr
Definition: SCTPAssociation.h:912
static int getAddressLevel(const L3Address &addr)
Utility: return IPv4 or IPv6 address level.
Definition: SCTPAssociationUtil.cc:2814
bool peerStreamReset
Definition: SCTPAssociation.h:786
void sendAbort(uint16 tBit=0)
Definition: SCTPAssociationUtil.cc:1101
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
int32 assocId
Definition: SCTPAssociation.h:908
bool listening
Definition: SCTPAssociation.h:910
std::vector< uint16 > peerChunkList
Definition: SCTPAssociation.h:824
bool peerAuth
Definition: SCTPAssociation.h:821
uint16_t uint16
Definition: Compat.h:32
void setPrimaryPath(SCTPPathVariables *path)
Definition: SCTPAssociation.h:545
cFSM * fsm
Definition: SCTPAssociation.h:963
IPv6InterfaceData * ipv6Data() const
Definition: InterfaceEntry.h:223
Definition: SCTPAssociation.h:57
void addLocalAddress(SCTPAssociation *assoc, L3Address address)
Definition: SCTP.cc:634
cOutVector * statisticsPeerRwnd
Definition: SCTPAssociation.h:983
Definition: SCTPAssociation.h:113
virtual InterfaceEntry * getInterface(int pos) const =0
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
bool performStateTransition(const SCTPEventCode &event)
Implemements the pure SCTP state machine.
Definition: SCTPAssociationBase.cc:1182
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
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
uint32 initialPeerMsgRwnd
Definition: SCTPAssociation.h:839
Definition: SCTPAssociation.h:123
AddressVector localAddresses
Definition: SCTPAssociation.h:607
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPEventCode inet::sctp::SCTPAssociation::processOutAndResponseArrived ( SCTPOutgoingSSNResetRequestParameter outRequestParam,
SCTPStreamResetResponseParameter responseParam 
)
protected

Referenced by processStreamResetArrived().

2759 {
2760  EV_TRACE << "processOutAndResponseArrived\n";
2761  if (getPath(remoteAddr)->ResetTimer->isScheduled()) {
2762  if (state->numResetRequests == 0) {
2763  SCTPResetTimer *tm = check_and_cast<SCTPResetTimer *>(PK(getPath(remoteAddr)->ResetTimer)->decapsulate());
2764  if (tm->getOutSN() == responseParam->getSrResSn()) {
2765  stopTimer(getPath(remoteAddr)->ResetTimer);
2766  delete state->resetChunk;
2767  state->resetChunk = nullptr;
2768  }
2769  delete tm;
2770  }
2771  }
2772  if (state->requests[outRequestParam->getSrResSn()].result != PERFORMED) {
2774  state->requests[outRequestParam->getSrResSn()].result = PERFORMED;
2775  }
2776  sendStreamResetResponse(outRequestParam->getSrReqSn(), PERFORMED);
2777  if (responseParam->getResult() == PERFORMED) {
2778  if (state->requests[responseParam->getSrResSn()].result != PERFORMED) {
2779  resetSsns();
2780  // resetExpectedSsns();
2781  state->resetPending = false;
2783  auto it = sctpMain->assocStatMap.find(assocId);
2784  it->second.numResetRequestsPerformed++;
2785  }
2786  }
2787  else {
2788  EV_INFO << "Reset Request failed. Send indication to app.\n";
2789  state->resetPending = false;
2791  }
2792  state->requests[responseParam->getSrResSn()].result = responseParam->getResult();
2793  return SCTP_E_IGNORE;
2794 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
void resetExpectedSsns()
Definition: SCTPAssociationStreamReset.cc:845
Definition: SCTPCommand.h:81
Definition: SCTPCommand.h:79
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
SCTP * sctpMain
Definition: SCTPAssociation.h:962
L3Address remoteAddr
Definition: SCTPAssociation.h:911
AssocStatMap assocStatMap
Definition: SCTP.h:171
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
uint16 numResetRequests
Definition: SCTPAssociation.h:644
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
#define PK(msg)
Definition: INETDefs.h:92
int32 assocId
Definition: SCTPAssociation.h:908
bool resetPending
Definition: SCTPAssociation.h:589
Definition: SCTPAssociation.h:144
void sendStreamResetResponse(uint32 srrsn, int result)
Definition: SCTPAssociationStreamReset.cc:763
void resetSsns()
Methods for Stream Reset.
Definition: SCTPAssociationStreamReset.cc:876
Definition: SCTPAssociation.h:91
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::processOutgoingResetRequestArrived ( SCTPOutgoingSSNResetRequestParameter requestParam)
protected

Referenced by processStreamResetArrived().

2339 {
2340  EV_TRACE << "processOutgoingResetRequestArrived\n";
2341  if (!state->firstPeerRequest && (requestParam->getSrReqSn() < (state->peerRequestSn)) ) {
2342  // Retransmission
2343  sendStreamResetResponse(requestParam->getSrReqSn(), NO_RESET);
2344  return;
2345  }
2346 
2347  if (state->findRequestNum(requestParam->getSrResSn())) {
2348  state->requests[requestParam->getSrResSn()].result = PERFORMED;
2350  state->waitForResponse = false;
2351  }
2352  if (getPath(remoteAddr)->ResetTimer->isScheduled()) {
2353  if (state->numResetRequests == 0) {
2354  SCTPResetTimer *tm = check_and_cast<SCTPResetTimer *>(PK(getPath(remoteAddr)->ResetTimer)->decapsulate());
2355  if ((tm->getOutSN() == requestParam->getSrResSn() && !tm->getOutAcked()) ||
2356  (tm->getInSN() == requestParam->getSrResSn() && !tm->getInAcked())) {
2357  stopTimer(getPath(remoteAddr)->ResetTimer);
2358  delete state->resetChunk;
2359  state->resetChunk = nullptr;
2360  state->resetPending = false;
2361  state->localRequestType = 0;
2362  state->stopReceiving = false;
2363  }
2364  delete tm;
2365  }
2366  }
2367  if (requestParam->getStreamNumbersArraySize() > 0) {
2368  uint16 count = 0;
2369  for (uint16 i = 0; i < requestParam->getStreamNumbersArraySize(); i++) {
2370  if (!receiveStreamPresent(requestParam->getStreamNumbers(i))) {
2371  sendStreamResetResponse(requestParam->getSrReqSn(), DENIED);
2372  return;
2373  }
2374  if (getExpectedSsnOfStream(requestParam->getStreamNumbers(i)) != 0) {
2375  count++;
2376  }
2377  }
2378  if (count == 0 && !(tsnGt(requestParam->getLastTsn(), state->gapList.getHighestTSNReceived()))) {
2379  sendStreamResetResponse(requestParam->getSrReqSn(), NOTHING_TO_DO);
2380  return;
2381  }
2382  }
2383  if (state->streamReset && !(tsnGt(requestParam->getLastTsn(), state->gapList.getHighestTSNReceived()))) {
2384  if (requestParam->getStreamNumbersArraySize() > 0) {
2385  for (uint16 i = 0; i < requestParam->getStreamNumbersArraySize(); i++) {
2386  resetExpectedSsn(requestParam->getStreamNumbers(i));
2387  }
2388  } else {
2390  }
2391  EV_DETAIL << "processOutgoingResetRequestArrived: resetExpectedSsns\n";
2392  if (state->sendResponse == PERFORMED) {
2393  sendStreamResetResponse(requestParam->getSrReqSn(), PERFORMED);
2394  state->sendResponse = 0;
2395  } else {
2397  state->responseSn = requestParam->getSrReqSn();
2398  }
2399  } else if (tsnGt(requestParam->getLastTsn(), state->gapList.getHighestTSNReceived())) {
2400  state->lastTsnBeforeReset = requestParam->getLastTsn();
2401  state->peerRequestSn = requestParam->getSrReqSn();
2402  sendStreamResetResponse(requestParam->getSrReqSn(), DEFERRED);
2403  state->incomingRequest = requestParam->dup();
2404  state->incomingRequestSet = true;
2405  state->resetDeferred = true;
2406  // state->firstPeerRequest = false;
2407  } else {
2408  sendStreamResetResponse(requestParam->getSrReqSn(), PERFORMED);
2409  }
2410 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
void resetExpectedSsns()
Definition: SCTPAssociationStreamReset.cc:845
int count(const std::vector< T > &v, const T &a)
Definition: stlutils.h:58
void resetExpectedSsn(uint16 id)
Definition: SCTPAssociationStreamReset.cc:853
uint16 sendResponse
Definition: SCTPAssociation.h:642
uint16 localRequestType
Definition: SCTPAssociation.h:810
bool waitForResponse
Definition: SCTPAssociation.h:789
bool firstPeerRequest
Definition: SCTPAssociation.h:790
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
uint32 lastTsnBeforeReset
Definition: SCTPAssociation.h:798
Definition: SCTPAssociation.h:148
bool findRequestNum(uint32 num)
Definition: SCTPAssociationBase.cc:511
Definition: SCTPAssociation.h:145
SCTPGapList gapList
Definition: SCTPAssociation.h:619
L3Address remoteAddr
Definition: SCTPAssociation.h:911
Definition: SCTPAssociation.h:149
bool stopReceiving
Definition: SCTPAssociation.h:591
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
uint16 numResetRequests
Definition: SCTPAssociation.h:644
bool receiveStreamPresent(uint16 sid)
Definition: SCTPAssociationStreamReset.cc:900
SCTPParameter * incomingRequest
Definition: SCTPAssociation.h:800
virtual SCTPParameter * dup() const override
Definition: SCTPMessage_m.h:1257
uint32 getHighestTSNReceived() const
Definition: SCTPGapList.h:96
static int32 tsnGt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1081
#define PK(msg)
Definition: INETDefs.h:92
bool resetDeferred
Definition: SCTPAssociation.h:787
bool resetPending
Definition: SCTPAssociation.h:589
uint16_t uint16
Definition: Compat.h:32
Definition: SCTPAssociation.h:144
Definition: SCTPAssociation.h:143
void sendStreamResetResponse(uint32 srrsn, int result)
Definition: SCTPAssociationStreamReset.cc:763
uint32 getExpectedSsnOfStream(uint16 id)
Definition: SCTPAssociationStreamReset.cc:861
uint32 responseSn
Definition: SCTPAssociation.h:643
uint32 peerRequestSn
Definition: SCTPAssociation.h:795
bool incomingRequestSet
Definition: SCTPAssociation.h:602
bool streamReset
Definition: SCTPAssociation.h:785
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::processPacketDropArrived ( SCTPPacketDropChunk pktdrop)
protected

Referenced by process_RCV_Message().

3375 {
3376  bool dataReceived = false;
3377 
3378  if (packetDropChunk->getMFlag() == false) {
3379  EV_TRACE << "processPacketDropArrived" << endl;
3380  if (packetDropChunk->getEncapsulatedPacket() != nullptr) {
3381  SCTPMessage *sctpmsg = (SCTPMessage *)(packetDropChunk->decapsulate());
3382  const uint32 numberOfChunks = sctpmsg->getChunksArraySize();
3383  EV_DETAIL << "numberOfChunks=" << numberOfChunks << endl;
3384  for (uint32 i = 0; i < numberOfChunks; i++) {
3385  SCTPChunk *chunk = (SCTPChunk *)(sctpmsg->removeChunk());
3386  const uint8 type = chunk->getChunkType();
3387  switch (type) {
3388  case DATA: {
3389  SCTPDataChunk *dataChunk = check_and_cast<SCTPDataChunk *>(chunk);
3390  const uint32 tsn = dataChunk->getTsn();
3391  auto pq = retransmissionQ->payloadQueue.find(tsn);
3392  if ((pq != retransmissionQ->payloadQueue.end()) &&
3393  (!chunkHasBeenAcked(pq->second))) {
3394  EV_DETAIL << simTime() << ": Packet Drop for TSN "
3395  << pq->second->tsn << " on path "
3396  << pq->second->getLastDestination()
3397  << " -> transmitting it again" << endl;
3398  putInTransmissionQ(pq->first, pq->second);
3399  }
3400  delete dataChunk->decapsulate();
3401  dataReceived = true;
3402  break;
3403  }
3404 
3405  case SACK:
3406  sendSack();
3407  break;
3408 
3409  case INIT:
3411  retransmitInit();
3413  break;
3414 
3415  case HEARTBEAT:
3417  break;
3418 
3419  case HEARTBEAT_ACK:
3420  break;
3421 
3422  case SHUTDOWN:
3426  break;
3427 
3428  case SHUTDOWN_ACK:
3432  break;
3433 
3434  case COOKIE_ECHO:
3438  break;
3439 
3440  case COOKIE_ACK:
3442  break;
3443 
3444  case ASCONF:
3445  stopTimer(getPath(remoteAddr)->AsconfTimer);
3446  retransmitAsconf();
3447  startTimer(getPath(remoteAddr)->AsconfTimer, getPath(remoteAddr)->pathRto);
3448  break;
3449 
3450  case FORWARD_TSN:
3451  if (peekAbandonedChunk(getPath(remoteAddr)) != nullptr) {
3452  SCTPMessage *sctpmsg = new SCTPMessage();
3453  sctpmsg->setBitLength(SCTP_COMMON_HEADER * 8);
3454  SCTPForwardTsnChunk *forwardChunk = createForwardTsnChunk(remoteAddr);
3456  SCTPAuthenticationChunk *authChunk = createAuthChunk();
3457  sctpmsg->addChunk(authChunk);
3458  }
3459  sctpmsg->addChunk(forwardChunk);
3460  }
3461  break;
3462  default:
3463  throw cRuntimeError("unknown chunk type");
3464  break;
3465 
3466  }
3467  delete chunk;
3468  }
3469  disposeOf(sctpmsg);
3470  } else {
3471  EV_INFO << "no chunk encapsulated" << endl;
3472  }
3473  state->peerRwnd = packetDropChunk->getMaxRwnd()
3474  - packetDropChunk->getQueuedData()
3475  - getOutstandingBytes();
3476  statisticsPeerRwnd->record(state->peerRwnd);
3477  return dataReceived;
3478  }
3479  return false;
3480 }
uint8_t uint8
Definition: Compat.h:34
Definition: SCTPAssociation.h:111
int32 getOutstandingBytes() const
Definition: SCTPAssociationUtil.cc:2721
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
void putInTransmissionQ(uint32 tsn, SCTPDataVariables *chunk)
Definition: SCTPAssociationUtil.cc:2870
Definition: SCTPAssociation.h:118
Definition: SCTPAssociation.h:119
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
Definition: SCTPAssociation.h:121
uint64 peerRwnd
Definition: SCTPAssociation.h:610
Definition: SCTPAssociation.h:122
void retransmitCookieEcho()
Definition: SCTPAssociationUtil.cc:955
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
Definition: SCTPAssociation.h:115
SCTPForwardTsnChunk * createForwardTsnChunk(const L3Address &pid)
Definition: SCTPAssociationUtil.cc:1283
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
Definition: SCTPAssociation.h:116
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void disposeOf(SCTPMessage *sctpmsg)
Definition: SCTPAssociationUtil.cc:2800
Definition: SCTPAssociation.h:130
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
void retransmitShutdown()
Definition: SCTPAssociationUtil.cc:1161
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
bool auth
Definition: SCTPAssociation.h:822
void sendHeartbeat(const SCTPPathVariables *path)
Definition: SCTPAssociationUtil.cc:977
simtime_t initRexmitTimeout
Definition: SCTPAssociation.h:650
L3Address remoteAddr
Definition: SCTPAssociation.h:911
SCTPDataVariables * peekAbandonedChunk(const SCTPPathVariables *path)
Definition: SCTPAssociationUtil.cc:2302
Definition: SCTPAssociation.h:112
cMessage * T2_ShutdownTimer
Definition: SCTPAssociation.h:920
void retransmitAsconf()
Definition: SCTPAssociationAddIP.cc:167
void retransmitInit()
Retransmitting chunks.
Definition: SCTPAssociationUtil.cc:712
uint32_t uint32
Definition: Compat.h:30
Definition: SCTPAssociation.h:114
void sendSack()
Definition: SCTPAssociationUtil.cc:1764
Definition: SCTPAssociation.h:129
bool peerAuth
Definition: SCTPAssociation.h:821
void sendCookieAck(const L3Address &dest)
Definition: SCTPAssociationUtil.cc:1034
cOutVector * statisticsPeerRwnd
Definition: SCTPAssociation.h:983
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
void retransmitShutdownAck()
Definition: SCTPAssociationUtil.cc:1174
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool chunkHasBeenAcked(const SCTPDataVariables *chunk) const
Definition: SCTPAssociation.h:1448
void inet::sctp::SCTPAssociation::processResetResponseArrived ( SCTPStreamResetResponseParameter responseParam)
protected

Referenced by processStreamResetArrived().

2533 {
2534  EV_TRACE << "processResetResponseArrived \n";
2535  if (getPath(remoteAddr)->ResetTimer->isScheduled()) {
2536  if (PK(getPath(remoteAddr)->ResetTimer)->hasEncapsulatedPacket() &&
2537  (state->numResetRequests == 0 || (state->getNumRequestsNotPerformed() == 1 && responseParam->getResult() != DEFERRED))) {
2538  SCTPResetTimer *tm = check_and_cast<SCTPResetTimer *>(PK(getPath(remoteAddr)->ResetTimer)->decapsulate());
2539  EV_DETAIL << "SrResSn=" << responseParam->getSrResSn() << " tmOut=" << tm->getOutSN() << " tmIn= " << tm->getInSN() << "\n";
2540  if (tm->getOutSN() == responseParam->getSrResSn() || tm->getInSN() == responseParam->getSrResSn() || responseParam->getResult() > DEFERRED) {
2541  stopTimer(getPath(remoteAddr)->ResetTimer);
2542  delete state->resetChunk;
2543  state->resetChunk = nullptr;
2545  if (state->streamsPending.size() == 0) {
2546  delete state->resetInfo;
2547  state->resetInfo = nullptr;
2548  }
2549  }
2550  delete tm;
2551  if (responseParam->getResult() > DEFERRED) {
2552  state->resetPending = false;
2553  state->resetRequested = false;
2554  state->waitForResponse = false;
2555  state->streamsPending.clear();
2556  state->resetOutStreams.clear();
2557  state->resetInStreams.clear();
2558  return;
2559  }
2560  }
2561  } else {
2562  if ((PK(getPath(remoteAddr)->ResetTimer)->hasEncapsulatedPacket())) {
2563  delete ((PK(getPath(remoteAddr)->ResetTimer)->decapsulate()));
2564  }
2565  }
2566  if (state->requests[responseParam->getSrResSn()].result != PERFORMED) {
2567  if (responseParam->getResult() == PERFORMED) {
2568  if (state->resetRequested) {
2569  if (state->resetOutStreams.size() > 0) {
2570  for (auto & elem : state->resetOutStreams) {
2571  resetSsn((elem));
2572  }
2573  state->resetOutStreams.clear();
2574  } else if (state->numAddedOutStreams == 0 && state->numAddedInStreams == 0) {
2575  resetSsns();
2576  }
2577  if (state->streamsPending.size() == 0)
2578  state->resetRequested = false;
2579  }
2580  state->resetPending = false;
2581  state->waitForResponse = false;
2582  if (responseParam->getReceiversNextTsn() != 0) {
2583  state->nextTSN = responseParam->getReceiversNextTsn();
2584  state->lastTsnAck = responseParam->getReceiversNextTsn() - 1;
2585  state->gapList.forwardCumAckTSN(responseParam->getSendersNextTsn() - 1);
2586  state->peerTsnAfterReset = responseParam->getSendersNextTsn();
2587  state->stopReceiving = false;
2588  state->stopOldData = true;
2589  if (state->resetInStreams.size() > 0) {
2590  for (auto & elem : state->resetInStreams) {
2591  resetExpectedSsn((elem));
2592  }
2593  state->resetInStreams.clear();
2594  } else {
2596  }
2597  // sendSack();
2598  }
2599  if (state->localRequestType == ADD_BOTH) {
2600  if (state->numAddedOutStreams > 0) {
2604  } else if (state->numAddedInStreams > 0) {
2607  state->numAddedInStreams = 0;
2608  }
2609  } else if (state->localRequestType == ADD_INCOMING) {
2612  state->numAddedInStreams = 0;
2613  } else if (state->localRequestType == ADD_OUTGOING) {
2617  }
2619  auto it = sctpMain->assocStatMap.find(assocId);
2620  it->second.numResetRequestsPerformed++;
2621  } else {
2622  EV_INFO << "Reset Request failed. Send indication to app.\n";
2623  if (responseParam->getResult() == DEFERRED) {
2625  } else {
2626  state->resetPending = false;
2628  }
2629  }
2630  state->requests[responseParam->getSrResSn()].result = responseParam->getResult();
2631  }
2632  if (state->incomingRequestSet && state->incomingRequest != nullptr && state->streamsPending.size() == 0) {
2633  delete state->incomingRequest;
2634  state->incomingRequest = nullptr;
2635  state->incomingRequestSet = false;
2636  }
2637 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
uint32 lastTsnAck
Definition: SCTPAssociation.h:614
bool resetRequested
Definition: SCTPAssociation.h:590
Definition: SCTPAssociation.h:155
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
void forwardCumAckTSN(const uint32 cumAckTSN)
Definition: SCTPGapList.cc:339
void resetExpectedSsns()
Definition: SCTPAssociationStreamReset.cc:845
void resetExpectedSsn(uint16 id)
Definition: SCTPAssociationStreamReset.cc:853
Definition: SCTPCommand.h:81
SCTPResetInfo * resetInfo
Definition: SCTPAssociation.h:808
uint16 localRequestType
Definition: SCTPAssociation.h:810
bool waitForResponse
Definition: SCTPAssociation.h:789
Definition: SCTPCommand.h:79
void(SCTPAssociation::* ssAddInStreams)(uint32 inStreams)
Definition: SCTPAssociation.h:1289
uint32 pathErrorCount
Definition: SCTPAssociation.h:299
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
uint16 numAddedOutStreams
Definition: SCTPAssociation.h:672
uint32 outboundStreams
Definition: SCTPAssociation.h:943
uint32 inboundStreams
Definition: SCTPAssociation.h:942
std::list< uint16 > streamsPending
Definition: SCTPAssociation.h:803
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void(SCTPAssociation::* ssAddOutStreams)(uint32 outStreams)
Definition: SCTPAssociation.h:1290
SCTPGapList gapList
Definition: SCTPAssociation.h:619
L3Address remoteAddr
Definition: SCTPAssociation.h:911
AssocStatMap assocStatMap
Definition: SCTP.h:171
Definition: SCTPAssociation.h:149
bool stopReceiving
Definition: SCTPAssociation.h:591
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
uint16 numResetRequests
Definition: SCTPAssociation.h:644
void resetSsn(uint16 id)
Definition: SCTPAssociationStreamReset.cc:884
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
SCTPParameter * incomingRequest
Definition: SCTPAssociation.h:800
std::list< uint16 > resetOutStreams
Definition: SCTPAssociation.h:801
Definition: SCTPAssociation.h:162
uint16 numAddedInStreams
Definition: SCTPAssociation.h:673
#define PK(msg)
Definition: INETDefs.h:92
int32 assocId
Definition: SCTPAssociation.h:908
bool stopOldData
Definition: SCTPAssociation.h:592
uint32 nextTSN
Definition: SCTPAssociation.h:613
bool resetPending
Definition: SCTPAssociation.h:589
Definition: SCTPAssociation.h:154
SSFunctions ssFunctions
Definition: SCTPAssociation.h:1294
Definition: SCTPAssociation.h:144
void resetSsns()
Methods for Stream Reset.
Definition: SCTPAssociationStreamReset.cc:876
uint16 getNumRequestsNotPerformed()
Definition: SCTPAssociationBase.cc:555
std::list< uint16 > resetInStreams
Definition: SCTPAssociation.h:802
bool incomingRequestSet
Definition: SCTPAssociation.h:602
uint32 peerTsnAfterReset
Definition: SCTPAssociation.h:797
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPEventCode inet::sctp::SCTPAssociation::processSackArrived ( SCTPSackChunk sackChunk)
protected

Referenced by process_RCV_Message().

1004 {
1005  simtime_t rttEstimation = SIMTIME_MAX;
1006  const uint64 sendBufferBeforeUpdate = state->sendBuffer;
1007  SCTPPathVariables *path = getPath(remoteAddr); // Path for *this* SACK!
1008  const uint64 arwnd = sackChunk->getA_rwnd();
1009  const uint32 tsna = sackChunk->getCumTsnAck();
1010  uint32 highestNewAck = tsna; // Highest newly acked TSN
1011  const uint16 numDups = sackChunk->getNumDupTsns();
1012  SCTP::AssocStat *assocStat = sctpMain->getAssocStat(assocId);
1013  bool dropFilledGap = false;
1014  const uint32 msgRwnd = sackChunk->getMsg_rwnd();
1015 
1016  // ====== Put information from SACK into GapList =========================
1017  SCTPGapList sackGapList;
1018  sackGapList.setInitialCumAckTSN(sackChunk->getCumTsnAck());
1019  uint32 lastTSN = sackChunk->getCumTsnAck();
1020  for (uint32 i = 0; i < sackChunk->getNumGaps(); i++) {
1021  uint32 tsn = sackChunk->getGapStart(i);
1022  assert(tsnLt(lastTSN + 1, tsn));
1023  lastTSN = tsn;
1024  while (tsnLe(tsn, sackChunk->getGapStop(i))) {
1025  bool dummy;
1026  sackGapList.updateGapList(tsn, dummy, true); // revokable TSN
1027  tsn++;
1028  }
1029  lastTSN = sackChunk->getGapStop(i);
1030  }
1031  if (assocStat) {
1032  assocStat->sumRGapRanges += ((sackChunk->getCumTsnAck() <= lastTSN) ?
1033  (uint64)(lastTSN - sackChunk->getCumTsnAck()) :
1034  (uint64)(sackChunk->getCumTsnAck() - lastTSN));
1035  }
1036  if (sackChunk->getNrSubtractRGaps() == false) {
1037  lastTSN = sackChunk->getCumTsnAck();
1038  for (uint32 i = 0; i < sackChunk->getNumNrGaps(); i++) {
1039  uint32 tsn = sackChunk->getNrGapStart(i);
1040  assert(tsnLt(lastTSN + 1, tsn));
1041  lastTSN = tsn;
1042  while (tsnLe(tsn, sackChunk->getNrGapStop(i))) {
1043  bool dummy;
1044  sackGapList.updateGapList(tsn, dummy, false); // non-revokable TSN
1045  tsn++;
1046  }
1047  lastTSN = sackChunk->getNrGapStop(i);
1048  }
1049  }
1050  else {
1051  lastTSN = sackChunk->getCumTsnAck();
1052  for (uint32 i = 0; i < sackChunk->getNumNrGaps(); i++) {
1053  uint32 tsn = sackChunk->getNrGapStart(i);
1054  assert(tsnLt(lastTSN + 1, tsn));
1055  lastTSN = tsn;
1056  while (tsnLe(tsn, sackChunk->getNrGapStop(i))) {
1057  if (sackGapList.tsnIsRevokable(tsn) == false) {
1058  bool dummy;
1059  sackGapList.updateGapList(tsn, dummy, false); // non-revokable TSN
1060  }
1061  tsn++;
1062  }
1063  lastTSN = sackChunk->getNrGapStop(i);
1064  }
1065  }
1066  if (assocStat) {
1067  assocStat->sumNRGapRanges += (sackChunk->getCumTsnAck() <= lastTSN) ?
1068  (uint64)(lastTSN - sackChunk->getCumTsnAck()) :
1069  (uint64)(sackChunk->getCumTsnAck() - lastTSN);
1070  }
1071  const uint16 numGaps = sackGapList.getNumGaps(SCTPGapList::GT_Any);
1072 
1073  // ====== Print some information =========================================
1074  EV_DETAIL << "##### SACK Processing: TSNa=" << tsna << " #####" << endl;
1075  for (auto & elem : sctpPathMap) {
1076  SCTPPathVariables *myPath = elem.second;
1077  EV_DETAIL << "Path " << myPath->remoteAddress << ":\t"
1078  << "outstanding=" << path->outstandingBytes << "\t"
1079  << "T3scheduled=" << path->T3_RtxTimer->getArrivalTime() << " "
1080  << (path->T3_RtxTimer->isScheduled() ? "[ok]" : "[NOT SCHEDULED]") << "\t"
1081  << "findPseudoCumAck=" << ((myPath->findPseudoCumAck == true) ? "true" : "false") << "\t"
1082  << "pseudoCumAck=" << myPath->pseudoCumAck << "\t"
1083  << "newPseudoCumAck=" << ((myPath->newPseudoCumAck == true) ? "true" : "false") << "\t"
1084  << "findRTXPseudoCumAck=" << ((myPath->findRTXPseudoCumAck == true) ? "true" : "false") << "\t"
1085  << "rtxPseudoCumAck=" << myPath->rtxPseudoCumAck << "\t"
1086  << "newRTXPseudoCumAck=" << ((myPath->newRTXPseudoCumAck == true) ? "true" : "false") << "\t"
1087  << endl;
1088  }
1089 
1090  EV_INFO << "Before processSackArrived for path " << path->remoteAddress
1091  << " with tsna=" << tsna << ":" << endl;
1092 
1093  // ====== SACK Sequence Number Check =====================================
1094  EV_INFO << "SACK Seq Number = " << sackChunk->getSackSeqNum() << endl;
1095  if ((state->checkSackSeqNumber == true) &&
1096  (sackChunk->getSackSeqNum() <= state->incomingSackSeqNum))
1097  {
1098  EV_DETAIL << "Out-of-data SACK: " << sackChunk->getSackSeqNum()
1099  << " < " << state->incomingSackSeqNum << endl;
1100  return SCTP_E_IGNORE;
1101  }
1102  state->incomingSackSeqNum = sackChunk->getSackSeqNum();
1103 
1104  // ====== Record statistics ==============================================
1105  numGapBlocks->record(numGaps);
1106  statisticsRevokableGapBlocksInLastSACK->record(sackGapList.getNumGaps(SCTPGapList::GT_Revokable));
1108 
1109  path->vectorPathAckedTSNCumAck->record(tsna);
1110  if (assocStat) {
1111  assocStat->numDups += numDups;
1112  }
1113 
1114  // ====== Initialize some variables ======================================
1115  for (auto & elem : sctpPathMap) {
1116  SCTPPathVariables *myPath = elem.second;
1117  // T.D. 26.03.09: Remember outstanding bytes before this update
1118  // Values are necessary for updating the congestion window!
1119  myPath->outstandingBytesBeforeUpdate = myPath->outstandingBytes; // copy from myPath, not from path!
1120  myPath->requiresRtx = false;
1121  myPath->lowestTSNRetransmitted = false;
1122  myPath->findLowestTSN = true;
1123  myPath->gapAckedChunksInLastSACK = 0;
1124  myPath->gapNRAckedChunksInLastSACK = 0;
1125  myPath->gapUnackedChunksInLastSACK = 0;
1126  myPath->newlyAckedBytes = 0;
1127  myPath->newCumAck = false; // Check whether CumAck affects this path
1128  // for all destinations, set newPseudoCumAck to FALSE.
1129  myPath->newPseudoCumAck = false;
1130  myPath->newRTXPseudoCumAck = false; // CUCv2
1131  myPath->sawNewAck = false;
1132  myPath->lowestNewAckInSack = 0;
1133  myPath->highestNewAckInSack = 0;
1134  myPath->newOldestChunkSendTime = simTime() + 9999.99; // initialize to more than simTime()
1135  if (myPath == path) {
1136  myPath->lastAckTime = simTime();
1137  }
1138  }
1139 
1140  // ====== Zero Window Probing ============================================
1141  if ((state->peerAllowsChunks) && (msgRwnd > 0) && (state->zeroWindowProbing)) {
1142  state->zeroWindowProbing = false;
1143  }
1144  if ((state->zeroWindowProbing) && (arwnd > 0)) {
1145  state->zeroWindowProbing = false;
1146  }
1147 
1148  // #######################################################################
1149  // #### Processing of CumAck ####
1150  // #######################################################################
1151 
1152  if (tsnGt(tsna, state->lastTsnAck)) { // Handle new CumAck
1153  EV_INFO << "===== Handling new CumAck for TSN " << tsna << " =====" << endl;
1154 
1155  SCTPDataVariables *myChunk = retransmissionQ->getChunk(state->lastTsnAck + 1);
1156  if ((myChunk != nullptr) && (myChunk->wasPktDropped) &&
1157  (myChunk->getLastDestinationPath()->fastRecoveryActive))
1158  {
1159  dropFilledGap = true;
1160  EV_DETAIL << "TSN " << myChunk->tsn << " filled gap" << endl;
1161  }
1162 
1163  // We have got new chunks acked, and our cum ack point is advanced ...
1164  // Depending on the parameter osbWithHeader ackedBytes are with or without the header bytes.
1165  // T.D. 23.03.09: path->newlyAckedBytes is updated in dequeueAckedChunks()!
1166  dequeueAckedChunks(tsna, path, rttEstimation); // chunks with tsn between lastTsnAck and tsna are removed from the transmissionQ and the retransmissionQ; outstandingBytes are decreased
1167 
1168  state->lastTsnAck = tsna;
1169  if (tsnGt(tsna, state->advancedPeerAckPoint)) {
1170  state->advancedPeerAckPoint = tsna;
1171  state->ackPointAdvanced = true;
1172  }
1173  // ====== Slow Path RTT Calculation ===================================
1174  if ((state->allowCMT == true) &&
1175  (state->cmtSlowPathRTTUpdate == true) &&
1176  (path->waitingForRTTCalculaton == true) &&
1177  ((path->tsnForRTTCalculation == tsna) ||
1178  (tsnLt(path->tsnForRTTCalculation, tsna))))
1179  {
1180  // Got update from CumAck -> no need for Slow Path RTT calculation
1181  path->waitingForRTTCalculaton = false;
1182  }
1183  }
1184  else if (tsnLt(tsna, state->lastTsnAck)) {
1185  EV_DETAIL << "Stale CumAck (" << tsna << " < " << state->lastTsnAck << ")"
1186  << endl;
1187  // ====== Slow Path RTT Calculation ===================================
1188  if ((state->allowCMT == true) &&
1189  (state->cmtSlowPathRTTUpdate == true) &&
1190  (path->waitingForRTTCalculaton == true))
1191  {
1192  // Slow Path Update
1193  // Look for a CumAck or GapAck of the remembered chunk on this path.
1194  // If it has been found, we can compute the RTT of this path.
1195 
1196  // ====== Look for matching CumAck first ===========================
1197  bool renewRTT = false;
1198  if ((tsnLt(path->tsnForRTTCalculation, tsna)) ||
1199  (path->tsnForRTTCalculation == tsna))
1200  {
1201  renewRTT = true;
1202  }
1203  // ====== Look for matching GapAck =================================
1204  else if ((numGaps > 0) &&
1205  ((path->tsnForRTTCalculation == sackGapList.getGapStop(SCTPGapList::GT_Any, numGaps - 1)) ||
1206  (tsnLt(path->tsnForRTTCalculation, sackGapList.getGapStop(SCTPGapList::GT_Any, numGaps - 1)))))
1207  {
1208  for (int32 key = 0; key < numGaps; key++) {
1209  const uint32 lo = sackGapList.getGapStart(SCTPGapList::GT_Any, key);
1210  const uint32 hi = sackGapList.getGapStop(SCTPGapList::GT_Any, key);
1211  if ((path->tsnForRTTCalculation == lo) ||
1212  (path->tsnForRTTCalculation == hi) ||
1213  (tsnLt(lo, path->tsnForRTTCalculation) &&
1214  tsnLt(path->tsnForRTTCalculation, hi)))
1215  {
1216  renewRTT = true;
1217  break;
1218  }
1219  }
1220  }
1221 
1222  if (renewRTT) {
1223  rttEstimation = simTime() - path->txTimeForRTTCalculation;
1224  path->waitingForRTTCalculaton = false;
1225  pmRttMeasurement(path, rttEstimation);
1226 
1227  EV_DETAIL << simTime() << ": SlowPathRTTUpdate from stale SACK - rtt="
1228  << rttEstimation << " from TSN "
1229  << path->tsnForRTTCalculation
1230  << " on path " << path->remoteAddress
1231  << " => RTO=" << path->pathRto << endl;
1232  }
1233  }
1234  return SCTP_E_IGNORE;
1235  }
1236 
1237  // ====== Handle reneging ================================================
1238  if ((numGaps == 0) && (tsnLt(tsna, state->highestTsnAcked))) {
1239  // Reneging, type 0:
1240  // In a previous SACK, chunks up to highestTsnAcked have been acked.
1241  // This SACK contains a CumAck < highestTsnAcked
1242  // => rereg TSNs from CumAck+1 to highestTsnAcked
1243  // => new highestTsnAcked = CumAck
1244  EV_DETAIL << "numGaps=0 && tsna " << tsna
1245  << " < highestTsnAcked " << state->highestTsnAcked << endl;
1247  while (i >= tsna + 1) {
1248  SCTPDataVariables *myChunk = retransmissionQ->getChunk(i);
1249  if (myChunk) {
1250  if (chunkHasBeenAcked(myChunk)) {
1251  tsnWasReneged(myChunk, path, 0);
1252  }
1253  }
1254  i--;
1255  }
1256  state->highestTsnAcked = tsna;
1257  }
1258 
1259  // #######################################################################
1260  // #### Processing of GapAcks ####
1261  // #######################################################################
1262 
1263  if ((numGaps > 0) && (!retransmissionQ->payloadQueue.empty())) {
1264  EV_INFO << "===== Handling GapAcks after CumTSNAck " << tsna << " =====" << endl;
1265  EV_INFO << "We got " << numGaps << " gap reports" << endl;
1266 
1267  // We got fragment reports... check for newly acked chunks.
1268  const uint32 queuedChunks = retransmissionQ->payloadQueue.size();
1269  EV_DETAIL << "Number of chunks in retransmissionQ: " << queuedChunks
1270  << " highestGapStop: " << sackGapList.getGapStop(SCTPGapList::GT_Any, numGaps - 1)
1271  << " highestTsnAcked: " << state->highestTsnAcked << endl;
1272 
1273  // ====== Handle reneging =============================================
1274  // highest gapStop smaller than highestTsnAcked: there might have been reneging
1275  if (tsnLt(sackGapList.getGapStop(SCTPGapList::GT_Any, numGaps - 1), state->highestTsnAcked)) {
1276  // Reneging, type 2:
1277  // In a previous SACK, chunks up to highestTsnAcked have been acked.
1278  // This SACK contains a last gap ack < highestTsnAcked
1279  // => rereg TSNs from last gap ack to highestTsnAcked
1280  // => new highestTsnAcked = last gap ack
1282  while (i >= sackGapList.getGapStop(SCTPGapList::GT_Any, numGaps - 1) + 1) {
1283  // ====== Looking up TSN in retransmission queue ================
1284  SCTPDataVariables *myChunk = retransmissionQ->getChunk(i);
1285  if (myChunk) {
1286  if (chunkHasBeenAcked(myChunk)) {
1287  EV_INFO << "TSN " << i << " was found. It has been un-acked." << endl;
1288  tsnWasReneged(myChunk, path, 2);
1289  EV_DETAIL << "highestTsnAcked now " << state->highestTsnAcked << endl;
1290  }
1291  }
1292  else {
1293  EV_INFO << "TSN " << i << " not found in retransmissionQ" << endl;
1294  }
1295  i--;
1296  }
1297  state->highestTsnAcked = sackGapList.getGapStop(SCTPGapList::GT_Any, numGaps - 1);
1298  }
1299 
1300  // ====== Looking for changes in the gap reports ======================
1301  EV_INFO << "Looking for changes in gap reports" << endl;
1302  // Get Pseudo CumAck for paths
1303  uint32 lo1 = tsna;
1304  uint32 tsnCheck = tsna + 1; // Just to make sure that no TSN is misssed
1305  for (int32 key = 0; key < numGaps; key++) {
1306  const uint32 lo = sackGapList.getGapStart(SCTPGapList::GT_Any, key);
1307  const uint32 hi = sackGapList.getGapStop(SCTPGapList::GT_Any, key);
1308 
1309  // ====== Iterate over TSNs *not* listed in gap reports ============
1310  for (uint32 pos = lo1 + 1; pos <= lo - 1; pos++) {
1311  assert(tsnCheck == pos);
1312  tsnCheck++;
1313  SCTPDataVariables *myChunk = retransmissionQ->getChunk(pos);
1314  if (myChunk) {
1315  SCTPPathVariables *myChunkLastPath = myChunk->getLastDestinationPath();
1316  assert(myChunkLastPath != nullptr);
1317  // T.D. 22.11.09: CUCv2 - chunk is *not* acked
1318  cucProcessGapReports(myChunk, myChunkLastPath, false);
1319  }
1320  }
1321  lo1 = sackGapList.getGapStop(SCTPGapList::GT_Any, key);
1322  // ====== Iterate over TSNs in gap reports =========================
1323  EV_INFO << "Examine TSNs between " << lo << " and " << hi << endl;
1324  for (uint32 pos = lo; pos <= hi; pos++) {
1325  bool chunkFirstTime = true;
1326  assert(tsnCheck == pos);
1327  tsnCheck++;
1328  SCTPDataVariables *myChunk = retransmissionQ->getChunkFast(pos, chunkFirstTime);
1329  if (myChunk) {
1330  if (chunkHasBeenAcked(myChunk) == false) {
1331  SCTPPathVariables *myChunkLastPath = myChunk->getLastDestinationPath();
1332  assert(myChunkLastPath != nullptr);
1333  // CUCv2 - chunk is acked
1334  cucProcessGapReports(myChunk, myChunkLastPath, true);
1335  // This chunk has been acked newly.
1336  // Let's process this new acknowledgement!
1337  handleChunkReportedAsAcked(highestNewAck, rttEstimation, myChunk,
1338  path /* i.e. the SACK path for RTT measurement! */,
1339  sackGapList.tsnIsNonRevokable(myChunk->tsn));
1340  }
1341  else {
1342  // Slow Path RTT Calculation
1343  if ((path->tsnForRTTCalculation == myChunk->tsn) &&
1344  (path->waitingForRTTCalculaton == true) &&
1345  (state->allowCMT == true) &&
1346  (state->cmtSlowPathRTTUpdate == true) &&
1347  (myChunk->getLastDestinationPath() == path))
1348  {
1349  const simtime_t rttEstimation = simTime() - path->txTimeForRTTCalculation;
1350  path->waitingForRTTCalculaton = false;
1351  pmRttMeasurement(path, rttEstimation);
1352 
1353  EV << simTime() << ": SlowPathRTTUpdate from gap report - rtt="
1354  << rttEstimation << " from TSN "
1355  << path->tsnForRTTCalculation
1356  << " on path " << path->remoteAddress
1357  << " => RTO=" << path->pathRto << endl;
1358  }
1359  }
1360  }
1361  // ====== R-acked chunk became NR-acked =========================
1362  else if (sackGapList.tsnIsNonRevokable(pos)) {
1363  bool chunkFirstTime = false;
1364  SCTPDataVariables *myChunk = retransmissionQ->getChunkFast(pos, chunkFirstTime);
1365  if (myChunk) {
1366  // myChunk != nullptr -> R-acked before, but not NR-acked
1367  handleChunkReportedAsAcked(highestNewAck, rttEstimation, myChunk,
1368  path /* i.e. the SACK path for RTT measurement! */,
1369  sackGapList.tsnIsNonRevokable(myChunk->tsn));
1370  // All NR-acked chunks have chunkMap->getChunk(pos) == nullptr!
1371  }
1372  }
1373  }
1374  }
1375  state->highestTsnAcked = sackGapList.getGapStop(SCTPGapList::GT_Any, numGaps - 1);
1376 
1377  // ====== Examine chunks between the gap reports ======================
1378  // They might have to be retransmitted or they could have been removed
1379  uint32 lo = tsna;
1380  for (int32 key = 0; key < numGaps; key++) {
1381  const uint32 hi = sackGapList.getGapStart(SCTPGapList::GT_Any, key);
1382  for (uint32 pos = lo + 1; pos <= hi - 1; pos++) {
1383  bool chunkFirstTime = true;
1384  SCTPDataVariables *myChunk = retransmissionQ->getChunkFast(pos, chunkFirstTime);
1385  if (myChunk) {
1386  handleChunkReportedAsMissing(sackChunk, highestNewAck, myChunk,
1387  path /* i.e. the SACK path for RTT measurement! */);
1388  }
1389  else {
1390  EV_INFO << "TSN " << pos << " not found in retransmissionQ" << endl;
1391  }
1392  }
1393  lo = sackGapList.getGapStop(SCTPGapList::GT_Any, key);
1394  }
1395 
1396  // ====== Validity checks =============================================
1397  path->vectorPathAckedTSNGapAck->record(state->highestTsnAcked);
1398  }
1399 
1400  // ====== Buffer space may have been gained => tell application ==========
1401  if (sendBufferBeforeUpdate != state->sendBuffer) {
1402  generateSendQueueAbatedIndication(sendBufferBeforeUpdate - state->sendBuffer);
1403  }
1404 
1405  // ====== Update Fast Recovery status, according to SACK =================
1407 
1408  // ====== Update RTT measurement for newly acked data chunks =============
1409  EV_DETAIL << simTime() << ": SACK: rtt=" << rttEstimation
1410  << ", path=" << path->remoteAddress << endl;
1411  pmRttMeasurement(path, rttEstimation);
1412 
1413  // ====== Record statistics ==============================================
1414  for (auto & elem : sctpPathMap) {
1415  SCTPPathVariables *myPath = elem.second;
1416  myPath->statisticsPathGapAckedChunksInLastSACK->record(myPath->gapAckedChunksInLastSACK);
1417  myPath->statisticsPathGapNRAckedChunksInLastSACK->record(myPath->gapNRAckedChunksInLastSACK);
1418  myPath->statisticsPathGapUnackedChunksInLastSACK->record(myPath->gapUnackedChunksInLastSACK);
1419  }
1420 
1421  // #######################################################################
1422  // #### Receiver Window Management ####
1423  // #######################################################################
1424 
1425  const uint32 osb = getOutstandingBytes();
1426  if (state->bytesToAddPerPeerChunk > 0) {
1428  }
1429  else if (state->peerAllowsChunks) {
1431  state->peerRwnd = arwnd - osb;
1432  if ((int32)(state->peerMsgRwnd) < 0) {
1433  state->peerMsgRwnd = 0;
1434  }
1437  }
1438  }
1439  else {
1440  state->peerRwnd = arwnd - osb;
1441  }
1442 
1443  // position of statement changed 20.07.05 I.R.
1444  if ((int32)(state->peerRwnd) < 0) {
1445  state->peerRwnd = 0;
1446  }
1447  if (state->peerRwnd > state->initialPeerRwnd) {
1449  }
1450  if (state->peerAllowsChunks && msgRwnd == 0) {
1451  state->peerWindowFull = true;
1452  }
1453  if (arwnd == 1 || state->peerRwnd < state->swsLimit || arwnd == 0) {
1454  EV_INFO << "processSackArrived: arwnd=" << arwnd
1455  << " state->peerRwnd=" << state->peerRwnd
1456  << " set peerWindowFull" << endl;
1457  state->peerWindowFull = true;
1458  }
1459  else if ((state->peerAllowsChunks && msgRwnd > 0) || !state->peerAllowsChunks) {
1460  state->peerWindowFull = false;
1461  state->zeroWindowProbing = false;
1462  }
1463  advancePeerTsn();
1464  statisticsArwndInLastSACK->record(arwnd);
1465  statisticsPeerRwnd->record(state->peerRwnd);
1466 
1467  // ====== Need for zero-window probing? ==================================
1468  if (osb == 0) {
1469  if ((state->peerAllowsChunks && msgRwnd == 0) || arwnd == 0)
1470  state->zeroWindowProbing = true;
1471  }
1472 
1473  // #######################################################################
1474  // #### Congestion Window Management ####
1475  // #######################################################################
1476 
1477  // ======= Update congestion window of each path =========================
1478  EV_DEBUG << "Before ccUpdateBytesAcked: ";
1479  for (auto & elem : sctpPathMap) {
1480  SCTPPathVariables *myPath = elem.second;
1481  const L3Address& myPathId = myPath->remoteAddress;
1482 
1483  if (myPath->newPseudoCumAck) {
1484  myPath->vectorPathPseudoCumAck->record(myPath->pseudoCumAck);
1485  }
1486  if (myPath->newRTXPseudoCumAck) {
1487  myPath->vectorPathRTXPseudoCumAck->record(myPath->rtxPseudoCumAck);
1488  }
1489  if (myPath->newlyAckedBytes > 0) {
1490  // Only call ccUpdateBytesAcked() when there are
1491  // acked bytes on this path!
1492  bool advanceWindow = myPath->newPseudoCumAck || myPath->newRTXPseudoCumAck;
1493  if (state->allowCMT == true) {
1495  advanceWindow = myPath->newPseudoCumAck || myPath->newRTXPseudoCumAck;
1496  }
1498  advanceWindow = myPath->newPseudoCumAck;
1499  }
1501  advanceWindow = myPath->newCumAck;
1502  }
1503  }
1504  EV_DETAIL << simTime() << ":\tCC " << myPath->newlyAckedBytes
1505  << " newly acked on path " << myPathId << ";"
1506  << "\tpath->newPseudoCumAck=" << ((myPath->newPseudoCumAck == true) ? "true" : "false")
1507  << "\tpath->newRTXPseudoCumAck=" << ((myPath->newRTXPseudoCumAck == true) ? "true" : "false")
1508  << "\tdropFilledGap=" << ((dropFilledGap == true) ? "true" : "false")
1509  << "\t->\tadvanceWindow=" << advanceWindow << endl;
1510 
1511  (this->*ccFunctions.ccUpdateBytesAcked)(myPath, myPath->newlyAckedBytes,
1512  (advanceWindow && dropFilledGap) ? false :
1513  advanceWindow);
1515  myPath->packetsInBurst = 0;
1516  }
1517  }
1518  }
1519 
1520  // ====== Update congestion windows on paths (handling decreases) ========
1521  EV_DEBUG << "Before ccUpdateAfterSack with tsna=" << tsna << endl;
1522  // ccUpdateAfterSack() will iterate over all paths.
1523  (this->*ccFunctions.ccUpdateAfterSack)();
1524 
1525  // #######################################################################
1526  // #### Path Management ####
1527  // #######################################################################
1528 
1529  if ((state->allowCMT == true) &&
1530  (state->cmtSmartT3Reset == true))
1531  {
1532  // ====== Find oldest unacked chunk on each path ======================
1533  for (SCTPQueue::PayloadQueue::const_iterator iterator = retransmissionQ->payloadQueue.begin();
1534  iterator != retransmissionQ->payloadQueue.end(); ++iterator)
1535  {
1536  const SCTPDataVariables *myChunk = iterator->second;
1537  SCTPPathVariables *myChunkLastPath = myChunk->getLastDestinationPath();
1538  if (!chunkHasBeenAcked(myChunk)) {
1539  if (myChunkLastPath->newOldestChunkSendTime > myChunk->sendTime) {
1540  EV_DETAIL << "TSN " << myChunk->tsn << " is new oldest on path "
1541  << myChunkLastPath->remoteAddress << ", rel send time is "
1542  << simTime() - myChunk->sendTime << " ago" << endl;
1543  myChunkLastPath->newOldestChunkSendTime = myChunk->sendTime;
1544  myChunkLastPath->oldestChunkTSN = myChunk->tsn;
1545  }
1546  }
1547  }
1548  }
1549 
1550  // ====== Need to stop or restart T3 timer? ==============================
1551  for (auto & elem : sctpPathMap) {
1552  SCTPPathVariables *myPath = elem.second;
1553  const L3Address& myPathId = myPath->remoteAddress;
1554 
1555  // ====== Smart T3 Reset ===============================================
1556  bool updatedOldestChunkSendTime = false;
1557  if ((state->allowCMT == true) &&
1558  (state->cmtSmartT3Reset == true))
1559  {
1560  // ====== Has oldest chunk send time been updated? =================
1561  if (myPath->newOldestChunkSendTime > simTime()) {
1562  myPath->newOldestChunkSendTime = myPath->oldestChunkSendTime;
1563  // newOldestChunkSendTime > simTime => no old chunk found:
1564  // Set newOldestChunkSendTime to oldestChunkSendTime
1565  }
1566  else if (myPath->newOldestChunkSendTime != myPath->oldestChunkSendTime) {
1567  // Update oldestChunkSendTime.
1568  myPath->oldestChunkSendTime = myPath->newOldestChunkSendTime;
1569  updatedOldestChunkSendTime = true;
1570  }
1571  assert(myPath->oldestChunkSendTime <= simTime());
1572  }
1573  if (myPath->outstandingBytes == 0) {
1574  // T.D. 07.01.2010: Only stop T3 timer when there is nothing more to send on this path!
1575  if (qCounter.roomTransQ.find(myPath->remoteAddress)->second == 0) {
1576  // Stop T3 timer, if there are no more outstanding bytes.
1577  stopTimer(myPath->T3_RtxTimer);
1578  myPath->oldestChunkSendTime = SIMTIME_ZERO;
1579  }
1580  }
1581  else if (myPath->newCumAck) { // Only care for CumAcks here!
1582  // NOTE: Due to the existence of retransmissions *before* PseudoCumAck for CUCv2,
1583  // it is *not* possible to check PseudoCumAck here!
1584  // This would miss retransmissions -> chunks would never be retransmitted!
1585  stopTimer(myPath->T3_RtxTimer);
1586  startTimer(myPath->T3_RtxTimer, myPath->pathRto);
1587  }
1588  else if (updatedOldestChunkSendTime) { // Smart T3 Reset
1589  stopTimer(myPath->T3_RtxTimer);
1590  startTimer(myPath->T3_RtxTimer, myPath->pathRto);
1591  }
1592  else {
1593  /* Also restart T3 timer, when lowest TSN is rtx'ed */
1594  if (myPath->lowestTSNRetransmitted == true) {
1595  EV_INFO << "Lowest TSN retransmitted => restart of T3 timer for path "
1596  << myPathId << endl;
1597  stopTimer(myPath->T3_RtxTimer);
1598  startTimer(myPath->T3_RtxTimer, myPath->pathRto);
1599  }
1600  }
1601 
1602  // ====== Clear error counter if TSNs on path have been acked =========
1603  if (myPath->newlyAckedBytes > 0) {
1604  pmClearPathCounter(myPath);
1605  }
1606  }
1607 
1608  return SCTP_E_IGNORE;
1609 }
MBVariant maxBurstVariant
Definition: SCTPAssociation.h:702
void tsnWasReneged(SCTPDataVariables *chunk, const SCTPPathVariables *sackPath, const int type)
Definition: SCTPAssociationRcvMessage.cc:938
CUCVariant cmtCUCVariant
Definition: SCTPAssociation.h:714
uint32 lastTsnAck
Definition: SCTPAssociation.h:614
void handleChunkReportedAsMissing(const SCTPSackChunk *sackChunk, const uint32 highestNewAck, SCTPDataVariables *myChunk, SCTPPathVariables *sackPath)
Definition: SCTPAssociationRcvMessage.cc:1713
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
bool zeroWindowProbing
Definition: SCTPAssociation.h:582
int32 getOutstandingBytes() const
Definition: SCTPAssociationUtil.cc:2721
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
Definition: SCTPAssociation.h:698
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
uint64 peerRwnd
Definition: SCTPAssociation.h:610
uint32 highestTsnAcked
Definition: SCTPAssociation.h:615
uint32 swsLimit
Definition: SCTPAssociation.h:664
void updateFastRecoveryStatus(const uint32 lastTsnAck)
Definition: SCTPCCFunctions.cc:580
Definition: SCTPAssociation.h:710
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
bool allowCMT
Definition: SCTPAssociation.h:705
bool checkSackSeqNumber
Definition: SCTPAssociation.h:773
cOutVector * statisticsRevokableGapBlocksInLastSACK
Definition: SCTPAssociation.h:980
void cucProcessGapReports(const SCTPDataVariables *chunk, SCTPPathVariables *path, const bool isAcked)
Definition: SCTPAssociationRcvMessage.cc:964
uint64 sendBuffer
Definition: SCTPAssociation.h:660
Definition: SCTPGapList.h:108
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
SCTPDataVariables * getChunkFast(const uint32 tsn, bool &firstTime)
Definition: SCTPQueue.cc:133
void dequeueAckedChunks(const uint32 tsna, SCTPPathVariables *path, simtime_t &rttEstimation)
Definition: SCTPAssociationRcvMessage.cc:2058
uint32 incomingSackSeqNum
Definition: SCTPAssociation.h:775
static int32 tsnLt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1083
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
bool cmtSlowPathRTTUpdate
Definition: SCTPAssociation.h:738
SCTP * sctpMain
Definition: SCTPAssociation.h:962
cOutVector * statisticsNonRevokableGapBlocksInLastSACK
Definition: SCTPAssociation.h:981
uint64 initialPeerRwnd
Definition: SCTPAssociation.h:611
uint32 peerMsgRwnd
Definition: SCTPAssociation.h:841
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
void advancePeerTsn()
Definition: SCTPAssociationUtil.cc:2201
CCFunctions ccFunctions
Definition: SCTPAssociation.h:951
Definition: SCTPGapList.h:107
bool cmtSmartT3Reset
Definition: SCTPAssociation.h:735
L3Address remoteAddr
Definition: SCTPAssociation.h:911
static int32 tsnLe(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1082
void(SCTPAssociation::* ccUpdateBytesAcked)(SCTPPathVariables *path, const uint32 ackedBytes, const bool ctsnaAdvanced)
Definition: SCTPAssociation.h:896
uint64_t uint64
Definition: Compat.h:28
void handleChunkReportedAsAcked(uint32 &highestNewAck, simtime_t &rttEstimation, SCTPDataVariables *myChunk, SCTPPathVariables *sackPath, const bool sackIsNonRevokable)
Definition: SCTPAssociationRcvMessage.cc:1611
SCTPDataVariables * getChunk(const uint32 key) const
Definition: SCTPQueue.cc:123
bool peerAllowsChunks
Definition: SCTPAssociation.h:838
uint32 bytesToAddPerPeerChunk
Definition: SCTPAssociation.h:845
cOutVector * numGapBlocks
Definition: SCTPAssociation.h:957
QueueCounter qCounter
Definition: SCTPAssociation.h:965
uint32 advancedPeerAckPoint
Definition: SCTPAssociation.h:836
Definition: SCTPGapList.h:109
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
static int32 tsnGt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1081
void(SCTPAssociation::* ccUpdateAfterSack)()
Definition: SCTPAssociation.h:892
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
uint32 outstandingMessages
Definition: SCTPAssociation.h:843
int32 assocId
Definition: SCTPAssociation.h:908
cOutVector * statisticsArwndInLastSACK
Definition: SCTPAssociation.h:982
uint32 tsn
Definition: SCTPAssociation.h:488
uint16_t uint16
Definition: Compat.h:32
void pmRttMeasurement(SCTPPathVariables *path, const simtime_t &rttEstimation)
Definition: SCTPAssociationUtil.cc:2760
bool ackPointAdvanced
Definition: SCTPAssociation.h:574
cOutVector * statisticsPeerRwnd
Definition: SCTPAssociation.h:983
bool peerWindowFull
Definition: SCTPAssociation.h:595
void pmClearPathCounter(SCTPPathVariables *path)
Definition: SCTPAssociationUtil.cc:2730
AssocStat * getAssocStat(uint32 assocId)
Definition: SCTP.h:225
Definition: SCTPAssociation.h:91
uint32 initialPeerMsgRwnd
Definition: SCTPAssociation.h:839
void generateSendQueueAbatedIndication(const uint64 bytes)
Definition: SCTPAssociationRcvMessage.cc:2016
Definition: SCTPAssociation.h:711
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool chunkHasBeenAcked(const SCTPDataVariables *chunk) const
Definition: SCTPAssociation.h:1448
bool inet::sctp::SCTPAssociation::processSCTPMessage ( SCTPMessage sctpmsg,
const L3Address srcAddr,
const L3Address destAddr 
)

Process incoming SCTP segment.

Normally returns true. A return value of false means that the connection structure must be deleted by the caller (SCTP).

Referenced by inet::sctp::SCTP::handleMessage().

985 {
986  printAssocBrief();
987 
988  localAddr = msgDestAddr;
989  localPort = sctpmsg->getDestPort();
990  remoteAddr = msgSrcAddr;
991  remotePort = sctpmsg->getSrcPort();
992 
993  if (fsm->getState() == SCTP_S_ESTABLISHED) {
994  bool found = false;
995  for (auto & elem : state->localAddresses) {
996  if ((elem) == msgDestAddr) {
997  found = true;
998  break;
999  }
1000  }
1001  if (!found) {
1002  EV_INFO << "destAddr " << msgDestAddr << " is not bound to host\n";
1003  return true;
1004  }
1005  }
1006 
1007  return process_RCV_Message(sctpmsg, msgSrcAddr, msgDestAddr);
1008 }
Definition: SCTPAssociation.h:60
bool process_RCV_Message(SCTPMessage *sctpseg, const L3Address &src, const L3Address &dest)
Definition: SCTPAssociationRcvMessage.cc:72
uint16 remotePort
Definition: SCTPAssociation.h:914
L3Address remoteAddr
Definition: SCTPAssociation.h:911
void printAssocBrief()
Utility: prints local/remote addr/port and app gate index/assocId.
Definition: SCTPAssociationUtil.cc:284
L3Address localAddr
Definition: SCTPAssociation.h:912
cFSM * fsm
Definition: SCTPAssociation.h:963
uint16 localPort
Definition: SCTPAssociation.h:913
AddressVector localAddresses
Definition: SCTPAssociation.h:607
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::processSSNTSNResetRequestArrived ( SCTPSSNTSNResetRequestParameter requestParam)
protected

Referenced by checkStreamsToReset(), and processStreamResetArrived().

2499 {
2500  EV_TRACE << "processSSNTSNResetRequestArrived\n";
2501  if (!state->firstPeerRequest && (requestParam->getSrReqSn() < (state->peerRequestSn)) ) {
2502  // Retransmission
2503  sendStreamResetResponse(requestParam->getSrReqSn(), NO_RESET);
2504  return;
2505  }
2506  if (!state->fragInProgress && state->outstandingBytes == 0) {
2508  state->stopOldData = true;
2509  // resetExpectedSsns();
2510  if (state->sendResponse == PERFORMED) {
2511  sendStreamResetResponse(requestParam, PERFORMED, true);
2512  state->sendResponse = 0;
2513  } else {
2515  state->responseSn = requestParam->getSrReqSn();
2517  state->incomingRequest = (SCTPParameter *)requestParam->dup(); //FIXME is the c-style conversion need here?
2518  state->incomingRequestSet = true;
2519  }
2520  } else {
2521  sendStreamResetResponse(requestParam, DEFERRED, true);
2522  state->incomingRequest = (SCTPParameter *)requestParam->dup(); //FIXME is the c-style conversion need here?
2523  state->incomingRequestSet = true;
2524  state->incomingRequest->setName("SSNDeferred");
2525  state->peerRequestSn = requestParam->getSrReqSn();
2526  // state->firstPeerRequest = false;
2528  state->resetDeferred = true;
2529  }
2530 }
uint16 peerRequestType
Definition: SCTPAssociation.h:809
bool fragInProgress
Definition: SCTPAssociation.h:601
uint16 sendResponse
Definition: SCTPAssociation.h:642
bool firstPeerRequest
Definition: SCTPAssociation.h:790
Definition: SCTPAssociation.h:148
uint64 outstandingBytes
Definition: SCTPAssociation.h:622
Definition: SCTPAssociation.h:149
uint32 advancedPeerAckPoint
Definition: SCTPAssociation.h:836
SCTPParameter * incomingRequest
Definition: SCTPAssociation.h:800
virtual SCTPParameter * dup() const override
Definition: SCTPMessage_m.h:1257
Definition: SCTPAssociation.h:153
bool resetDeferred
Definition: SCTPAssociation.h:787
bool stopOldData
Definition: SCTPAssociation.h:592
uint32 nextTSN
Definition: SCTPAssociation.h:613
Definition: SCTPAssociation.h:163
Definition: SCTPAssociation.h:144
void sendStreamResetResponse(uint32 srrsn, int result)
Definition: SCTPAssociationStreamReset.cc:763
uint32 responseSn
Definition: SCTPAssociation.h:643
uint32 peerRequestSn
Definition: SCTPAssociation.h:795
bool incomingRequestSet
Definition: SCTPAssociation.h:602
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPEventCode inet::sctp::SCTPAssociation::processStreamResetArrived ( SCTPStreamResetChunk strResChunk)
protected

Referenced by process_RCV_Message().

2797 {
2798  SCTPParameter *parameter, *nextParam;
2799  bool requestReceived = false;
2800  std::map<uint32, SCTPStateVariables::RequestData>::reverse_iterator rit;
2801  uint32 numberOfParameters = resetChunk->getParametersArraySize();
2802  EV_TRACE << "processStreamResetArrived\n";
2803 
2804  if (numberOfParameters == 0)
2805  return SCTP_E_IGNORE;
2806  for (uint16 i = 0; i < numberOfParameters; i++) {
2807  parameter = (SCTPParameter *)(resetChunk->getParameters(i));
2808  switch (parameter->getParameterType()) {
2810  SCTPOutgoingSSNResetRequestParameter *outRequestParam;
2811  outRequestParam = check_and_cast<SCTPOutgoingSSNResetRequestParameter *>(parameter);
2812  if (state->findPeerRequestNum(outRequestParam->getSrReqSn())) {
2813  // retransmission
2814  if (state->peerRequests[outRequestParam->getSrReqSn()].type != outRequestParam->getParameterType()) {
2815  sendStreamResetResponse(outRequestParam->getSrReqSn(), NO_RESET);
2816  return SCTP_E_IGNORE;
2817  }
2818  if (state->peerRequests[outRequestParam->getSrReqSn()].result != 100) {
2819  std::map<uint32, SCTPStateVariables::RequestData>::reverse_iterator rit;
2820  rit = state->peerRequests.rbegin();
2821  if (state->peerRequests[outRequestParam->getSrReqSn()].sn == rit->first) {
2822  // send response with same result
2823  sendStreamResetResponse(outRequestParam->getSrReqSn(), state->peerRequests[outRequestParam->getSrReqSn()].result);
2824  return SCTP_E_IGNORE;
2825  } else {
2826  sendStreamResetResponse(outRequestParam->getSrReqSn(), NO_RESET);
2827  return SCTP_E_IGNORE;
2828  }
2829  }
2830  }
2831  if (state->firstPeerRequest && outRequestParam->getSrReqSn() != state->expectedStreamResetSequenceNumber) {
2832  if (state->peerRequests.size() > 0) {
2833  sendStreamResetResponse(outRequestParam->getSrReqSn(), REQUEST_IN_PROGRESS);
2834  } else {
2835  sendStreamResetResponse(outRequestParam->getSrReqSn(), NO_RESET);
2836  }
2837  break;
2838  }
2839  state->peerRequests[outRequestParam->getSrReqSn()].sn = outRequestParam->getSrReqSn();
2840  state->peerRequests[outRequestParam->getSrReqSn()].result = 100;
2841  state->peerRequests[outRequestParam->getSrReqSn()].type = outRequestParam->getParameterType();
2842  if (numberOfParameters > i + 1) {
2843  nextParam = (SCTPParameter *)(resetChunk->getParameters(i + 1));
2844  if (nextParam->getParameterType() != INCOMING_RESET_REQUEST_PARAMETER &&
2845  nextParam->getParameterType() != STREAM_RESET_RESPONSE_PARAMETER) {
2846  processOutgoingResetRequestArrived(outRequestParam);
2847  delete nextParam;
2848  } else {
2849  switch (nextParam->getParameterType()) {
2851  SCTPIncomingSSNResetRequestParameter *inRequestParam;
2852  inRequestParam = check_and_cast<SCTPIncomingSSNResetRequestParameter *>(nextParam);
2853  state->peerRequests[inRequestParam->getSrReqSn()].sn = inRequestParam->getSrReqSn();
2854  state->peerRequests[inRequestParam->getSrReqSn()].result = 100;
2855  state->peerRequests[inRequestParam->getSrReqSn()].type = inRequestParam->getParameterType();
2856  processInAndOutResetRequestArrived(inRequestParam, outRequestParam);
2857  i++;
2858  break;
2859 
2861  SCTPStreamResetResponseParameter *responseParam;
2862  responseParam = check_and_cast<SCTPStreamResetResponseParameter *>(nextParam);
2863  state->numResetRequests -= 2;
2864  processOutAndResponseArrived(outRequestParam, responseParam);
2865  i++;
2866  break;
2867  }
2868  }
2869  } else {
2870  processOutgoingResetRequestArrived(outRequestParam);
2871  }
2872  requestReceived = true;
2873  break;
2874  }
2875 
2877  SCTPIncomingSSNResetRequestParameter *inRequestParam;
2878  inRequestParam = check_and_cast<SCTPIncomingSSNResetRequestParameter *>(parameter);
2879  rit = state->peerRequests.rbegin();
2880  if (state->firstPeerRequest && (inRequestParam->getSrReqSn() != state->expectedStreamResetSequenceNumber)) {
2881  sendStreamResetResponse(inRequestParam->getSrReqSn(), NO_RESET);
2882  return SCTP_E_IGNORE;
2883  }
2884  if (!state->firstPeerRequest &&
2885  (((inRequestParam->getSrReqSn() < (state->peerRequestSn)) &&
2886  (inRequestParam->getSrReqSn() != rit->first + 1)) ||
2887  (state->findPeerRequestNum(inRequestParam->getSrReqSn()) && state->peerRequests[inRequestParam->getSrReqSn()].type != inRequestParam->getParameterType()))) {
2888  sendStreamResetResponse(inRequestParam->getSrReqSn(), NO_RESET);
2889  return SCTP_E_IGNORE;
2890  }
2891  rit = state->requests.rbegin();
2892  if (rit->second.type == OUTGOING_RESET_REQUEST_PARAMETER && (rit->second.result == 100 || rit->second.result == PERFORMED)) {
2893  state->requestsOverlap = true;
2894  if (state->requests[rit->first].lastTsn == state->nextTSN - 1) {
2895  if (inRequestParam->getStreamNumbersArraySize() > 0) {
2896  uint16 match = 0;
2897  for (uint i = 0; i < inRequestParam->getStreamNumbersArraySize(); i++) {
2898  std::list<uint16>::iterator it;
2899  for (it = state->requests[rit->first].streams.begin(); it != state->requests[rit->first].streams.end(); it++) {
2900  if ((*it) == inRequestParam->getStreamNumbers(i))
2901  match++;
2902  }
2903  }
2904  if (match == inRequestParam->getStreamNumbersArraySize()) {
2905  sendStreamResetResponse(inRequestParam->getSrReqSn(), NOTHING_TO_DO);
2906  return SCTP_E_IGNORE;
2907  }
2908  } else {
2909  sendStreamResetResponse(inRequestParam->getSrReqSn(), NOTHING_TO_DO);
2910  return SCTP_E_IGNORE;
2911  }
2912  }
2913  }
2914  state->peerRequests[inRequestParam->getSrReqSn()].sn = inRequestParam->getSrReqSn();
2915  state->peerRequests[inRequestParam->getSrReqSn()].result = 100;
2916  state->peerRequests[inRequestParam->getSrReqSn()].type = inRequestParam->getParameterType();
2917  if (numberOfParameters > i + 1) {
2918  nextParam = (SCTPParameter *)(resetChunk->getParameters(i + 1));
2919  if (nextParam->getParameterType() != OUTGOING_RESET_REQUEST_PARAMETER) {
2920  processIncomingResetRequestArrived(inRequestParam);
2921  } else {
2922  if (nextParam->getParameterType() == OUTGOING_RESET_REQUEST_PARAMETER) {
2923  i++;
2924  SCTPOutgoingSSNResetRequestParameter *outRequestParam;
2925  outRequestParam = check_and_cast<SCTPOutgoingSSNResetRequestParameter *>(nextParam->dup());
2926  state->peerRequests[outRequestParam->getSrReqSn()].sn = outRequestParam->getSrReqSn();
2927  state->peerRequests[outRequestParam->getSrReqSn()].result = 100;
2928  state->peerRequests[outRequestParam->getSrReqSn()].type = outRequestParam->getParameterType();
2929  processInAndOutResetRequestArrived(inRequestParam, outRequestParam);
2930  delete outRequestParam;
2931  }
2932  }
2933  } else {
2934  processIncomingResetRequestArrived(inRequestParam);
2935  }
2936  requestReceived = true;
2937  break;
2938  }
2939 
2941  SCTPSSNTSNResetRequestParameter *ssnRequestParam;
2942  ssnRequestParam = check_and_cast<SCTPSSNTSNResetRequestParameter *>(parameter);
2943  rit = state->peerRequests.rbegin();
2944  if (state->firstPeerRequest && ssnRequestParam->getSrReqSn() != state->expectedStreamResetSequenceNumber) {
2945  if (state->peerRequests.size() > 0) {
2946  sendStreamResetResponse(ssnRequestParam->getSrReqSn(), REQUEST_IN_PROGRESS);
2947  } else {
2948  sendStreamResetResponse(ssnRequestParam->getSrReqSn(), NO_RESET);
2949  }
2950  break;
2951  }
2952  if (!state->firstPeerRequest &&
2953  ((((ssnRequestParam->getSrReqSn() < (state->peerRequestSn)) && (ssnRequestParam->getSrReqSn() != rit->first + 1))) ||
2954  ((state->findPeerRequestNum(ssnRequestParam->getSrReqSn())) &&
2955  state->peerRequests[ssnRequestParam->getSrReqSn()].type != ssnRequestParam->getParameterType()))) {
2956  sendStreamResetResponse(ssnRequestParam->getSrReqSn(), NO_RESET);
2957  return SCTP_E_IGNORE;
2958  }
2960  sendStreamResetResponse(ssnRequestParam, NOTHING_TO_DO, true);
2961  break;
2962  }
2963  state->peerRequests[ssnRequestParam->getSrReqSn()].sn = ssnRequestParam->getSrReqSn();
2964  state->peerRequests[ssnRequestParam->getSrReqSn()].result = 100;
2965  state->peerRequests[ssnRequestParam->getSrReqSn()].type = ssnRequestParam->getParameterType();
2966  processSSNTSNResetRequestArrived(ssnRequestParam);
2967  requestReceived = true;
2968  break;
2969 
2971  SCTPAddStreamsRequestParameter *addStreamsParam =
2972  check_and_cast<SCTPAddStreamsRequestParameter *>(parameter);
2973  if (addStreamsParam->getNumberOfStreams() == 0) {
2974  sendStreamResetResponse(addStreamsParam->getSrReqSn(), NOTHING_TO_DO);
2975  return SCTP_E_IGNORE;
2976  }
2977  rit = state->peerRequests.rbegin();
2978  if ((state->firstPeerRequest && addStreamsParam->getSrReqSn() != state->expectedStreamResetSequenceNumber) ||
2979  (!state->firstPeerRequest && ((addStreamsParam->getSrReqSn() < (state->peerRequestSn)) &&
2980  (addStreamsParam->getSrReqSn() != rit->first + 1))) ||
2981  (state->findPeerRequestNum(addStreamsParam->getSrReqSn()) &&
2982  state->peerRequests[addStreamsParam->getSrReqSn()].type != addStreamsParam->getParameterType())) {
2983  sendStreamResetResponse(addStreamsParam->getSrReqSn(), NO_RESET);
2984  return SCTP_E_IGNORE;
2985  }
2986  if (!(addStreamsParam->getNumberOfStreams() + outboundStreams <= 65535)) {
2987  sendStreamResetResponse(addStreamsParam->getSrReqSn(), DENIED);
2988  return SCTP_E_IGNORE;
2989  }
2990  state->peerRequests[addStreamsParam->getSrReqSn()].sn = addStreamsParam->getSrReqSn();
2991  state->peerRequests[addStreamsParam->getSrReqSn()].result = 100;
2992  state->peerRequests[addStreamsParam->getSrReqSn()].type = addStreamsParam->getParameterType();
2993  if (numberOfParameters > i + 1) {
2994  nextParam = (SCTPParameter *)(resetChunk->getParameters(i + 1));
2995  if (nextParam->getParameterType() == ADD_OUTGOING_STREAMS_REQUEST_PARAMETER) {
2996  SCTPAddStreamsRequestParameter *addOutStreamsParam;
2997  addOutStreamsParam = check_and_cast<SCTPAddStreamsRequestParameter *>(nextParam);
2998  state->peerRequests[addOutStreamsParam->getSrReqSn()].sn = addOutStreamsParam->getSrReqSn();
2999  state->peerRequests[addOutStreamsParam->getSrReqSn()].result = 100;
3000  state->peerRequests[addOutStreamsParam->getSrReqSn()].type = addOutStreamsParam->getParameterType();
3001  processAddInAndOutResetRequestArrived(addStreamsParam, addOutStreamsParam);
3002  i++;
3003  }
3004  } else {
3005  state->peerRequestSn = addStreamsParam->getSrReqSn();
3007  state->incomingRequest = ((SCTPParameter *)addStreamsParam)->dup(); //FIXME is the c-style conversion need here?
3008  state->incomingRequestSet = true;
3009  state->incomingRequest->setName("stateIncoming");
3011  }
3012  break;
3013  }
3014 
3016  SCTPAddStreamsRequestParameter *addOutStreamsParam =
3017  check_and_cast<SCTPAddStreamsRequestParameter *>(parameter);
3018  if (addOutStreamsParam->getNumberOfStreams() == 0) {
3019  sendStreamResetResponse(addOutStreamsParam->getSrReqSn(), NOTHING_TO_DO);
3020  return SCTP_E_IGNORE;
3021  }
3022  rit = state->peerRequests.rbegin();
3023  if ((!(addOutStreamsParam->getNumberOfStreams() + inboundStreams <= 65535)) ||
3024  (state->appLimited && (addOutStreamsParam->getNumberOfStreams() + inboundStreams > initInboundStreams))) {
3025  sendStreamResetResponse(addOutStreamsParam->getSrReqSn(), DENIED);
3026  return SCTP_E_IGNORE;
3027  }
3028  if (state->findPeerRequestNum(addOutStreamsParam->getSrReqSn())) {
3029  // retransmission
3030  if (state->peerRequests[addOutStreamsParam->getSrReqSn()].type != addOutStreamsParam->getParameterType()) {
3031  sendStreamResetResponse(addOutStreamsParam->getSrReqSn(), NO_RESET);
3032  return SCTP_E_IGNORE;
3033  }
3034  if (state->peerRequests[addOutStreamsParam->getSrReqSn()].result != 100) {
3035  if (state->peerRequests[addOutStreamsParam->getSrReqSn()].sn == rit->first) {
3036  // send response with same result
3037  sendStreamResetResponse(addOutStreamsParam->getSrReqSn(), state->peerRequests[addOutStreamsParam->getSrReqSn()].result);
3038  return SCTP_E_IGNORE;
3039  } else {
3040  sendStreamResetResponse(addOutStreamsParam->getSrReqSn(), NO_RESET);
3041  return SCTP_E_IGNORE;
3042  }
3043  }
3044  }
3045  if ((state->firstPeerRequest && addOutStreamsParam->getSrReqSn() != state->expectedStreamResetSequenceNumber) ||
3046  (!state->firstPeerRequest && ((addOutStreamsParam->getSrReqSn() < (state->peerRequestSn)) &&
3047  (addOutStreamsParam->getSrReqSn() != rit->first + 1)))) {
3048  // Retransmission
3049  sendStreamResetResponse(addOutStreamsParam->getSrReqSn(), NO_RESET);
3050  return SCTP_E_IGNORE;
3051  }
3052  state->peerRequests[addOutStreamsParam->getSrReqSn()].sn = addOutStreamsParam->getSrReqSn();
3053  state->peerRequests[addOutStreamsParam->getSrReqSn()].result = 100;
3054  state->peerRequests[addOutStreamsParam->getSrReqSn()].type = addOutStreamsParam->getParameterType();
3056  inboundStreams += addOutStreamsParam->getNumberOfStreams();
3058  state->numAddedInStreams = 0;
3059  (this->*ssFunctions.ssAddInStreams)(addOutStreamsParam->getNumberOfStreams());
3060  }
3061  if (numberOfParameters > i + 1) {
3062  nextParam = (SCTPParameter *)(resetChunk->getParameters(i + 1));
3063  if (nextParam->getParameterType() == ADD_INCOMING_STREAMS_REQUEST_PARAMETER) {
3064  SCTPAddStreamsRequestParameter *addInStreamsParam;
3065  addInStreamsParam = check_and_cast<SCTPAddStreamsRequestParameter *>(nextParam);
3066  state->peerRequests[addInStreamsParam->getSrReqSn()].sn = addInStreamsParam->getSrReqSn();
3067  state->peerRequests[addInStreamsParam->getSrReqSn()].result = 100;
3068  state->peerRequests[addInStreamsParam->getSrReqSn()].type = addInStreamsParam->getParameterType();
3069  processAddInAndOutResetRequestArrived(addInStreamsParam, addOutStreamsParam);
3070  i++;
3071  } else {
3072  state->peerRequestSn = addOutStreamsParam->getSrReqSn();
3075  state->responseSn = addOutStreamsParam->getSrReqSn();
3076  state->firstPeerRequest = false;
3077  // state->numAddedInStreams = addOutStreamsParam->getNumberOfStreams();
3078  state->resetRequested = true;
3079  }
3080  } else {
3081  state->peerRequestSn = addOutStreamsParam->getSrReqSn();
3084  state->responseSn = addOutStreamsParam->getSrReqSn();
3085  // state->numAddedInStreams = addOutStreamsParam->getNumberOfStreams();
3086  state->firstPeerRequest = false;
3087  state->resetRequested = true;
3088  }
3089  requestReceived = true;
3090  break;
3091  }
3092 
3094  SCTPStreamResetResponseParameter *responseParam;
3095  responseParam = check_and_cast<SCTPStreamResetResponseParameter *>(parameter);
3096  if (!state->findRequestNum(responseParam->getSrResSn())) {
3097  delete state->resetChunk;
3098  state->resetChunk = nullptr;
3099  break;
3100  }
3101  if (numberOfParameters > i + 1) {
3102  nextParam = (SCTPParameter *)(resetChunk->getParameters(i + 1));
3103  if (nextParam->getParameterType() != OUTGOING_RESET_REQUEST_PARAMETER) {
3104  if (responseParam->getResult() != DEFERRED)
3106  processResetResponseArrived(responseParam);
3107  } else {
3108  switch (nextParam->getParameterType()) {
3110  SCTPOutgoingSSNResetRequestParameter *outRequestParam;
3111  outRequestParam = check_and_cast<SCTPOutgoingSSNResetRequestParameter *>(nextParam);
3112  if ((state->firstPeerRequest && outRequestParam->getSrReqSn() != state->expectedStreamResetSequenceNumber) ||
3113  (!state->firstPeerRequest && (outRequestParam->getSrReqSn() < (state->peerRequestSn)))) {
3114  // Retransmission
3115  sendStreamResetResponse(outRequestParam->getSrReqSn(), NO_RESET);
3116  return SCTP_E_IGNORE;
3117  }
3118  state->peerRequests[outRequestParam->getSrReqSn()].sn = outRequestParam->getSrReqSn();
3119  state->peerRequests[outRequestParam->getSrReqSn()].result = 100;
3120  state->peerRequests[outRequestParam->getSrReqSn()].type = outRequestParam->getParameterType();
3121  state->numResetRequests -= 2;
3122  processOutAndResponseArrived(outRequestParam, responseParam);
3123  requestReceived = true;
3124  i++;
3125  break;
3126  }
3127  }
3128  }
3129  } else {
3130  if (responseParam->getResult() != DEFERRED)
3132  processResetResponseArrived(responseParam);
3133  }
3134  break;
3135  }
3136  }
3137  }
3138  return SCTP_E_IGNORE;
3139 }
void processOutgoingResetRequestArrived(SCTPOutgoingSSNResetRequestParameter *requestParam)
Definition: SCTPAssociationRcvMessage.cc:2338
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
bool appLimited
Definition: SCTPAssociation.h:791
uint16 peerRequestType
Definition: SCTPAssociation.h:809
uint32 streamResetSequenceNumber
Definition: SCTPAssociation.h:793
bool resetRequested
Definition: SCTPAssociation.h:590
Definition: SCTPAssociation.h:155
SCTPEventCode processInAndOutResetRequestArrived(SCTPIncomingSSNResetRequestParameter *inRequestParam, SCTPOutgoingSSNResetRequestParameter *outRequestParam)
Definition: SCTPAssociationRcvMessage.cc:2639
unsigned int uint
Definition: INETDefs.h:63
uint16 sendResponse
Definition: SCTPAssociation.h:642
uint16 localRequestType
Definition: SCTPAssociation.h:810
uint32 initPeerTsn
Definition: SCTPAssociation.h:948
uint32 expectedStreamResetSequenceNumber
Definition: SCTPAssociation.h:794
bool firstPeerRequest
Definition: SCTPAssociation.h:790
Definition: SCTPAssociation.h:159
void(SCTPAssociation::* ssAddInStreams)(uint32 inStreams)
Definition: SCTPAssociation.h:1289
uint32 outboundStreams
Definition: SCTPAssociation.h:943
std::map< uint32, RequestData > peerRequests
Definition: SCTPAssociation.h:807
uint32 inboundStreams
Definition: SCTPAssociation.h:942
void processResetResponseArrived(SCTPStreamResetResponseParameter *responseParam)
Definition: SCTPAssociationRcvMessage.cc:2532
void processAddInAndOutResetRequestArrived(SCTPAddStreamsRequestParameter *addInRequestParam, SCTPAddStreamsRequestParameter *addOutRequestParam)
Definition: SCTPAssociationRcvMessage.cc:2696
Definition: SCTPAssociation.h:148
bool findRequestNum(uint32 num)
Definition: SCTPAssociationBase.cc:511
bool requestsOverlap
Definition: SCTPAssociation.h:792
Definition: SCTPAssociation.h:156
Definition: SCTPAssociation.h:145
SCTPGapList gapList
Definition: SCTPAssociation.h:619
Definition: SCTPAssociation.h:149
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
uint16 numResetRequests
Definition: SCTPAssociation.h:644
Definition: SCTPAssociation.h:157
void processSSNTSNResetRequestArrived(SCTPSSNTSNResetRequestParameter *requestParam)
Definition: SCTPAssociationRcvMessage.cc:2498
uint32_t uint32
Definition: Compat.h:30
SCTPParameter * incomingRequest
Definition: SCTPAssociation.h:800
virtual SCTPParameter * dup() const override
Definition: SCTPMessage_m.h:1257
Definition: SCTPAssociation.h:164
Definition: SCTPAssociation.h:158
Definition: SCTPAssociation.h:162
uint16 numAddedInStreams
Definition: SCTPAssociation.h:673
uint32 initInboundStreams
Definition: SCTPAssociation.h:944
uint32 nextTSN
Definition: SCTPAssociation.h:613
uint16_t uint16
Definition: Compat.h:32
bool findPeerRequestNum(uint32 num)
Definition: SCTPAssociationBase.cc:518
Definition: SCTPAssociation.h:154
SSFunctions ssFunctions
Definition: SCTPAssociation.h:1294
Definition: SCTPAssociation.h:144
Definition: SCTPAssociation.h:143
void sendStreamResetResponse(uint32 srrsn, int result)
Definition: SCTPAssociationStreamReset.cc:763
SCTPEventCode processOutAndResponseArrived(SCTPOutgoingSSNResetRequestParameter *outRequestParam, SCTPStreamResetResponseParameter *responseParam)
Definition: SCTPAssociationRcvMessage.cc:2757
uint32 getCumAckTSN() const
Definition: SCTPGapList.h:91
void processIncomingResetRequestArrived(SCTPIncomingSSNResetRequestParameter *requestParam)
Definition: SCTPAssociationRcvMessage.cc:2412
Definition: SCTPAssociation.h:91
Definition: SCTPAssociation.h:147
uint32 responseSn
Definition: SCTPAssociation.h:643
uint32 peerRequestSn
Definition: SCTPAssociation.h:795
bool incomingRequestSet
Definition: SCTPAssociation.h:602
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::processTimer ( cMessage *  msg)

Referenced by inet::sctp::SCTP::handleMessage().

890 {
891  SCTPPathVariables *path = nullptr;
892 
893  EV_INFO << msg->getName() << " timer expired at " << simTime() << "\n";
894 
895  SCTPPathInfo *pinfo = check_and_cast<SCTPPathInfo *>(msg->getControlInfo());
896  L3Address addr = pinfo->getRemoteAddress();
897 
898  if (!addr.isUnspecified())
899  path = getPath(addr);
900 
901  // first do actions
902  SCTPEventCode event;
903  event = SCTP_E_IGNORE;
904 
905  if (msg == T1_InitTimer) {
907  }
908  else if (msg == SackTimer) {
909  EV_DETAIL << simTime() << " delayed Sack: cTsnAck=" << state->gapList.getCumAckTSN() << " highestTsnReceived=" << state->gapList.getHighestTSNReceived() << " lastTsnReceived=" << state->lastTsnReceived << " ackState=" << state->ackState << " numGaps=" << state->gapList.getNumGaps(SCTPGapList::GT_Any) << "\n";
910  sendSack();
911  }
912  else if (msg == T2_ShutdownTimer) {
915  }
916  else if (msg == T5_ShutdownGuardTimer) {
918  if (state->shutdownChunk) {
919  delete state->shutdownChunk;
920  state->shutdownChunk = nullptr;
921  }
923  sendAbort();
925  return true;
926  }
927  else if (path != nullptr && msg == path->HeartbeatIntervalTimer) {
928  process_TIMEOUT_HEARTBEAT_INTERVAL(path, path->forceHb);
929  }
930  else if (path != nullptr && msg == path->HeartbeatTimer) {
932  }
933  else if (path != nullptr && msg == path->T3_RtxTimer) {
934  process_TIMEOUT_RTX(path);
935  }
936  else if (path != nullptr && msg == path->CwndTimer) {
937  (this->*ccFunctions.ccUpdateAfterCwndTimeout)(path);
938  }
939  else if (strcmp(msg->getName(), "StartTesting") == 0) {
940  //if (sctpMain->testing == false)
941  //{
942  //sctpMain->testing = true;
943  EV_DEBUG << "set testing to true\n";
944  //}
945  // todo: testing was removed.
946  }
947  else if (path != nullptr && msg == path->ResetTimer) {
948  process_TIMEOUT_RESET(path);
949  }
950  else if (path != nullptr && msg == path->AsconfTimer) {
952  }
953  else if (msg == StartAddIP) {
955  const char *type = (const char *)sctpMain->par("addIpType");
956  sendAsconf(type);
957  }
958  else if (msg == FairStartTimer) {
959  auto it = sctpMain->assocStatMap.find(assocId);
960  if (it != sctpMain->assocStatMap.end()) {
961  it->second.fairStart = simTime();
962  fairTimer = true;
963  }
964  }
965  else if (msg == FairStopTimer) {
966  auto it = sctpMain->assocStatMap.find(assocId);
967  if (it != sctpMain->assocStatMap.end()) {
968  it->second.fairStop = simTime();
969  it->second.fairLifeTime = it->second.fairStop - it->second.fairStart;
970  it->second.fairThroughput = it->second.fairAckedBytes / it->second.fairLifeTime.dbl();
971  fairTimer = false;
972  }
973  }
974  else {
975  sctpAlgorithm->processTimer(msg, event);
976  }
977 
978  // then state transitions
979  return performStateTransition(event);
980 }
uint32 asconfSn
Definition: SCTPAssociation.h:778
cMessage * FairStartTimer
Definition: SCTPAssociation.h:930
uint32 corrIdNum
Definition: SCTPAssociation.h:780
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
uint32 getNumGaps(const GapType type) const
Definition: SCTPGapList.h:112
uint32 lastTsnReceived
Definition: SCTPAssociation.h:616
SCTPEventCode
Definition: SCTPAssociation.h:71
void process_TIMEOUT_HEARTBEAT_INTERVAL(SCTPPathVariables *path, bool force)
Definition: SCTPAssociationRcvMessage.cc:3559
cMessage * FairStopTimer
Definition: SCTPAssociation.h:931
void(SCTPAssociation::* ccUpdateAfterCwndTimeout)(SCTPPathVariables *path)
Definition: SCTPAssociation.h:893
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
Definition: SCTPCommand.h:73
cMessage * T5_ShutdownGuardTimer
Definition: SCTPAssociation.h:921
cMessage * SackTimer
Definition: SCTPAssociation.h:922
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void process_TIMEOUT_RTX(SCTPPathVariables *path)
Definition: SCTPAssociationRcvMessage.cc:3720
uint32 ackState
Definition: SCTPAssociation.h:618
CCFunctions ccFunctions
Definition: SCTPAssociation.h:951
Definition: SCTPGapList.h:107
void process_TIMEOUT_SHUTDOWN(SCTPEventCode &event)
Definition: SCTPAssociationRcvMessage.cc:3537
SCTPGapList gapList
Definition: SCTPAssociation.h:619
void removeAssociation(SCTPAssociation *assoc)
Definition: SCTP.cc:799
AssocStatMap assocStatMap
Definition: SCTP.h:171
void sendAsconf(const char *type, const bool remote=false)
Methods for Add-IP and AUTH.
Definition: SCTPAssociationAddIP.cc:25
cMessage * T2_ShutdownTimer
Definition: SCTPAssociation.h:920
bool fairTimer
Definition: SCTPAssociation.h:927
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
uint32 getHighestTSNReceived() const
Definition: SCTPGapList.h:96
void sendSack()
Definition: SCTPAssociationUtil.cc:1764
void process_TIMEOUT_INIT_REXMIT(SCTPEventCode &event)
Definition: SCTPAssociationRcvMessage.cc:3508
void process_TIMEOUT_ASCONF(SCTPPathVariables *path)
Definition: SCTPAssociationRcvMessage.cc:3705
void sendAbort(uint16 tBit=0)
Definition: SCTPAssociationUtil.cc:1101
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
int32 assocId
Definition: SCTPAssociation.h:908
cMessage * StartAddIP
Definition: SCTPAssociation.h:924
SCTPAlgorithm * sctpAlgorithm
Definition: SCTPAssociation.h:970
SCTPShutdownChunk * shutdownChunk
pointer to the resetChunk (for retransmission)
Definition: SCTPAssociation.h:656
uint32 getCumAckTSN() const
Definition: SCTPGapList.h:91
void process_TIMEOUT_RESET(SCTPPathVariables *path)
Definition: SCTPAssociationRcvMessage.cc:3646
bool performStateTransition(const SCTPEventCode &event)
Implemements the pure SCTP state machine.
Definition: SCTPAssociationBase.cc:1182
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
Definition: SCTPAssociation.h:91
void process_TIMEOUT_HEARTBEAT(SCTPPathVariables *path)
Definition: SCTPAssociationRcvMessage.cc:3577
virtual void processTimer(cMessage *timer, SCTPEventCode &event)=0
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::pushUlp ( )
protected

Referenced by process_RECEIVE_REQUEST().

1888 {
1889  int32 count = 0;
1890 
1891  for (unsigned int i = 0; i < inboundStreams; i++) { //12.06.08
1892  putInDeliveryQ(i);
1893  }
1894  if (state->pushMessagesLeft <= 0) {
1896  }
1897  bool restrict = false;
1898  if (state->pushMessagesLeft > 0) {
1899  restrict = true;
1900  }
1901 
1903 
1904  EV_DETAIL << simTime() << " Calling pushUlp(" << state->queuedReceivedBytes
1905  << " bytes queued) ..." << endl
1906  << "messagesToPush=" << state->messagesToPush
1907  << " pushMessagesLeft=" << state->pushMessagesLeft
1908  << " restrict=" << restrict
1909  << " buffered Messages=" << state->bufferedMessages << endl;
1910  uint32 i = state->nextRSid;
1911  uint64 tempQueuedBytes = 0;
1912  do {
1913  auto iter = receiveStreams.find(i);
1914  SCTPReceiveStream *rStream = iter->second;
1915  EV_DETAIL << "Size of stream " << iter->first << ": "
1916  << rStream->getDeliveryQ()->getQueueSize() << endl;
1917 
1918  while ((!rStream->getDeliveryQ()->payloadQueue.empty()) &&
1919  (!restrict || (restrict && state->pushMessagesLeft > 0)))
1920  {
1921  SCTPDataVariables *chunk = rStream->getDeliveryQ()->extractMessage();
1923 
1924  if (state->pushMessagesLeft > 0)
1926 
1927  // ====== Non-revokably acknowledge chunks of the message ==========
1928  /* bool dummy;
1929  for (uint32 j = chunk->tsn; j < chunk->tsn + chunk->fragments; j++)
1930  state->gapList.updateGapList(j, dummy, false);*/
1931 
1932  tempQueuedBytes = state->queuedReceivedBytes;
1933  state->queuedReceivedBytes -= chunk->len / 8;
1935  EV_INFO << "buffered Messages now " << state->bufferedMessages << endl;
1936  if (state->swsAvoidanceInvoked) {
1938  /* now check, if user has read enough so that window opens up more than one MTU */
1939  if ((state->messageAcceptLimit > 0 &&
1942  ||
1943  (state->messageAcceptLimit == 0 &&
1946  {
1947  state->swsMsgInvoked = false;
1948  /* only if the window has opened up more than one MTU we will send a SACK */
1949  state->swsAvoidanceInvoked = false;
1950  EV_DETAIL << "pushUlp: Window opens up to " << (int32)state->localRwnd - state->queuedReceivedBytes << " bytes: sending a SACK. SWS Avoidance INACTIVE\n";
1951 
1952  sendSack();
1953  }
1954  }
1955  else if ((int32)(state->swsLimit) == 0) {
1956  sendSack();
1957  }
1958  else if ((tempQueuedBytes > state->localRwnd * 3 / 4) && (state->queuedReceivedBytes <= state->localRwnd * 3 / 4)) {
1959  sendSack();
1960  }
1961  EV_DETAIL << "Push TSN " << chunk->tsn
1962  << ": sid=" << chunk->sid << " ssn=" << chunk->ssn << endl;
1963  cMessage *msg = (cMessage *)chunk->userData;
1964  msg->setKind(SCTP_I_DATA);
1965  SCTPRcvInfo *cmd = new SCTPRcvInfo("push");
1966  cmd->setAssocId(assocId);
1967  cmd->setGate(appGateIndex);
1968  cmd->setSid(chunk->sid);
1969  cmd->setSsn(chunk->ssn);
1970  cmd->setSendUnordered(!chunk->ordered);
1971  cmd->setLocalAddr(localAddr);
1972  cmd->setRemoteAddr(remoteAddr);
1973  cmd->setPpid(chunk->ppid);
1974  cmd->setTsn(chunk->tsn);
1975  cmd->setCumTsn(state->lastTsnAck);
1976  msg->setControlInfo(cmd);
1977  state->numMsgsReq[count]--;
1978  EndToEndDelay->record(simTime() - chunk->firstSendTime);
1979  auto iter = sctpMain->assocStatMap.find(assocId);
1980  if (iter->second.numEndToEndMessages >= iter->second.startEndToEndDelay &&
1981  (iter->second.numEndToEndMessages < iter->second.stopEndToEndDelay || !iter->second.stopEndToEndDelay))
1982  {
1983  iter->second.cumEndToEndDelay += (simTime() - chunk->firstSendTime);
1984  }
1985  iter->second.numEndToEndMessages++;
1986 
1987  // set timestamp to sending time
1988  chunk->userData->setTimestamp(chunk->firstSendTime);
1989  delete chunk;
1990  sendToApp(msg);
1991  }
1992  i = (i + 1) % inboundStreams;
1993  count++;
1994  } while (i != state->nextRSid);
1995 
1996  state->nextRSid = (state->nextRSid + 1) % inboundStreams;
1997  if (restrict && state->bufferedMessages > 0) {
1998  for (auto & elem : receiveStreams) {
1999  if (!(elem.second->getDeliveryQ()->payloadQueue.empty())) {
2000  sendDataArrivedNotification(elem.second->getStreamId());
2001  break;
2002  }
2003  }
2004  }
2005  if ((state->queuedReceivedBytes == 0) && (fsm->getState() == SCTP_S_SHUTDOWN_ACK_SENT)) {
2006  EV_INFO << "SCTP_E_CLOSE" << endl;
2008  }
2009 }
bool swsMsgInvoked
Definition: SCTPAssociation.h:847
bool swsAvoidanceInvoked
Definition: SCTPAssociation.h:580
uint32 lastTsnAck
Definition: SCTPAssociation.h:614
uint32 bufferedMessages
Definition: SCTPAssociation.h:842
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
int count(const std::vector< T > &v, const T &a)
Definition: stlutils.h:58
uint32 swsLimit
Definition: SCTPAssociation.h:664
uint32 nextRSid
Definition: SCTPAssociation.h:663
cOutVector * EndToEndDelay
Definition: SCTPAssociation.h:926
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
uint64 localRwnd
Definition: SCTPAssociation.h:612
Definition: SCTPAssociation.h:64
cOutVector * statisticsQueuedReceivedBytes
Definition: SCTPAssociation.h:974
uint64 roomSumRcvStreams
Definition: SCTPAssociation.h:877
Definition: SCTPCommand.h:63
uint32 localMsgRwnd
Definition: SCTPAssociation.h:840
uint32 inboundStreams
Definition: SCTPAssociation.h:942
void sendDataArrivedNotification(uint16 sid)
Definition: SCTPAssociationUtil.cc:1789
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
SCTP * sctpMain
Definition: SCTPAssociation.h:962
L3Address remoteAddr
Definition: SCTPAssociation.h:911
Definition: SCTPAssociation.h:76
uint64_t uint64
Definition: Compat.h:28
AssocStatMap assocStatMap
Definition: SCTP.h:171
QueueCounter qCounter
Definition: SCTPAssociation.h:965
std::vector< int32 > numMsgsReq
Definition: SCTPAssociation.h:646
uint32 messageAcceptLimit
Definition: SCTPAssociation.h:639
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
uint32 messagesToPush
Definition: SCTPAssociation.h:633
uint32 bytesToAddPerRcvdChunk
Definition: SCTPAssociation.h:844
L3Address localAddr
Definition: SCTPAssociation.h:912
void sendSack()
Definition: SCTPAssociationUtil.cc:1764
int32 pushMessagesLeft
Definition: SCTPAssociation.h:634
int32 assocId
Definition: SCTPAssociation.h:908
uint32 assocPmtu
Definition: SCTPAssociation.h:627
void sendToApp(cMessage *msg)
Utility: sends packet to application.
Definition: SCTPAssociationUtil.cc:457
int32 appGateIndex
Definition: SCTPAssociation.h:907
void putInDeliveryQ(uint16 sid)
Definition: SCTPAssociationUtil.cc:1847
cFSM * fsm
Definition: SCTPAssociation.h:963
uint64 queuedReceivedBytes
Definition: SCTPAssociation.h:625
bool performStateTransition(const SCTPEventCode &event)
Implemements the pure SCTP state machine.
Definition: SCTPAssociationBase.cc:1182
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::putInDeliveryQ ( uint16  sid)
protected

Referenced by processDataArrived(), and pushUlp().

1848 {
1849  SCTPReceiveStream *rStream = receiveStreams.find(sid)->second;
1850  EV_INFO << "putInDeliveryQ: SSN=" << rStream->getExpectedStreamSeqNum()
1851  << " SID=" << sid
1852  << " QueueSize=" << rStream->getOrderedQ()->getQueueSize() << endl;
1853  while (rStream->getOrderedQ()->getQueueSize() > 0) {
1854  /* dequeue first from reassembly Q */
1855  SCTPDataVariables *chunk =
1856  rStream->getOrderedQ()->dequeueChunkBySSN(rStream->getExpectedStreamSeqNum());
1857  if (chunk) {
1858  EV_DETAIL << "putInDeliveryQ::chunk " << chunk->tsn
1859  << ", sid " << chunk->sid << " and ssn " << chunk->ssn
1860  << " dequeued from ordered queue. queuedReceivedBytes="
1861  << state->queuedReceivedBytes << " will be reduced by "
1862  << chunk->len / 8 << endl;
1864  state->queuedReceivedBytes -= chunk->len / 8;
1866 
1867  if (rStream->getDeliveryQ()->checkAndInsertChunk(chunk->tsn, chunk)) {
1869  state->queuedReceivedBytes += chunk->len / 8;
1870 
1871  EV_DETAIL << "data put in deliveryQ; queuedBytes now "
1872  << state->queuedReceivedBytes << endl;
1874  int32 seqnum = rStream->getExpectedStreamSeqNum();
1875  rStream->setExpectedStreamSeqNum(++seqnum);
1876  if (rStream->getExpectedStreamSeqNum() > 65535) {
1877  rStream->setExpectedStreamSeqNum(0);
1878  }
1879  }
1880  }
1881  else {
1882  break;
1883  }
1884  }
1885 }
uint32 bufferedMessages
Definition: SCTPAssociation.h:842
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
uint64 roomSumRcvStreams
Definition: SCTPAssociation.h:877
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
QueueCounter qCounter
Definition: SCTPAssociation.h:965
int32_t int32
Definition: Compat.h:31
uint64 queuedReceivedBytes
Definition: SCTPAssociation.h:625
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::putInTransmissionQ ( uint32  tsn,
SCTPDataVariables chunk 
)
protected

Referenced by processPacketDropArrived().

2871 {
2872  if (chunk->countsAsOutstanding) {
2873  decreaseOutstandingBytes(chunk);
2874  }
2875  auto it = transmissionQ->payloadQueue.find(tsn);
2876  if (it == transmissionQ->payloadQueue.end()) {
2877  EV_DETAIL << "putInTransmissionQ: insert tsn=" << tsn << endl;
2878  chunk->wasDropped = true;
2879  chunk->wasPktDropped = true;
2880  chunk->hasBeenFastRetransmitted = true;
2881  chunk->setNextDestination(chunk->getLastDestinationPath());
2882  if (!transmissionQ->checkAndInsertChunk(chunk->tsn, chunk)) {
2883  EV_DETAIL << "putInTransmissionQ: cannot add message/chunk (TSN="
2884  << tsn << ") to the transmissionQ" << endl;
2885  }
2886  else {
2887  chunk->enqueuedInTransmissionQ = true;
2888  auto q = qCounter.roomTransQ.find(chunk->getNextDestination());
2889  q->second += ADD_PADDING(chunk->len / 8 + SCTP_DATA_CHUNK_LENGTH);
2890  auto qb = qCounter.bookedTransQ.find(chunk->getNextDestination());
2891  qb->second += chunk->booksize;
2892  EV_DETAIL << "putInTransmissionQ: " << transmissionQ->getQueueSize() << " chunks="
2893  << q->second << " bytes" << endl;
2894  }
2895  }
2896 }
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
void decreaseOutstandingBytes(SCTPDataVariables *chunk)
Definition: SCTPAssociationRcvMessage.cc:41
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
QueueCounter qCounter
Definition: SCTPAssociation.h:965
bool checkAndInsertChunk(const uint32 key, SCTPDataVariables *chunk)
Definition: SCTPQueue.cc:50
uint32 getQueueSize() const
Definition: SCTPQueue.cc:60
void inet::sctp::SCTPAssociation::recalculateOLIABasis ( )
private
200  {
201  // it is necessary to calculate all flow information
202  double assoc_best_paths_l_rXl_r__rtt_r = 0.0;
203  //max_w_paths: The set of paths in all_paths with largest congestion windows.
204  //https://tools.ietf.org/html/draft-khalili-mptcp-congestion-control-05
205  uint32 max_w_paths = 0;
206  uint32 max_w_paths_cnt = 0; (void)max_w_paths_cnt; // FIXME this variable is unused
207  uint32 best_paths_cnt = 0;
208 
209  // Create the sets
210  int cnt = 0;
211  assocCollectedPaths.clear();
212  assocBestPaths.clear();
213  assocMaxWndPaths.clear();
214  for (SCTPPathMap::iterator iter = sctpPathMap.begin();
215  iter != sctpPathMap.end(); iter++, cnt++) {
216  SCTPPathVariables* path = iter->second;
217  bool next = false;
218  double r_sRTT = GET_SRTT(path->srtt.dbl());
219  double r_l_rXl_r__rtt_r = ((path->oliaSentBytes
220  * path->oliaSentBytes) / r_sRTT);
221  if (assocBestPaths.empty()) {
222  assoc_best_paths_l_rXl_r__rtt_r = r_l_rXl_r__rtt_r;
223  assocBestPaths.insert(std::make_pair(cnt, path));
224  next = true;
225  }
226  if (assocMaxWndPaths.empty()) {
227  max_w_paths = path->cwnd;
228  assocMaxWndPaths.insert(std::make_pair(cnt, path));
229  next = true;
230  }
231  if (next)
232  continue;
233  // set up the sets
234  if (r_l_rXl_r__rtt_r > assoc_best_paths_l_rXl_r__rtt_r) {
235  assoc_best_paths_l_rXl_r__rtt_r = r_l_rXl_r__rtt_r;
236  assocBestPaths.insert(std::make_pair(cnt, path));
237  assocBestPaths.erase(best_paths_cnt);
238 
239  best_paths_cnt = cnt;
240  next = true;
241  }
242  if (path->cwnd > max_w_paths) {
243  max_w_paths = path->cwnd;
244  assocMaxWndPaths.insert(std::make_pair(cnt, path));
245  assocMaxWndPaths.erase(best_paths_cnt);
246  max_w_paths_cnt = cnt;
247  next = true;
248  }
249  if (next)
250  continue;
251 
252  assocCollectedPaths.insert(std::make_pair(cnt, path));
253 
254  }
255 }
SCTPPathCollection assocMaxWndPaths
Definition: SCTPAssociation.h:902
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
uint32_t uint32
Definition: Compat.h:30
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
SCTPPathCollection assocCollectedPaths
Definition: SCTPAssociation.h:903
SCTPPathCollection assocBestPaths
Definition: SCTPAssociation.h:901
bool inet::sctp::SCTPAssociation::receiveStreamPresent ( uint16  sid)
protected

Referenced by processInAndOutResetRequestArrived(), and processOutgoingResetRequestArrived().

901 {
902  auto iterator = receiveStreams.find(id);
903  if (iterator == receiveStreams.end())
904  return false;
905  else
906  return true;
907 }
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
void inet::sctp::SCTPAssociation::recordCwndUpdate ( SCTPPathVariables path)
private

Referenced by processHeartbeatAckArrived(), and removePath().

356 {
357  if (path == nullptr) {
358  uint32 totalSsthresh = 0.0;
359  uint32 totalCwnd = 0.0;
360  double totalBandwidth = 0.0;
361  for (auto & elem : sctpPathMap)
362  {
363  SCTPPathVariables *path = elem.second;
364  totalSsthresh += path->ssthresh;
365  totalCwnd += path->cwnd;
366  totalBandwidth += path->cwnd / GET_SRTT(path->srtt.dbl());
367  }
368  statisticsTotalSSthresh->record(totalSsthresh);
369  statisticsTotalCwnd->record(totalCwnd);
370  statisticsTotalBandwidth->record(totalBandwidth);
371  }
372  else {
373  path->statisticsPathSSthresh->record(path->ssthresh);
374  path->statisticsPathCwnd->record(path->cwnd);
375  path->statisticsPathBandwidth->record(path->cwnd / GET_SRTT(path->srtt.dbl()));
376  }
377 }
cOutVector * statisticsTotalBandwidth
Definition: SCTPAssociation.h:978
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
cOutVector * statisticsTotalCwnd
Definition: SCTPAssociation.h:977
uint32_t uint32
Definition: Compat.h:30
cOutVector * statisticsTotalSSthresh
Definition: SCTPAssociation.h:976
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
void inet::sctp::SCTPAssociation::removePath ( )

Referenced by processAsconfArrived(), and inet::sctp::SCTP::removeAssociation().

1791 {
1792  while (!sctpPathMap.empty()) {
1793  auto pathIterator = sctpPathMap.begin();
1794  SCTPPathVariables *path = pathIterator->second;
1795  for (auto j = remoteAddressList.begin(); j != remoteAddressList.end(); j++) {
1796  if ((*j) == path->remoteAddress) {
1797  remoteAddressList.erase(j);
1798  break;
1799  }
1800  }
1801  EV_INFO << getFullPath() << " remove path " << path->remoteAddress << endl;
1802  stopTimer(path->HeartbeatTimer);
1803  delete path->HeartbeatTimer;
1804  stopTimer(path->HeartbeatIntervalTimer);
1805  delete path->HeartbeatIntervalTimer;
1806  stopTimer(path->T3_RtxTimer);
1807  delete path->T3_RtxTimer;
1808  stopTimer(path->CwndTimer);
1809  delete path->CwndTimer;
1810  stopTimer(path->ResetTimer);
1811  delete path->ResetTimer;
1812  stopTimer(path->AsconfTimer);
1813  delete path->AsconfTimer;
1814  stopTimer(path->BlockingTimer);
1815  delete path->BlockingTimer;
1816  delete path;
1817  sctpPathMap.erase(pathIterator);
1818  }
1819 }
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
AddressVector remoteAddressList
Definition: SCTPAssociation.h:940
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
void inet::sctp::SCTPAssociation::removePath ( const L3Address addr)
2054 {
2055  auto pathIterator = sctpPathMap.find(addr);
2056  if (pathIterator != sctpPathMap.end()) {
2057  SCTPPathVariables *path = pathIterator->second;
2058  path->cwnd = 0;
2059  path->ssthresh = 0;
2060  recordCwndUpdate(path);
2061 
2062  stopTimer(path->HeartbeatTimer);
2063  delete path->HeartbeatTimer;
2064  stopTimer(path->HeartbeatIntervalTimer);
2065  delete path->HeartbeatIntervalTimer;
2066  stopTimer(path->T3_RtxTimer);
2067  delete path->T3_RtxTimer;
2068  stopTimer(path->CwndTimer);
2069  delete path->CwndTimer;
2070  sctpPathMap.erase(pathIterator);
2071  stopTimer(path->ResetTimer);
2072  delete path->ResetTimer;
2073  stopTimer(path->AsconfTimer);
2074  delete path->AsconfTimer;
2075  delete path;
2076  }
2077 }
void recordCwndUpdate(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:355
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
void inet::sctp::SCTPAssociation::renegablyAckChunk ( SCTPDataVariables chunk,
SCTPPathVariables sackPath 
)
private

Referenced by handleChunkReportedAsAcked().

1981 {
1982  // ====== Bookkeeping ====================================================
1983  if (chunk->countsAsOutstanding) {
1984  decreaseOutstandingBytes(chunk);
1985  }
1986 
1987  if ((chunk->hasBeenCountedAsNewlyAcked == false) &&
1988  (chunk->hasBeenAcked == false))
1989  {
1990  if ((state->cmtMovedChunksReduceCwnd == false) ||
1991  (chunk->hasBeenMoved == false))
1992  {
1993  chunk->hasBeenCountedAsNewlyAcked = true;
1994  // The chunk has not been acked before.
1995  // Therefore, its size may *once* be counted as newly acked.
1996  chunk->getLastDestinationPath()->newlyAckedBytes += chunk->booksize;
1997  }
1998  }
1999 
2000  // ====== Acknowledge chunk =============================================
2001  ackChunk(chunk, sackPath);
2002  chunk->gapReports = 0;
2003 
2004  // ====== Remove chunk from transmission queue ===========================
2005  if (transmissionQ->getChunk(chunk->tsn)) { // I.R. 02.01.2007
2006  EV_INFO << "Found TSN " << chunk->tsn << " in transmissionQ -> remote it" << endl;
2007  transmissionQ->removeMsg(chunk->tsn);
2008  chunk->enqueuedInTransmissionQ = false;
2009  auto q = qCounter.roomTransQ.find(chunk->getNextDestination());
2010  q->second -= ADD_PADDING(chunk->len / 8 + SCTP_DATA_CHUNK_LENGTH);
2011  auto qb = qCounter.bookedTransQ.find(chunk->getNextDestination());
2012  qb->second -= chunk->booksize;
2013  }
2014 }
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
bool cmtMovedChunksReduceCwnd
Definition: SCTPAssociation.h:742
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
void decreaseOutstandingBytes(SCTPDataVariables *chunk)
Definition: SCTPAssociationRcvMessage.cc:41
void removeMsg(const uint32 key)
Definition: SCTPQueue.cc:157
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
void ackChunk(SCTPDataVariables *chunk, SCTPPathVariables *sackPath)
Definition: SCTPAssociation.h:1437
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
SCTPDataVariables * getChunk(const uint32 key) const
Definition: SCTPQueue.cc:123
QueueCounter qCounter
Definition: SCTPAssociation.h:965
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::resetExpectedSsn ( uint16  id)
protected

Referenced by processInAndOutResetRequestArrived(), processOutgoingResetRequestArrived(), and processResetResponseArrived().

854 {
855  auto iterator = receiveStreams.find(id);
856  iterator->second->setExpectedStreamSeqNum(0);
857  EV_INFO << "Expected Ssn " << id <<" has been resetted on " << localAddr << "\n";
859 }
Definition: SCTPCommand.h:80
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
L3Address localAddr
Definition: SCTPAssociation.h:912
void inet::sctp::SCTPAssociation::resetExpectedSsns ( )
protected

Referenced by checkStreamsToReset(), process_RCV_Message(), processInAndOutResetRequestArrived(), processOutAndResponseArrived(), processOutgoingResetRequestArrived(), processResetResponseArrived(), and sendStreamResetResponse().

846 {
847  for (auto & elem : receiveStreams)
848  elem.second->setExpectedStreamSeqNum(0);
849  EV_INFO << "Expected Ssns have been resetted on " << localAddr << "\n";
851 }
Definition: SCTPCommand.h:80
SCTPReceiveStreamMap receiveStreams
Definition: SCTPAssociation.h:969
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
L3Address localAddr
Definition: SCTPAssociation.h:912
void inet::sctp::SCTPAssociation::resetGapLists ( )
protected

Referenced by sendStreamResetResponse().

715 {
716  uint32 newCumAck = state->gapList.getHighestTSNReceived() + (1<<31);
717  state->gapList.resetGaps(newCumAck);
718 }
SCTPGapList gapList
Definition: SCTPAssociation.h:619
void resetGaps(const uint32 newCumAck)
Definition: SCTPGapList.cc:395
uint32_t uint32
Definition: Compat.h:30
uint32 getHighestTSNReceived() const
Definition: SCTPGapList.h:96
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::resetSsn ( uint16  id)
protected

Referenced by processIncomingResetRequestArrived(), processResetResponseArrived(), sendBundledOutgoingResetAndResponse(), and sendOutgoingResetRequest().

885 {
886  auto iterator = sendStreams.find(id);
887  iterator->second->setNextStreamSeqNum(0);
888  EV_INFO << "SSns resetted on " << localAddr << "\n";
889 }
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
L3Address localAddr
Definition: SCTPAssociation.h:912
void inet::sctp::SCTPAssociation::resetSsns ( )
protected

Methods for Stream Reset.

Referenced by processIncomingResetRequestArrived(), processOutAndResponseArrived(), processResetResponseArrived(), and sendStreamResetResponse().

877 {
878  for (auto & elem : sendStreams)
879  elem.second->setNextStreamSeqNum(0);
880  EV_INFO << "SSns resetted on " << localAddr << "\n";
882 }
Definition: SCTPCommand.h:79
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
L3Address localAddr
Definition: SCTPAssociation.h:912
void inet::sctp::SCTPAssociation::retransmitAsconf ( )
protected

Referenced by process_TIMEOUT_ASCONF(), and processPacketDropArrived().

168 {
169  SCTPMessage *sctpmsg = new SCTPMessage();
170  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
171 
172  SCTPAsconfChunk *sctpasconf = new SCTPAsconfChunk("ASCONF-RTX");
173  sctpasconf = check_and_cast<SCTPAsconfChunk *>(state->asconfChunk->dup());
174  sctpasconf->setChunkType(ASCONF);
175  sctpasconf->setByteLength(state->asconfChunk->getByteLength());
176 
177  if (state->auth && state->peerAuth) {
178  SCTPAuthenticationChunk *authChunk = createAuthChunk();
179  sctpmsg->addChunk(authChunk);
180  auto it = sctpMain->assocStatMap.find(assocId);
181  it->second.numAuthChunksSent++;
182  }
183  sctpmsg->addChunk(sctpasconf);
184 
185  sendToIP(sctpmsg);
186 }
SCTPAsconfChunk * asconfChunk
Definition: SCTPAssociation.h:782
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
Definition: SCTPAssociation.h:130
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
bool auth
Definition: SCTPAssociation.h:822
SCTP * sctpMain
Definition: SCTPAssociation.h:962
AssocStatMap assocStatMap
Definition: SCTP.h:171
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
virtual SCTPAsconfChunk * dup() const override
Definition: SCTPMessage.h:168
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::retransmitCookieEcho ( )
protected

Referenced by process_RCV_Message(), process_TIMEOUT_INIT_REXMIT(), and processPacketDropArrived().

956 {
957  SCTPAuthenticationChunk *authChunk;
958  SCTPMessage *sctpmsg = new SCTPMessage();
959  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
960  SCTPCookieEchoChunk *cookieEchoChunk = check_and_cast<SCTPCookieEchoChunk *>(state->cookieChunk->dup());
961  if (cookieEchoChunk->getCookieArraySize() == 0) {
962  cookieEchoChunk->setStateCookie(state->cookieChunk->getStateCookie()->dup());
963  }
965  authChunk = createAuthChunk();
966  sctpmsg->addChunk(authChunk);
967  auto it = sctpMain->assocStatMap.find(assocId);
968  it->second.numAuthChunksSent++;
969  }
970  sctpmsg->addChunk(cookieEchoChunk);
971 
972  EV_INFO << "retransmitCookieEcho localAddr=" << localAddr << " remoteAddr" << remoteAddr << "\n";
973 
974  sendToIP(sctpmsg);
975 }
Definition: SCTPAssociation.h:121
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
bool auth
Definition: SCTPAssociation.h:822
SCTP * sctpMain
Definition: SCTPAssociation.h:962
L3Address remoteAddr
Definition: SCTPAssociation.h:911
AssocStatMap assocStatMap
Definition: SCTP.h:171
SCTPCookieEchoChunk * cookieChunk
pointer to the cookie chunk data structure (for retransmissions)
Definition: SCTPAssociation.h:654
L3Address localAddr
Definition: SCTPAssociation.h:912
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::retransmitInit ( )
protected

Retransmitting chunks.

Referenced by process_RCV_Message(), process_TIMEOUT_INIT_REXMIT(), and processPacketDropArrived().

713 {
714  SCTPMessage *sctpmsg = new SCTPMessage();
715  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
716  SCTPInitChunk *sctpinit; // = new SCTPInitChunk("INIT");
717 
718  EV_INFO << "Retransmit InitChunk=" << &sctpinit << "\n";
719 
720  sctpinit = check_and_cast<SCTPInitChunk *>(state->initChunk->dup());
721  sctpinit->setChunkType(INIT);
722  sctpmsg->addChunk(sctpinit);
723 
724  sendToIP(sctpmsg);
725 }
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
SCTPInitChunk * initChunk
pointer to the init chunk data structure (for retransmissions)
Definition: SCTPAssociation.h:652
Definition: SCTPAssociation.h:112
virtual SCTPInitChunk * dup() const override
Definition: SCTPMessage_m.h:234
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::retransmitReset ( )
protected

Referenced by process_TIMEOUT_RESET().

26 {
27  SCTPMessage *sctpmsg = new SCTPMessage();
28  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
29  SCTPStreamResetChunk *sctpreset = check_and_cast<SCTPStreamResetChunk *>(state->resetChunk->dup());
30  state->numResetRequests = sctpreset->getParametersArraySize();
31  sctpreset->setName("RESETRetransmit");
32  sctpreset->setChunkType(RE_CONFIG);
33  sctpmsg->addChunk(sctpreset);
34  state->waitForResponse = true;
35  EV_INFO << "retransmitStreamReset localAddr=" << localAddr << " remoteAddr" << remoteAddr << "\n";
36 
37  sendToIP(sctpmsg);
38 }
virtual SCTPStreamResetChunk * dup() const override
Definition: SCTPMessage.h:135
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
bool waitForResponse
Definition: SCTPAssociation.h:789
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
Definition: SCTPAssociation.h:128
L3Address remoteAddr
Definition: SCTPAssociation.h:911
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
uint16 numResetRequests
Definition: SCTPAssociation.h:644
L3Address localAddr
Definition: SCTPAssociation.h:912
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::retransmitShutdown ( )
protected

Referenced by process_TIMEOUT_SHUTDOWN(), and processPacketDropArrived().

1162 {
1163  SCTPMessage *sctpmsg = new SCTPMessage();
1164  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
1165  SCTPShutdownChunk *shutdownChunk;
1166  shutdownChunk = check_and_cast<SCTPShutdownChunk *>(state->shutdownChunk->dup());
1167  sctpmsg->addChunk(shutdownChunk);
1168 
1169  EV_INFO << "retransmitShutdown localAddr=" << localAddr << " remoteAddr" << remoteAddr << "\n";
1170 
1171  sendToIP(sctpmsg);
1172 }
virtual SCTPShutdownChunk * dup() const override
Definition: SCTPMessage_m.h:1075
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
L3Address remoteAddr
Definition: SCTPAssociation.h:911
L3Address localAddr
Definition: SCTPAssociation.h:912
SCTPShutdownChunk * shutdownChunk
pointer to the resetChunk (for retransmission)
Definition: SCTPAssociation.h:656
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::retransmitShutdownAck ( )
protected

Referenced by process_TIMEOUT_SHUTDOWN(), and processPacketDropArrived().

1175 {
1176  SCTPMessage *sctpmsg = new SCTPMessage();
1177  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
1178  SCTPShutdownAckChunk *shutdownAckChunk;
1179  shutdownAckChunk = check_and_cast<SCTPShutdownAckChunk *>(state->shutdownAckChunk->dup());
1180  sctpmsg->addChunk(shutdownAckChunk);
1181 
1182  EV_INFO << "retransmitShutdownAck localAddr=" << localAddr << " remoteAddr" << remoteAddr << "\n";
1183 
1184  sendToIP(sctpmsg);
1185 }
virtual SCTPShutdownAckChunk * dup() const override
Definition: SCTPMessage_m.h:1111
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
SCTPShutdownAckChunk * shutdownAckChunk
Definition: SCTPAssociation.h:657
L3Address remoteAddr
Definition: SCTPAssociation.h:911
L3Address localAddr
Definition: SCTPAssociation.h:912
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int32 inet::sctp::SCTPAssociation::rpPathBlockingControl ( SCTPPathVariables path,
const double  reduction 
)
protected
413 {
414  // ====== Compute new cwnd ===============================================
415  const int32 newCwnd = (int32)ceil(path->cwnd - reduction);
416  // NOTE: newCwnd may be negative!
417  // ====== Block path if newCwnd < 1 MTU ==================================
418  if ((state->rpPathBlocking == true) && (newCwnd < (int32)path->pmtu)) {
419  if ((path->blockingTimeout < 0.0) || (path->blockingTimeout < simTime())) {
420  // printf("a=%1.9f b=%1.9f a=%d b=%d\n", path->blockingTimeout.dbl(), simTime().dbl(), (path->blockingTimeout < 0.0), (path->blockingTimeout < simTime()) );
421 
422  const simtime_t timeout = (state->rpScaleBlockingTimeout == true) ?
423  path->cmtGroupPaths * path->pathRto :
424  path->pathRto;
425  EV << "Blocking " << path->remoteAddress << " for " << timeout << endl;
426 
427  path->blockingTimeout = simTime() + timeout;
428  assert(!path->BlockingTimer->isScheduled());
429  startTimer(path->BlockingTimer, timeout);
430  }
431  }
432  return newCwnd;
433 }
bool rpScaleBlockingTimeout
Definition: SCTPAssociation.h:769
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
bool rpPathBlocking
Definition: SCTPAssociation.h:768
int32_t int32
Definition: Compat.h:31
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::scheduleSack ( )
protected

Referenced by process_RCV_Message().

1259 {
1260  /* increase SACK counter, we received another data PACKET */
1262  state->ackState++;
1263  else {
1265  state->firstChunkReceived = true;
1266  }
1267 
1268  EV_DETAIL << "scheduleSack() : ackState is now: " << state->ackState << "\n";
1269 
1270  if (state->ackState <= sackFrequency - 1) {
1271  /* start a SACK timer if none is running, to expire 200 ms (or parameter) from now */
1272  if (!SackTimer->isScheduled()) {
1274  }
1275  /* else: leave timer running, and do nothing... */ else {
1276  /* is this possible at all ? Check this... */
1277 
1278  EV_DETAIL << "SACK timer running, but scheduleSack() called\n";
1279  }
1280  }
1281 }
uint32 sackFrequency
Definition: SCTPAssociation.h:949
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
bool firstChunkReceived
Definition: SCTPAssociation.h:579
cMessage * SackTimer
Definition: SCTPAssociation.h:922
uint32 ackState
Definition: SCTPAssociation.h:618
double sackPeriod
Definition: SCTPAssociation.h:950
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::scheduleTimeout ( cMessage *  msg,
const simtime_t &  timeout 
)
inlineprotected

Utility: start a timer.

Referenced by startTimer().

1189  {
1190  sctpMain->scheduleAt(simTime() + timeout, msg);
1191  }
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void inet::sctp::SCTPAssociation::sendAbort ( uint16  tBit = 0)
protected

Referenced by process_ABORT(), process_RCV_Message(), process_TIMEOUT_HEARTBEAT(), process_TIMEOUT_INIT_REXMIT(), process_TIMEOUT_RTX(), process_TIMEOUT_SHUTDOWN(), processCookieEchoArrived(), processErrorArrived(), processInitArrived(), and updateCounters().

1102 {
1103  SCTPAuthenticationChunk *authChunk;
1104  SCTPMessage *msg = new SCTPMessage();
1105  msg->setByteLength(SCTP_COMMON_HEADER);
1106 
1107  EV_INFO << "SCTPAssociationUtil:sendABORT localPort=" << localPort << " remotePort=" << remotePort << "\n";
1108 
1109  msg->setSrcPort(localPort);
1110  msg->setDestPort(remotePort);
1111  SCTPAbortChunk *abortChunk = new SCTPAbortChunk("ABORT");
1112  abortChunk->setChunkType(ABORT);
1113  abortChunk->setT_Bit(tBit);
1114  abortChunk->setByteLength(SCTP_ABORT_CHUNK_LENGTH);
1115  if (state->auth && state->peerAuth && typeInChunkList(ABORT)) {
1116  authChunk = createAuthChunk();
1117  msg->addChunk(authChunk);
1118  auto it = sctpMain->assocStatMap.find(assocId);
1119  it->second.numAuthChunksSent++;
1120  }
1121  msg->addChunk(abortChunk);
1122  if (state->resetChunk != nullptr) {
1123  delete state->resetChunk;
1124  }
1125  sendToIP(msg, remoteAddr);
1126 }
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
bool auth
Definition: SCTPAssociation.h:822
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
L3Address remoteAddr
Definition: SCTPAssociation.h:911
AssocStatMap assocStatMap
Definition: SCTP.h:171
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
int32 assocId
Definition: SCTPAssociation.h:908
Definition: SCTPAssociation.h:117
bool peerAuth
Definition: SCTPAssociation.h:821
uint16 localPort
Definition: SCTPAssociation.h:913
#define SCTP_ABORT_CHUNK_LENGTH
Definition: SCTPAssociation.h:218
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendAddInAndOutStreamsRequest ( SCTPResetInfo info)
protected

Referenced by process_STREAM_RESET().

665 {
666  EV_INFO << "StreamReset:sendAddInandStreamsRequest\n";
667  SCTPMessage *msg = new SCTPMessage();
668  msg->setByteLength(SCTP_COMMON_HEADER);
669  msg->setSrcPort(localPort);
670  msg->setDestPort(remotePort);
671  SCTPResetTimer *rt = new SCTPResetTimer();
672  SCTPStreamResetChunk *resetChunk = new SCTPStreamResetChunk("AddInOutCONFIG");
673  resetChunk->setChunkType(RE_CONFIG);
674  resetChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
676  SCTPAddStreamsRequestParameter *addOutStreams = new SCTPAddStreamsRequestParameter("Add_Out_Streams");
677  addOutStreams->setParameterType(ADD_OUTGOING_STREAMS_REQUEST_PARAMETER);
678  addOutStreams->setNumberOfStreams(info->getOutstreams());
679  state->numAddedOutStreams = info->getOutstreams();
680  rt->setOutSN(srsn);
681  rt->setOutAcked(false);
683  state->requests[srsn].result = 100;
685  addOutStreams->setSrReqSn(srsn++);
686  addOutStreams->setByteLength(SCTP_ADD_STREAMS_REQUEST_PARAMETER_LENGTH);
687  SCTPAddStreamsRequestParameter *addInStreams = new SCTPAddStreamsRequestParameter("Add_In_Streams");
688  addInStreams->setParameterType(ADD_INCOMING_STREAMS_REQUEST_PARAMETER);
689  addInStreams->setNumberOfStreams(info->getInstreams());
690  state->numAddedInStreams = info->getInstreams();
691  rt->setInSN(srsn);
692  rt->setInAcked(false);
694  state->requests[srsn].result = 100;
696  addInStreams->setSrReqSn(srsn++);
697  addInStreams->setByteLength(SCTP_ADD_STREAMS_REQUEST_PARAMETER_LENGTH);
698  resetChunk->addParameter(addOutStreams);
699  resetChunk->addParameter(addInStreams);
702  if (state->resetChunk != nullptr) {
703  delete state->resetChunk;
704  state->resetChunk = nullptr;
705  }
706  state->resetChunk = check_and_cast<SCTPStreamResetChunk *>(resetChunk->dup());
707  state->resetChunk->setName("stateAddInOutResetChunk");
708  msg->addChunk(resetChunk);
709  sendToIP(msg, remoteAddr);
710  PK(getPath(remoteAddr)->ResetTimer)->encapsulate(rt);
711  startTimer(getPath(remoteAddr)->ResetTimer, getPath(remoteAddr)->pathRto);
712 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
uint32 streamResetSequenceNumber
Definition: SCTPAssociation.h:793
#define SCTP_ADD_STREAMS_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:229
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
uint16 localRequestType
Definition: SCTPAssociation.h:810
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
uint16 numAddedOutStreams
Definition: SCTPAssociation.h:672
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
uint16 remotePort
Definition: SCTPAssociation.h:914
Definition: SCTPAssociation.h:128
L3Address remoteAddr
Definition: SCTPAssociation.h:911
void addOutStreams(uint32 outStreams)
Definition: SCTPSSFunctions.cc:80
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
IRoutingTable * rt
Definition: SCTPAssociation.h:936
uint16 numResetRequests
Definition: SCTPAssociation.h:644
uint32_t uint32
Definition: Compat.h:30
Definition: SCTPAssociation.h:162
uint16 numAddedInStreams
Definition: SCTPAssociation.h:673
#define PK(msg)
Definition: INETDefs.h:92
void addInStreams(uint32 inStreams)
Definition: SCTPSSFunctions.cc:65
uint16 localPort
Definition: SCTPAssociation.h:913
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendAddOutgoingStreamsRequest ( uint16  numStreams)
protected

Referenced by process_RCV_Message().

615 {
616  EV_INFO << "StreamReset:sendAddOutgoingStreamsRequest\n";
617  uint32 srsn = 0;
618  SCTPMessage *msg = new SCTPMessage();
619  msg->setByteLength(SCTP_COMMON_HEADER);
620  msg->setSrcPort(localPort);
621  msg->setDestPort(remotePort);
622  SCTPStreamResetChunk *resetChunk = new SCTPStreamResetChunk("AddRE_CONFIG");
623  resetChunk->setChunkType(RE_CONFIG);
624  resetChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
626  if (resDat != nullptr && resDat->sn == state->streamResetSequenceNumber - 1) {
627  srsn = state->streamResetSequenceNumber - 1;
628  } else {
630  state->requests[srsn].result = 100;
632  state->requests[srsn].sn = srsn;
633  auto it = sctpMain->assocStatMap.find(assocId);
634  it->second.numResetRequestsSent++;
635  }
636  SCTPAddStreamsRequestParameter *addStreams = new SCTPAddStreamsRequestParameter("Add_Streams");
637  addStreams->setParameterType(ADD_OUTGOING_STREAMS_REQUEST_PARAMETER);
638  addStreams->setNumberOfStreams(numStreams);
639  state->numAddedOutStreams = addStreams->getNumberOfStreams();
641  addStreams->setSrReqSn(srsn);
642  addStreams->setByteLength(SCTP_ADD_STREAMS_REQUEST_PARAMETER_LENGTH);
643  resetChunk->addParameter(addStreams);
644  if (state->resetChunk != nullptr) {
645  delete state->resetChunk;
646  state->resetChunk = nullptr;
647  }
648  state->resetChunk = check_and_cast<SCTPStreamResetChunk *>(resetChunk->dup());
649  state->resetChunk->setName("stateAddResetChunk");
650  msg->addChunk(resetChunk);
651  sendToIP(msg, remoteAddr);
652  if (!(getPath(remoteAddr)->ResetTimer->isScheduled())) {
653  SCTPResetTimer *rt = new SCTPResetTimer();
654  rt->setInSN(0);
655  rt->setInAcked(true);
656  rt->setOutSN(srsn);
657  rt->setOutAcked(false);
658  PK(getPath(remoteAddr)->ResetTimer)->encapsulate(rt);
659  startTimer(getPath(remoteAddr)->ResetTimer, getPath(remoteAddr)->pathRto);
660  }
662 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
uint32 streamResetSequenceNumber
Definition: SCTPAssociation.h:793
#define SCTP_ADD_STREAMS_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:229
Definition: SCTPAssociation.h:155
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
uint16 localRequestType
Definition: SCTPAssociation.h:810
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
uint16 numAddedOutStreams
Definition: SCTPAssociation.h:672
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
Definition: SCTPAssociation.h:128
L3Address remoteAddr
Definition: SCTPAssociation.h:911
AssocStatMap assocStatMap
Definition: SCTP.h:171
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
IRoutingTable * rt
Definition: SCTPAssociation.h:936
uint32_t uint32
Definition: Compat.h:30
struct inet::sctp::SCTPStateVariables::requestData RequestData
#define PK(msg)
Definition: INETDefs.h:92
int32 assocId
Definition: SCTPAssociation.h:908
uint16 localPort
Definition: SCTPAssociation.h:913
RequestData * findTypeInRequests(uint16 type)
Definition: SCTPAssociationBase.cc:545
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendAsconf ( const char *  type,
const bool  remote = false 
)
protected

Methods for Add-IP and AUTH.

Referenced by processAsconfArrived(), and processErrorArrived().

26 {
27  SCTPAuthenticationChunk *authChunk = nullptr;
28  bool nat = false;
29  L3Address targetAddr = remoteAddr;
30  uint16 chunkLength = 0;
31 
32  if (state->asconfOutstanding == false) {
33  EV_DEBUG << "sendAsconf\n";
34  SCTPMessage *sctpAsconf = new SCTPMessage("ASCONF-MSG");
35  sctpAsconf->setByteLength(SCTP_COMMON_HEADER);
36  sctpAsconf->setSrcPort(localPort);
37  sctpAsconf->setDestPort(remotePort);
38  SCTPAsconfChunk *asconfChunk = new SCTPAsconfChunk("ASCONF-CHUNK");
39  asconfChunk->setChunkType(ASCONF);
40  asconfChunk->setSerialNumber(state->asconfSn);
41  chunkLength = SCTP_ADD_IP_CHUNK_LENGTH;
42  EV_INFO << "localAddr=" << localAddr << ", remoteAddr=" << remoteAddr << "\n";
43  if (getAddressLevel(localAddr) == 3 && getAddressLevel(remoteAddr) == 4 && (bool)sctpMain->par("natFriendly")) {
44  asconfChunk->setAddressParam(L3Address("0.0.0.0"));
45  asconfChunk->setPeerVTag(peerVTag);
46  nat = true;
47  }
48  else {
49  asconfChunk->setAddressParam(localAddr);
50  }
51 
53  chunkLength += 20;
54  }
55  else if (localAddr.getType() == L3Address::IPv4) {
56  chunkLength += 8;
57  }
58  else
59  throw cRuntimeError("Unknown address type");
60 
61  asconfChunk->setByteLength(chunkLength);
62 
63  cStringTokenizer tokenizer(type);
64  while (tokenizer.hasMoreTokens()) {
65  const char *token = tokenizer.nextToken();
66  switch (atoi(token)) {
67  case ADD_IP_ADDRESS: {
68  SCTPAddIPParameter *ipParam;
69  ipParam = new SCTPAddIPParameter("AddIP");
70  chunkLength += SCTP_ADD_IP_PARAMETER_LENGTH;
71  ipParam->setParameterType(ADD_IP_ADDRESS);
72  ipParam->setRequestCorrelationId(++state->corrIdNum);
73  if (nat) {
74  ipParam->setAddressParam(L3Address("0.0.0.0"));
75  sctpMain->addLocalAddressToAllRemoteAddresses(this, L3AddressResolver().resolve(sctpMain->par("addAddress"), 1), (std::vector<L3Address>)remoteAddressList);
76  state->localAddresses.push_back(L3AddressResolver().resolve(sctpMain->par("addAddress"), 1));
77  if (remote)
78  targetAddr = remoteAddr;
79  else
80  targetAddr = getNextAddress(getPath(remoteAddr));
81  }
82  else {
83  ipParam->setAddressParam(L3AddressResolver().resolve(sctpMain->par("addAddress"), 1));
84  }
85  if (ipParam->getAddressParam().getType() == L3Address::IPv6) {
86  chunkLength += 20;
87  ipParam->setBitLength((SCTP_ADD_IP_PARAMETER_LENGTH + 20) * 8);
88  }
89  else if (ipParam->getAddressParam().getType() == L3Address::IPv4) {
90  chunkLength += 8;
91  ipParam->setBitLength((SCTP_ADD_IP_PARAMETER_LENGTH + 8) * 8);
92  }
93  else
94  throw cRuntimeError("Unknown address type");
95  asconfChunk->addAsconfParam(ipParam);
96  break;
97  }
98 
99  case DELETE_IP_ADDRESS: {
100  SCTPDeleteIPParameter *delParam;
101  delParam = new SCTPDeleteIPParameter("DeleteIP");
102  chunkLength += SCTP_ADD_IP_PARAMETER_LENGTH;
103  delParam->setParameterType(DELETE_IP_ADDRESS);
104  delParam->setRequestCorrelationId(++state->corrIdNum);
105  delParam->setAddressParam(L3AddressResolver().resolve(sctpMain->par("addAddress"), 1));
106  if (delParam->getAddressParam().getType() == L3Address::IPv6) {
107  chunkLength += 20;
108  delParam->setBitLength((SCTP_ADD_IP_PARAMETER_LENGTH + 20) * 8);
109  }
110  else if (delParam->getAddressParam().getType() == L3Address::IPv4) {
111  chunkLength += 8;
112  delParam->setBitLength((SCTP_ADD_IP_PARAMETER_LENGTH + 8) * 8);
113  }
114  else
115  throw cRuntimeError("Unknown address type");
116  asconfChunk->addAsconfParam(delParam);
117  break;
118  }
119 
120  case SET_PRIMARY_ADDRESS: {
121  SCTPSetPrimaryIPParameter *priParam;
122  priParam = new SCTPSetPrimaryIPParameter("SetPrimary");
123  chunkLength += SCTP_ADD_IP_PARAMETER_LENGTH;
124  priParam->setParameterType(SET_PRIMARY_ADDRESS);
125  priParam->setRequestCorrelationId(++state->corrIdNum);
126  priParam->setAddressParam(L3AddressResolver().resolve(sctpMain->par("addAddress"), 1));
127  if (nat) {
128  priParam->setAddressParam(L3Address("0.0.0.0"));
129  }
130  if (priParam->getAddressParam().getType() == L3Address::IPv6) {
131  chunkLength += 20;
132  priParam->setByteLength((SCTP_ADD_IP_PARAMETER_LENGTH + 20));
133  }
134  else if (priParam->getAddressParam().getType() == L3Address::IPv4) {
135  chunkLength += 8;
136  priParam->setByteLength((SCTP_ADD_IP_PARAMETER_LENGTH + 8));
137  }
138  else
139  throw cRuntimeError("Unknown address type");
140  asconfChunk->addAsconfParam(priParam);
141  break;
142  }
143 
144  default:
145  printf("type %d not known\n", atoi(token));
146  break;
147  }
148  }
149  asconfChunk->setByteLength(chunkLength);
150 
151  if (state->auth && state->peerAuth) {
152  authChunk = createAuthChunk();
153  sctpAsconf->addChunk(authChunk);
154  auto it = sctpMain->assocStatMap.find(assocId);
155  it->second.numAuthChunksSent++;
156  }
157  sctpAsconf->addChunk(asconfChunk);
158 
159  state->asconfChunk = check_and_cast<SCTPAsconfChunk *>(asconfChunk->dup());
160  state->asconfChunk->setName("STATE-ASCONF");
161 
162  sendToIP(sctpAsconf, targetAddr);
163  state->asconfOutstanding = true;
164  }
165 }
AddressType getType() const
Definition: L3Address.cc:52
uint32 asconfSn
Definition: SCTPAssociation.h:778
Definition: SCTPAssociation.h:172
uint32 corrIdNum
Definition: SCTPAssociation.h:780
Definition: L3Address.h:47
AddressVector remoteAddressList
Definition: SCTPAssociation.h:940
SCTPAsconfChunk * asconfChunk
Definition: SCTPAssociation.h:782
const L3Address & getNextAddress(const SCTPPathVariables *oldPath) const
Definition: SCTPAssociation.h:1220
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
Definition: SCTPAssociation.h:168
Definition: SCTPAssociation.h:130
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
#define SCTP_ADD_IP_PARAMETER_LENGTH
Definition: SCTPAssociation.h:232
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
bool auth
Definition: SCTPAssociation.h:822
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
uint32 peerVTag
Definition: SCTPAssociation.h:916
Definition: SCTPAssociation.h:171
L3Address remoteAddr
Definition: SCTPAssociation.h:911
AssocStatMap assocStatMap
Definition: SCTP.h:171
#define SCTP_ADD_IP_CHUNK_LENGTH
Definition: SCTPAssociation.h:231
L3Address localAddr
Definition: SCTPAssociation.h:912
static int getAddressLevel(const L3Address &addr)
Utility: return IPv4 or IPv6 address level.
Definition: SCTPAssociationUtil.cc:2814
bool asconfOutstanding
Definition: SCTPAssociation.h:781
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
uint16_t uint16
Definition: Compat.h:32
uint16 localPort
Definition: SCTPAssociation.h:913
void addLocalAddressToAllRemoteAddresses(SCTPAssociation *assoc, L3Address address, std::vector< L3Address > remAddresses)
Definition: SCTP.cc:661
Definition: L3Address.h:46
AddressVector localAddresses
Definition: SCTPAssociation.h:607
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendAsconfAck ( const uint32  serialNumber)
protected
189 {
190  SCTPMessage *sctpAsconfAck = new SCTPMessage("ASCONF_ACK");
191  sctpAsconfAck->setByteLength(SCTP_COMMON_HEADER);
192  sctpAsconfAck->setSrcPort(localPort);
193  sctpAsconfAck->setDestPort(remotePort);
194 
195  SCTPAsconfAckChunk *asconfAckChunk = new SCTPAsconfAckChunk("ASCONF_ACK");
196  asconfAckChunk->setChunkType(ASCONF_ACK);
197  asconfAckChunk->setSerialNumber(serialNumber);
198  asconfAckChunk->setByteLength(SCTP_ADD_IP_CHUNK_LENGTH);
199  if (state->auth && state->peerAuth) {
200  SCTPAuthenticationChunk *authChunk = createAuthChunk();
201  sctpAsconfAck->addChunk(authChunk);
202  auto it = sctpMain->assocStatMap.find(assocId);
203  it->second.numAuthChunksSent++;
204  }
205  sctpAsconfAck->addChunk(asconfAckChunk);
206  sendToIP(sctpAsconfAck, remoteAddr);
207 }
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
bool auth
Definition: SCTPAssociation.h:822
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
L3Address remoteAddr
Definition: SCTPAssociation.h:911
AssocStatMap assocStatMap
Definition: SCTP.h:171
#define SCTP_ADD_IP_CHUNK_LENGTH
Definition: SCTPAssociation.h:231
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
Definition: SCTPAssociation.h:126
uint16 localPort
Definition: SCTPAssociation.h:913
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendBundledOutgoingResetAndResponse ( SCTPIncomingSSNResetRequestParameter requestParam)
protected
207 {
208  EV_INFO << "sendBundledOutgoingResetAndResponse to " << remoteAddr << "\n";
209  uint16 len = 0;
210  if (!(getPath(remoteAddr)->ResetTimer->isScheduled())) {
211  SCTPStreamResetChunk *resetChunk = new SCTPStreamResetChunk("Outbundle_CONFIG");
212  resetChunk->setChunkType(RE_CONFIG);
213  resetChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
215  SCTPOutgoingSSNResetRequestParameter *outResetParam;
216  outResetParam = new SCTPOutgoingSSNResetRequestParameter("Outgoing_SSN_B_Request_Param");
217  outResetParam->setParameterType(OUTGOING_RESET_REQUEST_PARAMETER);
218  state->requests[srsn].result = 100;
221  outResetParam->setSrReqSn(srsn++);
222  outResetParam->setSrResSn(requestParam->getSrReqSn());
223  outResetParam->setLastTsn(state->nextTSN - 1);
224  if (state->streamsToReset.size() > 0) {
225  outResetParam->setStreamNumbersArraySize(state->streamsToReset.size());
226  uint16 i = 0;
227  for (std::list<uint16>::iterator it = state->streamsToReset.begin(); it != state->streamsToReset.end(); ++it) {
228  outResetParam->setStreamNumbers(i, *it);
229  state->resetOutStreams.push_back(outResetParam->getStreamNumbers(i));
230  resetSsn(outResetParam->getStreamNumbers(i));
231  i++;
232  }
233  len = state->streamsToReset.size() * 2;
234  state->streamsToReset.clear();
235  } else if (requestParam->getStreamNumbersArraySize() > 0) {
236  outResetParam->setStreamNumbersArraySize(requestParam->getStreamNumbersArraySize());
237  for (uint16 i = 0; i < requestParam->getStreamNumbersArraySize(); i++) {
238  outResetParam->setStreamNumbers(i, requestParam->getStreamNumbers(i));
239  }
240  len = requestParam->getStreamNumbersArraySize() * 2;
241  }
242  outResetParam->setByteLength(SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH + len);
243  resetChunk->addParameter(outResetParam);
245 
246  SCTPStreamResetChunk *resetResponseChunk;
247  EV_INFO << "sendbundledStreamResetResponse to " << remoteAddr << "\n";
248  resetResponseChunk = new SCTPStreamResetChunk("responseRE_CONFIG");
249  resetResponseChunk->setChunkType(RE_CONFIG);
250  resetResponseChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
251  SCTPStreamResetResponseParameter *responseParam = new SCTPStreamResetResponseParameter("Response_Param");
252  responseParam->setParameterType(STREAM_RESET_RESPONSE_PARAMETER);
253  responseParam->setSrResSn(requestParam->getSrReqSn());
254  responseParam->setResult(PERFORMED);
255  responseParam->setByteLength(SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH);
256  resetResponseChunk->addParameter(responseParam);
257  state->resetRequested = false;
258 
259  SCTPResetTimer *rt = new SCTPResetTimer();
260  rt->setInSN(0);
261  rt->setInAcked(true);
262  rt->setOutSN(srsn - 1);
263  rt->setOutAcked(false);
264 
265  SCTPMessage *msg = new SCTPMessage();
266  msg->setByteLength(SCTP_COMMON_HEADER);
267  msg->setSrcPort(localPort);
268  msg->setDestPort(remotePort);
269  msg->addChunk(resetChunk);
270  msg->addChunk(resetResponseChunk);
272  if (state->resetChunk != nullptr) {
273  delete state->resetChunk;
274  state->resetChunk = nullptr;
275  }
276  state->resetChunk = check_and_cast<SCTPStreamResetChunk *>(resetChunk->dup());
277  state->resetChunk->setName("State_Resetchunk");
278  if (qCounter.roomSumSendStreams != 0) {
279  storePacket(getPath(remoteAddr), msg, 1, 0, false);
280  state->bundleReset = true;
281  rt->setName("bundleReset");
282  sendOnPath(getPath(remoteAddr), true);
283  state->bundleReset = false;
284  } else {
285  sendToIP(msg, remoteAddr);
286  }
287  if (PK(getPath(remoteAddr)->ResetTimer)->hasEncapsulatedPacket()) {
288  PK(getPath(remoteAddr)->ResetTimer)->decapsulate();
289  }
290  PK(getPath(remoteAddr)->ResetTimer)->encapsulate(rt);
291  if (getPath(remoteAddr)->ResetTimer->isScheduled()) {
292  stopTimer(getPath(remoteAddr)->ResetTimer);
293  }
294  startTimer(getPath(remoteAddr)->ResetTimer, getPath(remoteAddr)->pathRto);
295  }
296 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
uint32 streamResetSequenceNumber
Definition: SCTPAssociation.h:793
bool resetRequested
Definition: SCTPAssociation.h:590
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
bool bundleReset
Definition: SCTPAssociation.h:788
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
uint16_t len
Definition: TCP_NSC.cc:85
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
uint16 localRequestType
Definition: SCTPAssociation.h:810
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
Definition: SCTPAssociation.h:159
void storePacket(SCTPPathVariables *pathVar, SCTPMessage *sctpMsg, const uint16 chunksAdded, const uint16 dataChunksAdded, const bool authAdded)
Definition: SCTPAssociationSendAll.cc:55
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
Definition: SCTPAssociation.h:150
uint16 remotePort
Definition: SCTPAssociation.h:914
#define SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH
Definition: SCTPAssociation.h:228
Definition: SCTPAssociation.h:156
Definition: SCTPAssociation.h:128
L3Address remoteAddr
Definition: SCTPAssociation.h:911
QueueCounter qCounter
Definition: SCTPAssociation.h:965
#define SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:225
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
IRoutingTable * rt
Definition: SCTPAssociation.h:936
uint16 numResetRequests
Definition: SCTPAssociation.h:644
uint32_t uint32
Definition: Compat.h:30
void resetSsn(uint16 id)
Definition: SCTPAssociationStreamReset.cc:884
std::list< uint16 > resetOutStreams
Definition: SCTPAssociation.h:801
#define PK(msg)
Definition: INETDefs.h:92
std::list< uint16 > streamsToReset
Definition: SCTPAssociation.h:804
uint32 nextTSN
Definition: SCTPAssociation.h:613
uint16_t uint16
Definition: Compat.h:32
Definition: SCTPAssociation.h:144
uint16 localPort
Definition: SCTPAssociation.h:913
void sendOnPath(SCTPPathVariables *pathId, const bool firstPass=true)
Utility: Send data from sendQueue.
Definition: SCTPAssociationSendAll.cc:668
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendCookieAck ( const L3Address dest)
protected

Referenced by processCookieEchoArrived(), and processPacketDropArrived().

1035 {
1036  SCTPAuthenticationChunk *authChunk;
1037  SCTPMessage *sctpcookieack = new SCTPMessage();
1038  sctpcookieack->setByteLength(SCTP_COMMON_HEADER);
1039 
1040  EV_INFO << "SCTPAssociationUtil:sendCookieACK\n";
1041 
1042  sctpcookieack->setSrcPort(localPort);
1043  sctpcookieack->setDestPort(remotePort);
1044  SCTPCookieAckChunk *cookieAckChunk = new SCTPCookieAckChunk("COOKIE_ACK");
1045  cookieAckChunk->setChunkType(COOKIE_ACK);
1046  cookieAckChunk->setByteLength(SCTP_COOKIE_ACK_LENGTH);
1048  authChunk = createAuthChunk();
1049  sctpcookieack->addChunk(authChunk);
1050  auto it = sctpMain->assocStatMap.find(assocId);
1051  it->second.numAuthChunksSent++;
1052  }
1053  sctpcookieack->addChunk(cookieAckChunk);
1054  sendToIP(sctpcookieack, dest);
1055 }
#define SCTP_COOKIE_ACK_LENGTH
Definition: SCTPAssociation.h:219
Definition: SCTPAssociation.h:122
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
bool auth
Definition: SCTPAssociation.h:822
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
AssocStatMap assocStatMap
Definition: SCTP.h:171
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
uint16 localPort
Definition: SCTPAssociation.h:913
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendCookieEcho ( SCTPInitAckChunk initackchunk)
protected

Referenced by processInitAckArrived().

907 {
908  SCTPAuthenticationChunk *authChunk;
909  SCTPMessage *sctpcookieecho = new SCTPMessage();
910  sctpcookieecho->setByteLength(SCTP_COMMON_HEADER);
911 
912  EV_INFO << "SCTPAssociationUtil:sendCookieEcho\n";
913 
914  sctpcookieecho->setSrcPort(localPort);
915  sctpcookieecho->setDestPort(remotePort);
916  SCTPCookieEchoChunk *cookieEchoChunk = new SCTPCookieEchoChunk("COOKIE_ECHO");
917  cookieEchoChunk->setChunkType(COOKIE_ECHO);
918  int32 len = initAckChunk->getCookieArraySize();
919  cookieEchoChunk->setCookieArraySize(len);
920  if (len > 0) {
921  for (int32 i = 0; i < len; i++)
922  cookieEchoChunk->setCookie(i, initAckChunk->getCookie(i));
923  cookieEchoChunk->setByteLength((SCTP_COOKIE_ACK_LENGTH + len));
924  }
925  else {
926  SCTPCookie *cookie = check_and_cast<SCTPCookie *>(initAckChunk->getStateCookie());
927  cookieEchoChunk->setStateCookie(cookie);
928  cookieEchoChunk->setByteLength(SCTP_COOKIE_ACK_LENGTH + cookie->getByteLength());
929  }
930  uint32 unknownLen = initAckChunk->getUnrecognizedParametersArraySize();
931  if (unknownLen > 0) {
932  EV_INFO << "Found unrecognized Parameters in INIT-ACK chunk with a length of " << unknownLen << " bytes.\n";
933  cookieEchoChunk->setUnrecognizedParametersArraySize(unknownLen);
934  for (uint32 i = 0; i < unknownLen; i++)
935  cookieEchoChunk->setUnrecognizedParameters(i, initAckChunk->getUnrecognizedParameters(i));
936  }
937  else
938  cookieEchoChunk->setUnrecognizedParametersArraySize(0);
939  state->cookieChunk = check_and_cast<SCTPCookieEchoChunk *>(cookieEchoChunk->dup());
940  if (len == 0) {
941  state->cookieChunk->setStateCookie(initAckChunk->getStateCookie()->dup());
942  }
943 
945  authChunk = createAuthChunk();
946  sctpcookieecho->addChunk(authChunk);
947  auto it = sctpMain->assocStatMap.find(assocId);
948  it->second.numAuthChunksSent++;
949  }
950 
951  sctpcookieecho->addChunk(cookieEchoChunk);
952  sendToIP(sctpcookieecho);
953 }
#define SCTP_COOKIE_ACK_LENGTH
Definition: SCTPAssociation.h:219
Definition: SCTPAssociation.h:121
uint16_t len
Definition: TCP_NSC.cc:85
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
bool auth
Definition: SCTPAssociation.h:822
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
AssocStatMap assocStatMap
Definition: SCTP.h:171
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
SCTPCookieEchoChunk * cookieChunk
pointer to the cookie chunk data structure (for retransmissions)
Definition: SCTPAssociation.h:654
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
uint16 localPort
Definition: SCTPAssociation.h:913
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendDataArrivedNotification ( uint16  sid)
protected

Referenced by processDataArrived(), processForwardTsnArrived(), and pushUlp().

1790 {
1791  EV_INFO << "SendDataArrivedNotification\n";
1792 
1793  cPacket *cmsg = new cPacket("SCTP_I_DATA_NOTIFICATION");
1794  cmsg->setKind(SCTP_I_DATA_NOTIFICATION);
1795  SCTPCommand *cmd = new SCTPCommand("notification");
1796  cmd->setAssocId(assocId);
1797  cmd->setSid(sid);
1798  cmd->setNumMsgs(1);
1799  cmsg->setControlInfo(cmd);
1800 
1801  sendToApp(cmsg);
1802 }
Definition: SCTPCommand.h:64
int32 assocId
Definition: SCTPAssociation.h:908
void sendToApp(cMessage *msg)
Utility: sends packet to application.
Definition: SCTPAssociationUtil.cc:457
void inet::sctp::SCTPAssociation::sendDoubleStreamResetResponse ( uint32  insrrsn,
uint16  inresult,
uint32  outsrrsn,
uint16  outresult 
)
protected

Referenced by processInAndOutResetRequestArrived().

806 {
807  SCTPStreamResetChunk *resetChunk;
808  EV_INFO << "sendDoubleStreamResetResponse to " << remoteAddr << "\n";
809  SCTPMessage *msg = new SCTPMessage();
810  msg->setByteLength(SCTP_COMMON_HEADER);
811  msg->setSrcPort(localPort);
812  msg->setDestPort(remotePort);
813  resetChunk = new SCTPStreamResetChunk("responseRE_CONFIG");
814  resetChunk->setChunkType(RE_CONFIG);
815  resetChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
816  SCTPStreamResetResponseParameter *outResponseParam = new SCTPStreamResetResponseParameter("Out_Response_Param");
817  outResponseParam->setParameterType(STREAM_RESET_RESPONSE_PARAMETER);
818  outResponseParam->setSrResSn(outsrrsn);
819  outResponseParam->setResult(outresult);
820  outResponseParam->setByteLength(SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH);
821  resetChunk->addParameter(outResponseParam);
822  SCTPStreamResetResponseParameter *inResponseParam = new SCTPStreamResetResponseParameter("In_Response_Param");
823  inResponseParam->setParameterType(STREAM_RESET_RESPONSE_PARAMETER);
824  inResponseParam->setSrResSn(insrrsn);
825  inResponseParam->setResult(inresult);
826  state->peerRequests[insrrsn].result = inresult;
827  state->peerRequests[outsrrsn].result = outresult;
828  inResponseParam->setByteLength(SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH);
829  resetChunk->addParameter(inResponseParam);
830  msg->addChunk(resetChunk);
831  if (qCounter.roomSumSendStreams != 0) {
832  storePacket(getPath(remoteAddr), msg, 1, 0, false);
833  state->bundleReset = true;
834  sendOnPath(getPath(remoteAddr), true);
835  state->bundleReset = false;
836  } else {
837  sendToIP(msg, remoteAddr);
838  }
839  if (outresult == PERFORMED || outresult == DENIED) {
840  state->resetRequested = false;
841  state->firstPeerRequest = false;
842  }
843 }
bool resetRequested
Definition: SCTPAssociation.h:590
bool bundleReset
Definition: SCTPAssociation.h:788
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
bool firstPeerRequest
Definition: SCTPAssociation.h:790
Definition: SCTPAssociation.h:159
void storePacket(SCTPPathVariables *pathVar, SCTPMessage *sctpMsg, const uint16 chunksAdded, const uint16 dataChunksAdded, const bool authAdded)
Definition: SCTPAssociationSendAll.cc:55
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
std::map< uint32, RequestData > peerRequests
Definition: SCTPAssociation.h:807
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
uint16 remotePort
Definition: SCTPAssociation.h:914
#define SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH
Definition: SCTPAssociation.h:228
Definition: SCTPAssociation.h:128
Definition: SCTPAssociation.h:145
L3Address remoteAddr
Definition: SCTPAssociation.h:911
QueueCounter qCounter
Definition: SCTPAssociation.h:965
Definition: SCTPAssociation.h:144
uint16 localPort
Definition: SCTPAssociation.h:913
void sendOnPath(SCTPPathVariables *pathId, const bool firstPass=true)
Utility: Send data from sendQueue.
Definition: SCTPAssociationSendAll.cc:668
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendEstabIndicationToApp ( )
protected

Utility: sends SCTP_I_ESTABLISHED indication with SCTPConnectInfo to application.

430 {
431  EV_INFO << "sendEstabIndicationToApp: localPort="
432  << localPort << " remotePort=" << remotePort << endl;
433 
434  cPacket *msg = new cPacket(indicationName(SCTP_I_ESTABLISHED));
435  msg->setKind(SCTP_I_ESTABLISHED);
436 
437  SCTPConnectInfo *establishIndication = new SCTPConnectInfo("ConnectInfo");
438  establishIndication->setAssocId(assocId);
439  establishIndication->setLocalAddr(localAddr);
440  establishIndication->setRemoteAddr(remoteAddr);
441  establishIndication->setLocalPort(localPort);
442  establishIndication->setRemotePort(remotePort);
443  establishIndication->setRemoteAddresses(remoteAddressList);
444  establishIndication->setInboundStreams(inboundStreams);
445  establishIndication->setOutboundStreams(outboundStreams);
446  establishIndication->setNumMsgs(state->sendQueueLimit);
447  msg->setControlInfo(establishIndication);
448  sctpMain->send(msg, "to_appl", appGateIndex);
449 
450  char vectorName[128];
451  for (uint16 i = 0; i < inboundStreams; i++) {
452  snprintf(vectorName, sizeof(vectorName), "Stream %d Throughput", i);
453  streamThroughputVectors[i] = new cOutVector(vectorName);
454  }
455 }
uint64 sendQueueLimit
Definition: SCTPAssociation.h:659
AddressVector remoteAddressList
Definition: SCTPAssociation.h:940
std::map< uint16, cOutVector * > streamThroughputVectors
Definition: SCTPAssociation.h:928
static const char * indicationName(const int32 code)
Utility: returns name of SCTP_I_xxx constants.
Definition: SCTPAssociationUtil.cc:206
uint32 outboundStreams
Definition: SCTPAssociation.h:943
uint32 inboundStreams
Definition: SCTPAssociation.h:942
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
Definition: SCTPCommand.h:65
L3Address remoteAddr
Definition: SCTPAssociation.h:911
L3Address localAddr
Definition: SCTPAssociation.h:912
int32 assocId
Definition: SCTPAssociation.h:908
int32 appGateIndex
Definition: SCTPAssociation.h:907
uint16_t uint16
Definition: Compat.h:32
uint16 localPort
Definition: SCTPAssociation.h:913
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendHeartbeat ( const SCTPPathVariables path)
protected

Referenced by pmStartPathManagement(), process_TIMEOUT_HEARTBEAT_INTERVAL(), processAsconfArrived(), and processPacketDropArrived().

978 {
979  SCTPAuthenticationChunk *authChunk;
980  SCTPMessage *sctpHeartbeatbeat = new SCTPMessage();
981  sctpHeartbeatbeat->setByteLength(SCTP_COMMON_HEADER);
982 
983  sctpHeartbeatbeat->setSrcPort(localPort);
984  sctpHeartbeatbeat->setDestPort(remotePort);
985  SCTPHeartbeatChunk *heartbeatChunk = new SCTPHeartbeatChunk("HEARTBEAT");
986  heartbeatChunk->setChunkType(HEARTBEAT);
987  heartbeatChunk->setRemoteAddr(path->remoteAddress);
988  heartbeatChunk->setTimeField(simTime());
989  heartbeatChunk->setByteLength(SCTP_HEARTBEAT_CHUNK_LENGTH + 12);
991  authChunk = createAuthChunk();
992  sctpHeartbeatbeat->addChunk(authChunk);
993  auto it = sctpMain->assocStatMap.find(assocId);
994  it->second.numAuthChunksSent++;
995  }
996  sctpHeartbeatbeat->addChunk(heartbeatChunk);
997  EV_INFO << "sendHeartbeat: sendToIP to " << path->remoteAddress << endl;
998  sendToIP(sctpHeartbeatbeat, path->remoteAddress);
999 }
#define SCTP_HEARTBEAT_CHUNK_LENGTH
Definition: SCTPAssociation.h:217
Definition: SCTPAssociation.h:115
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
bool auth
Definition: SCTPAssociation.h:822
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
AssocStatMap assocStatMap
Definition: SCTP.h:171
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
uint16 localPort
Definition: SCTPAssociation.h:913
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendHeartbeatAck ( const SCTPHeartbeatChunk heartbeatChunk,
const L3Address src,
const L3Address dest 
)
protected

Referenced by process_RCV_Message().

1004 {
1005  SCTPAuthenticationChunk *authChunk;
1006  SCTPMessage *sctpHeartbeatAck = new SCTPMessage();
1007  sctpHeartbeatAck->setByteLength(SCTP_COMMON_HEADER);
1008  sctpHeartbeatAck->setSrcPort(localPort);
1009  sctpHeartbeatAck->setDestPort(remotePort);
1010  SCTPHeartbeatAckChunk *heartbeatAckChunk = new SCTPHeartbeatAckChunk("HEARTBEAT_ACK");
1011  heartbeatAckChunk->setChunkType(HEARTBEAT_ACK);
1012  heartbeatAckChunk->setRemoteAddr(heartbeatChunk->getRemoteAddr());
1013  heartbeatAckChunk->setTimeField(heartbeatChunk->getTimeField());
1014  const int32 len = heartbeatChunk->getInfoArraySize();
1015  if (len > 0) {
1016  heartbeatAckChunk->setInfoArraySize(len);
1017  for (int32 i = 0; i < len; i++)
1018  heartbeatAckChunk->setInfo(i, heartbeatChunk->getInfo(i));
1019  }
1020 
1021  heartbeatAckChunk->setByteLength(heartbeatChunk->getByteLength());
1023  authChunk = createAuthChunk();
1024  sctpHeartbeatAck->addChunk(authChunk);
1025  auto it = sctpMain->assocStatMap.find(assocId);
1026  it->second.numAuthChunksSent++;
1027  }
1028  sctpHeartbeatAck->addChunk(heartbeatAckChunk);
1029 
1030  EV_INFO << "sendHeartbeatAck: sendToIP from " << src << " to " << dest << endl;
1031  sendToIP(sctpHeartbeatAck, dest);
1032 }
uint16_t len
Definition: TCP_NSC.cc:85
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
Definition: SCTPAssociation.h:116
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
bool auth
Definition: SCTPAssociation.h:822
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
AssocStatMap assocStatMap
Definition: SCTP.h:171
int32_t int32
Definition: Compat.h:31
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
uint16 localPort
Definition: SCTPAssociation.h:913
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendHMacError ( const uint16  id)
protected

Referenced by process_RCV_Message().

1833 {
1834  SCTPMessage *sctpmsg = new SCTPMessage();
1835  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
1836  SCTPErrorChunk *errorChunk = new SCTPErrorChunk("ErrorChunk");
1837  errorChunk->setChunkType(ERRORTYPE);
1838  SCTPSimpleErrorCauseParameter *cause = new SCTPSimpleErrorCauseParameter("Cause");
1839  cause->setParameterType(UNSUPPORTED_HMAC);
1840  cause->setByteLength(6);
1841  cause->setValue(id);
1842  errorChunk->setByteLength(4);
1843  errorChunk->addParameters(cause);
1844  sctpmsg->addChunk(errorChunk);
1845 }
Definition: SCTPAssociation.h:191
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
Definition: SCTPAssociation.h:120
void inet::sctp::SCTPAssociation::sendIndicationToApp ( const int32  code,
const int32  value = 0 
)
protected

Utility: sends status indication (SCTP_I_xxx) to application.

Referenced by chunkMustBeAbandoned(), peekAbandonedChunk(), process_RCV_Message(), process_SEND(), process_TIMEOUT_HEARTBEAT(), process_TIMEOUT_INIT_REXMIT(), process_TIMEOUT_RTX(), process_TIMEOUT_SHUTDOWN(), processAsconfAckArrived(), processAsconfArrived(), processOutAndResponseArrived(), processResetResponseArrived(), resetExpectedSsn(), resetExpectedSsns(), resetSsns(), sendOnPath(), signalConnectionTimeout(), and updateCounters().

412 {
413  EV_INFO << "sendIndicationToApp: " << indicationName(code) << endl;
414  assert(code != SCTP_I_SENDQUEUE_ABATED);
415 
416  cPacket *msg = new cPacket(indicationName(code));
417  msg->setKind(code);
418 
419  SCTPCommand *indication = new SCTPCommand(indicationName(code));
420  indication->setAssocId(assocId);
421  indication->setLocalAddr(localAddr);
422  indication->setLocalPort(localPort);
423  indication->setRemoteAddr(remoteAddr);
424  indication->setRemotePort(remotePort);
425  msg->setControlInfo(indication);
426  sctpMain->send(msg, "to_appl", appGateIndex);
427 }
Definition: SCTPCommand.h:77
static const char * indicationName(const int32 code)
Utility: returns name of SCTP_I_xxx constants.
Definition: SCTPAssociationUtil.cc:206
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
L3Address remoteAddr
Definition: SCTPAssociation.h:911
L3Address localAddr
Definition: SCTPAssociation.h:912
int32 assocId
Definition: SCTPAssociation.h:908
int32 appGateIndex
Definition: SCTPAssociation.h:907
uint16 localPort
Definition: SCTPAssociation.h:913
void inet::sctp::SCTPAssociation::sendInit ( )
protected

Methods for creating and sending chunks.

Referenced by process_ASSOCIATE().

509 {
510  AddressVector adv;
512 
513  if (remoteAddr.isUnspecified() || remotePort == 0)
514  throw cRuntimeError("Error processing command ASSOCIATE: foreign socket unspecified");
515 
516  if (localPort == 0)
517  throw cRuntimeError("Error processing command ASSOCIATE: local port unspecified");
518 
520  // create message consisting of INIT chunk
521  SCTPMessage *sctpmsg = new SCTPMessage();
522  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
523  SCTPInitChunk *initChunk = new SCTPInitChunk("INIT");
524  initChunk->setChunkType(INIT);
525  initChunk->setInitTag((uint32)(fmod(RNGCONTEXT intrand(INT32_MAX), 1.0 + (double)(unsigned)0xffffffffUL)) & 0xffffffffUL);
526 
527  peerVTag = initChunk->getInitTag();
528  EV_INFO << "INIT from " << localAddr << ":InitTag=" << peerVTag << "\n";
529  initChunk->setA_rwnd(sctpMain->par("arwnd"));
530  state->localRwnd = (long)sctpMain->par("arwnd");
531  initChunk->setNoOutStreams(outboundStreams);
533  initChunk->setNoInStreams(inboundStreams);
534  initChunk->setInitTSN(1000);
535  initChunk->setMsg_rwnd(sctpMain->par("messageAcceptLimit"));
536  state->nextTSN = initChunk->getInitTSN();
537  state->lastTSN = initChunk->getInitTSN() + state->numRequests - 1;
539  state->asconfSn = 1000;
540 
541  initTsn = initChunk->getInitTSN();
542 #ifdef WITH_IPv4
543  initChunk->setIpv4Supported(true);
544 #else
545  initChunk->setIpv4Supported(false);
546 #endif
547 #ifdef WITH_IPv6
548  initChunk->setIpv6Supported(true);
549 #else
550  initChunk->setIpv6Supported(false);
551 #endif
552  EV_INFO << "add local address\n";
553  if (localAddressList.front().isUnspecified()) {
554  for (int32 i = 0; i < ift->getNumInterfaces(); ++i) {
555 #ifdef WITH_IPv4
556  if (ift->getInterface(i)->ipv4Data() != nullptr) {
557  adv.push_back(ift->getInterface(i)->ipv4Data()->getIPAddress());
558  }
559  else
560 #endif // ifdef WITH_IPv4
561 #ifdef WITH_IPv6
562  if (ift->getInterface(i)->ipv6Data() != nullptr) {
563  for (int32 j = 0; j < ift->getInterface(i)->ipv6Data()->getNumAddresses(); j++) {
564  EV_DETAIL << "add address " << ift->getInterface(i)->ipv6Data()->getAddress(j) << "\n";
565  adv.push_back(ift->getInterface(i)->ipv6Data()->getAddress(j));
566  }
567  }
568  else
569 #endif // ifdef WITH_IPv6
570  ;
571  }
572  }
573  else {
574  adv = localAddressList;
575  EV_DETAIL << "gebundene Adresse " << localAddr << " wird hinzugefuegt\n"; // todo
576  }
577  if (initChunk->getIpv4Supported() || initChunk->getIpv6Supported()) {
578  length += 8;
579  }
580  uint32 addrNum = 0;
581  bool friendly = false;
582  if (sctpMain->hasPar("natFriendly")) {
583  friendly = sctpMain->par("natFriendly");
584  }
586  for (auto & elem : adv) {
587  if (!friendly) {
588  initChunk->setAddressesArraySize(addrNum + 1);
589  initChunk->setAddresses(addrNum++, (elem));
590  length += 20;
591  }
592  sctpMain->addLocalAddress(this, (elem));
593  state->localAddresses.push_back((elem));
594  if (localAddr.isUnspecified())
595  localAddr = (elem);
596  }
597  }
598  else if (remoteAddr.getType() == L3Address::IPv4) {
599  int rlevel = getAddressLevel(remoteAddr);
600  EV_DETAIL << "level of remote address=" << rlevel << "\n";
601  for (auto & elem : adv) {
602  int addressLevel = getAddressLevel(elem);
603  EV_DETAIL << "level of address " << (elem) << " = " << addressLevel << "\n";
604  if (addressLevel >= rlevel) {
605  initChunk->setAddressesArraySize(addrNum + 1);
606  initChunk->setAddresses(addrNum++, (elem));
607  length += 8;
608  sctpMain->addLocalAddress(this, (elem));
609  state->localAddresses.push_back((elem));
610  if (localAddr.toIPv4().getInt() == 0)
611  localAddr = (elem);
612  }
613  else if (rlevel == 4 && addressLevel == 3 && friendly) {
614  sctpMain->addLocalAddress(this, (elem));
615  state->localAddresses.push_back((elem));
616  if (localAddr.toIPv4().getInt() == 0)
617  localAddr = (elem);
618  }
619  }
620  }
621  else
622  throw cRuntimeError("Unknown address type: %d", (int)(remoteAddr.getType()));
623 
624  uint16 count = 0;
625  if (sctpMain->auth == true) {
626  initChunk->setSepChunksArraySize(++count);
627  initChunk->setSepChunks(count - 1, AUTH);
628  state->keyVector[0] = (uint8_t)RANDOM;
629  state->keyVector[2] = 36;
630  for (int32 k = 0; k < 32; k++) {
631  initChunk->setRandomArraySize(k + 1);
632  initChunk->setRandom(k, (uint8)(RNGCONTEXT intrand(256)));
633  state->keyVector[k + 2] = initChunk->getRandom(k);
634  }
635  state->sizeKeyVector = 36;
636  state->keyVector[state->sizeKeyVector] = (uint8_t)CHUNKS;
637  state->sizeKeyVector += 2;
639  state->sizeKeyVector += 2;
640  initChunk->setChunkTypesArraySize(state->chunkList.size());
641  int32 k = 0;
642  for (auto & elem : state->chunkList) {
643  initChunk->setChunkTypes(k, (elem));
644  state->keyVector[state->sizeKeyVector] = (elem);
645  state->sizeKeyVector++;
646  k++;
647  }
649  state->sizeKeyVector += 2;
650  state->keyVector[state->sizeKeyVector] = 1 + 4;
651  state->sizeKeyVector += 2;
653  state->sizeKeyVector++;
654  initChunk->setHmacTypesArraySize(1);
655  initChunk->setHmacTypes(0, 1);
656  length += initChunk->getChunkTypesArraySize() + 50;
657  }
658 
659  if (sctpMain->pktdrop) {
660  initChunk->setSepChunksArraySize(++count);
661  initChunk->setSepChunks(count - 1, PKTDROP);
662  }
663  if (state->streamReset == true) {
664  initChunk->setSepChunksArraySize(++count);
665  initChunk->setSepChunks(count - 1, RE_CONFIG);
666  }
667  if ((bool)sctpMain->par("addIP") == true) {
668  initChunk->setSepChunksArraySize(++count);
669  initChunk->setSepChunks(count - 1, ASCONF);
670  initChunk->setSepChunksArraySize(++count);
671  initChunk->setSepChunks(count - 1, ASCONF_ACK);
672  }
673  if (count > 0) {
675  }
676  if (state->prMethod != 0) {
677  initChunk->setForwardTsn(true);
678  length += 4;
679  }
680 
682  initChunk->setByteLength(length);
683  sctpmsg->addChunk(initChunk);
684  // set path variables
685  if (remoteAddressList.size() > 0) {
686  for (auto & elem : remoteAddressList) {
687  EV_DEBUG << " get new path for " << (elem) << " at line " << __LINE__ << "\n";
688  SCTPPathVariables *path = new SCTPPathVariables((elem), this, rt);
689  sctpPathMap[(elem)] = path;
690  qCounter.roomTransQ[(elem)] = 0;
691  qCounter.bookedTransQ[(elem)] = 0;
692  qCounter.roomRetransQ[(elem)] = 0;
693  }
694  }
695  else {
696  EV_DEBUG << " get new path for " << remoteAddr << " at line " << __LINE__ << "\n";
697  SCTPPathVariables *path = new SCTPPathVariables(remoteAddr, this, rt);
698  sctpPathMap[remoteAddr] = path;
702  }
703  // send it
704  state->initChunk = check_and_cast<SCTPInitChunk *>(initChunk->dup());
705  state->initChunk->setName("StateInitChunk");
707  EV_DEBUG << getFullPath() << " sendInit: localVTag=" << localVTag << " peerVTag=" << peerVTag << "\n";
708  sendToIP(sctpmsg);
709  sctpMain->assocList.push_back(this);
710 }
AddressType getType() const
Definition: L3Address.cc:52
uint32 initTsn
Definition: SCTPAssociation.h:947
uint8_t uint8
Definition: Compat.h:34
uint32 asconfSn
Definition: SCTPAssociation.h:778
IPv4InterfaceData * ipv4Data() const
Definition: InterfaceEntry.h:221
uint32 streamResetSequenceNumber
Definition: SCTPAssociation.h:793
uint32 localVTag
Definition: SCTPAssociation.h:915
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
uint32 lastTSN
Definition: SCTPAssociation.h:617
Definition: L3Address.h:47
AddressVector remoteAddressList
Definition: SCTPAssociation.h:940
Definition: SCTPAssociation.h:127
void printInfoAssocMap()
Definition: SCTP.cc:42
int count(const std::vector< T > &v, const T &a)
Definition: stlutils.h:58
AddressVector localAddressList
Definition: SCTPAssociation.h:939
IInterfaceTable * ift
Definition: SCTPAssociation.h:937
bool pktdrop
Definition: SCTP.h:212
uint64 localRwnd
Definition: SCTPAssociation.h:612
CounterMap roomRetransQ
Definition: SCTPAssociation.h:880
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
uint32 prMethod
Definition: SCTPAssociation.h:837
Definition: SCTPAssociation.h:183
#define RNGCONTEXT
Definition: INETDefs.h:85
Definition: SCTPAssociation.h:130
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
uint8 keyVector[512]
Definition: SCTPAssociation.h:825
uint32 outboundStreams
Definition: SCTPAssociation.h:943
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
uint32 inboundStreams
Definition: SCTPAssociation.h:942
uint16 remotePort
Definition: SCTPAssociation.h:914
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
SCTP * sctpMain
Definition: SCTPAssociation.h:962
Definition: SCTPAssociation.h:185
SCTPInitChunk * initChunk
pointer to the init chunk data structure (for retransmissions)
Definition: SCTPAssociation.h:652
std::vector< uint16 > chunkList
Definition: SCTPAssociation.h:823
const IPv6Address & getAddress(int i) const
Returns ith address of the interface.
Definition: IPv6InterfaceData.cc:290
void printSctpPathMap() const
Definition: SCTPAssociationUtil.cc:131
#define SCTP_INIT_CHUNK_LENGTH
Definition: SCTPAssociation.h:213
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
Definition: SCTPAssociation.h:124
std::vector< L3Address > AddressVector
Definition: SCTPAssociation.h:52
#define SCTP_SUPPORTED_EXTENSIONS_PARAMETER_LENGTH
Definition: SCTPAssociation.h:230
Definition: SCTPAssociation.h:128
uint32 peerVTag
Definition: SCTPAssociation.h:916
bool isUnspecified() const
Definition: L3Address.cc:133
L3Address remoteAddr
Definition: SCTPAssociation.h:911
CounterMap bookedTransQ
Definition: SCTPAssociation.h:879
Definition: SCTPAssociation.h:112
bool auth
Definition: SCTP.h:210
uint32 numRequests
Definition: SCTPAssociation.h:631
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
QueueCounter qCounter
Definition: SCTPAssociation.h:965
IRoutingTable * rt
Definition: SCTPAssociation.h:936
IPv4Address getIPAddress() const
Definition: IPv4InterfaceData.h:177
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
L3Address localAddr
Definition: SCTPAssociation.h:912
static int getAddressLevel(const L3Address &addr)
Utility: return IPv4 or IPv6 address level.
Definition: SCTPAssociationUtil.cc:2814
uint32 getInt() const
Returns the address as an int.
Definition: IPv4Address.h:197
uint32 initInboundStreams
Definition: SCTPAssociation.h:944
std::list< SCTPAssociation * > assocList
Definition: SCTP.h:180
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
uint32 nextTSN
Definition: SCTPAssociation.h:613
Definition: SCTPAssociation.h:126
uint16_t uint16
Definition: Compat.h:32
void setPrimaryPath(SCTPPathVariables *path)
Definition: SCTPAssociation.h:545
#define INT32_MAX
Definition: lexer.cc:75
IPv6InterfaceData * ipv6Data() const
Definition: InterfaceEntry.h:223
uint16 localPort
Definition: SCTPAssociation.h:913
void addLocalAddress(SCTPAssociation *assoc, L3Address address)
Definition: SCTP.cc:634
virtual InterfaceEntry * getInterface(int pos) const =0
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
const double k
Definition: QAM16Modulation.cc:24
Definition: SCTPAssociation.h:184
IPv4Address toIPv4() const
Definition: L3Address.h:76
uint32 sizeKeyVector
Definition: SCTPAssociation.h:826
Definition: L3Address.h:46
AddressVector localAddresses
Definition: SCTPAssociation.h:607
int getNumAddresses() const
Returns the number of addresses the interface has.
Definition: IPv6InterfaceData.h:482
bool streamReset
Definition: SCTPAssociation.h:785
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendInitAck ( SCTPInitChunk initchunk)
protected

Referenced by processInitArrived().

728 {
730 
732  // create segment
733  SCTPMessage *sctpinitack = new SCTPMessage();
734  sctpinitack->setByteLength(SCTP_COMMON_HEADER);
735 
736  sctpinitack->setSrcPort(localPort);
737  sctpinitack->setDestPort(remotePort);
738  EV_INFO << "sendInitAck at " << localAddr << ". Provided InitTag=" << initChunk->getInitTag() << "\n";
739  SCTPInitAckChunk *initAckChunk = new SCTPInitAckChunk("INIT_ACK");
740  initAckChunk->setChunkType(INIT_ACK);
741  SCTPCookie *cookie = new SCTPCookie("CookieUtil");
742  cookie->setCreationTime(simTime());
743  cookie->setLocalTieTagArraySize(32);
744  cookie->setPeerTieTagArraySize(32);
745  if (fsm->getState() == SCTP_S_CLOSED) {
746  while (peerVTag == 0) {
747  peerVTag = (uint32)RNGCONTEXT intrand(INT32_MAX);
748  }
749  initAckChunk->setInitTag(peerVTag);
750  initAckChunk->setInitTSN(2000);
751  state->nextTSN = initAckChunk->getInitTSN();
752  state->lastTSN = initAckChunk->getInitTSN() + state->numRequests - 1;
753  state->asconfSn = 2000;
755  cookie->setLocalTag(localVTag);
756  cookie->setPeerTag(peerVTag);
757  for (int32 i = 0; i < 32; i++) {
758  cookie->setLocalTieTag(i, 0);
759  cookie->setPeerTieTag(i, 0);
760  }
761  sctpinitack->setTag(localVTag);
762  EV_INFO << "state=closed: localVTag=" << localVTag << " peerVTag=" << peerVTag << "\n";
763  }
764  else if (fsm->getState() == SCTP_S_COOKIE_WAIT || fsm->getState() == SCTP_S_COOKIE_ECHOED) {
765  initAckChunk->setInitTag(peerVTag);
766  EV_INFO << "different state:set InitTag in InitAck: " << initAckChunk->getInitTag() << "\n";
767  initAckChunk->setInitTSN(state->nextTSN);
768  initPeerTsn = initChunk->getInitTSN();
770  cookie->setLocalTag(initChunk->getInitTag());
771  cookie->setPeerTag(peerVTag);
772  for (int32 i = 0; i < 32; i++) {
773  cookie->setPeerTieTag(i, (uint8)(RNGCONTEXT intrand(256)));
774  state->peerTieTag[i] = cookie->getPeerTieTag(i);
775  if (fsm->getState() == SCTP_S_COOKIE_ECHOED) {
776  cookie->setLocalTieTag(i, (uint8)(RNGCONTEXT intrand(256)));
777  state->localTieTag[i] = cookie->getLocalTieTag(i);
778  }
779  else
780  cookie->setLocalTieTag(i, 0);
781  }
782  sctpinitack->setTag(initChunk->getInitTag());
783  EV_DETAIL << "VTag in InitAck: " << sctpinitack->getTag() << "\n";
784  }
785  else {
786  EV_INFO << "other state\n";
787  uint32 tag = 0;
788  while (tag == 0) {
789  tag = (uint32)(fmod(RNGCONTEXT intrand(INT32_MAX), 1.0 + (double)(unsigned)0xffffffffUL)) & 0xffffffffUL;
790  }
791  initAckChunk->setInitTag(tag);
792  initAckChunk->setInitTSN(state->nextTSN);
793  cookie->setLocalTag(localVTag);
794  cookie->setPeerTag(peerVTag);
795  for (int32 i = 0; i < 32; i++) {
796  cookie->setPeerTieTag(i, state->peerTieTag[i]);
797  cookie->setLocalTieTag(i, state->localTieTag[i]);
798  }
799  sctpinitack->setTag(initChunk->getInitTag());
800  }
801  cookie->setByteLength(SCTP_COOKIE_LENGTH + 4);
802  initAckChunk->setStateCookie(cookie);
803  initAckChunk->setCookieArraySize(0);
804  initAckChunk->setA_rwnd(sctpMain->par("arwnd"));
805  state->localRwnd = (long)sctpMain->par("arwnd");
806  initAckChunk->setMsg_rwnd(sctpMain->par("messageAcceptLimit"));
807  initAckChunk->setNoOutStreams((unsigned int)min(outboundStreams, initChunk->getNoInStreams()));
808  initAckChunk->setNoInStreams((unsigned int)min(inboundStreams, initChunk->getNoOutStreams()));
809  initTsn = initAckChunk->getInitTSN();
810 #ifdef WITH_IPv4
811  initAckChunk->setIpv4Supported(true);
812 #else
813  initAckChunk->setIpv4Supported(false);
814 #endif
815 #ifdef WITH_IPv6
816  initAckChunk->setIpv6Supported(true);
817 #else
818  initAckChunk->setIpv6Supported(false);
819 #endif
820  if (initAckChunk->getIpv4Supported() || initAckChunk->getIpv6Supported()) {
821  length += 8;
822  }
823  uint32 addrNum = 0;
824  bool friendly = false;
825  if (sctpMain->hasPar("natFriendly")) {
826  friendly = sctpMain->par("natFriendly");
827  }
828  if (!friendly)
829  for (auto & elem : state->localAddresses) {
830  initAckChunk->setAddressesArraySize(addrNum + 1);
831  initAckChunk->setAddresses(addrNum++, (elem));
832  if ((elem).getType() == L3Address::IPv4) {
833  length += 8;
834  } else if ((elem).getType() == L3Address::IPv6) {
835  length += 20;
836  }
837  }
838 
839  uint16 count = 0;
840  if (sctpMain->auth == true) {
841  initAckChunk->setSepChunksArraySize(++count);
842  initAckChunk->setSepChunks(count - 1, AUTH);
843  for (int32 k = 0; k < 32; k++) {
844  initAckChunk->setRandomArraySize(k + 1);
845  initAckChunk->setRandom(k, (uint8)(RNGCONTEXT intrand(256)));
846  }
847  initAckChunk->setChunkTypesArraySize(state->chunkList.size());
848  int32 k = 0;
849  for (auto & elem : state->chunkList) {
850  initAckChunk->setChunkTypes(k, (elem));
851  k++;
852  }
853  initAckChunk->setHmacTypesArraySize(1);
854  initAckChunk->setHmacTypes(0, 1);
855  length += initAckChunk->getChunkTypesArraySize() + 48;
856  }
857  uint32 unknownLen = initChunk->getUnrecognizedParametersArraySize();
858  if (unknownLen > 0) {
859  EV_INFO << "Found unrecognized Parameters in INIT chunk with a length of " << unknownLen << " bytes.\n";
860  initAckChunk->setUnrecognizedParametersArraySize(unknownLen);
861  for (uint32 i = 0; i < unknownLen; i++)
862  initAckChunk->setUnrecognizedParameters(i, initChunk->getUnrecognizedParameters(i));
863  length += unknownLen;
864  }
865  else
866  initAckChunk->setUnrecognizedParametersArraySize(0);
867 
868  if (sctpMain->pktdrop) {
869  initAckChunk->setSepChunksArraySize(++count);
870  initAckChunk->setSepChunks(count - 1, PKTDROP);
871  }
872 
873  if (state->streamReset == true) {
874  initAckChunk->setSepChunksArraySize(++count);
875  initAckChunk->setSepChunks(count - 1, RE_CONFIG);
876  }
877  if ((bool)sctpMain->par("addIP") == true) {
878  initAckChunk->setSepChunksArraySize(++count);
879  initAckChunk->setSepChunks(count - 1, ASCONF);
880  initAckChunk->setSepChunksArraySize(++count);
881  initAckChunk->setSepChunks(count - 1, ASCONF_ACK);
882  }
883  if (count > 0) {
885  }
886  if (state->prMethod != 0) {
887  initAckChunk->setForwardTsn(true);
888  length += 4;
889  }
890 
891  initAckChunk->setByteLength(length + initAckChunk->getCookieArraySize() + cookie->getByteLength());
892  inboundStreams = ((initChunk->getNoOutStreams() < initAckChunk->getNoInStreams()) ? initChunk->getNoOutStreams() : initAckChunk->getNoInStreams());
893  outboundStreams = ((initChunk->getNoInStreams() < initAckChunk->getNoOutStreams()) ? initChunk->getNoInStreams() : initAckChunk->getNoOutStreams());
895  sctpinitack->addChunk(initAckChunk);
896  if (fsm->getState() == SCTP_S_CLOSED) {
897  sendToIP(sctpinitack, state->initialPrimaryPath);
898  }
899  else {
900  sendToIP(sctpinitack);
901  }
902  sctpMain->assocList.push_back(this);
904 }
uint32 initTsn
Definition: SCTPAssociation.h:947
uint8_t uint8
Definition: Compat.h:34
uint32 asconfSn
Definition: SCTPAssociation.h:778
uint32 streamResetSequenceNumber
Definition: SCTPAssociation.h:793
uint32 localVTag
Definition: SCTPAssociation.h:915
uint32 lastTSN
Definition: SCTPAssociation.h:617
Definition: L3Address.h:47
void forwardCumAckTSN(const uint32 cumAckTSN)
Definition: SCTPGapList.cc:339
Definition: SCTPAssociation.h:127
int count(const std::vector< T > &v, const T &a)
Definition: stlutils.h:58
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
void(SCTPAssociation::* ssInitStreams)(uint32 inStreams, uint32 outStreams)
Definition: SCTPAssociation.h:1288
bool pktdrop
Definition: SCTP.h:212
uint64 localRwnd
Definition: SCTPAssociation.h:612
Definition: SCTPAssociation.h:58
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
uint32 prMethod
Definition: SCTPAssociation.h:837
uint32 initPeerTsn
Definition: SCTPAssociation.h:948
#define RNGCONTEXT
Definition: INETDefs.h:85
Definition: SCTPAssociation.h:130
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
uint32 outboundStreams
Definition: SCTPAssociation.h:943
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
uint32 inboundStreams
Definition: SCTPAssociation.h:942
uint16 remotePort
Definition: SCTPAssociation.h:914
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
SCTP * sctpMain
Definition: SCTPAssociation.h:962
uint8 peerTieTag[32]
Definition: SCTPAssociation.h:637
std::vector< uint16 > chunkList
Definition: SCTPAssociation.h:823
void printSctpPathMap() const
Definition: SCTPAssociationUtil.cc:131
#define SCTP_INIT_CHUNK_LENGTH
Definition: SCTPAssociation.h:213
Definition: SCTPAssociation.h:124
#define SCTP_SUPPORTED_EXTENSIONS_PARAMETER_LENGTH
Definition: SCTPAssociation.h:230
Definition: SCTPAssociation.h:128
uint32 peerVTag
Definition: SCTPAssociation.h:916
SCTPGapList gapList
Definition: SCTPAssociation.h:619
L3Address remoteAddr
Definition: SCTPAssociation.h:911
bool auth
Definition: SCTP.h:210
uint32 numRequests
Definition: SCTPAssociation.h:631
L3Address initialPrimaryPath
Definition: SCTPAssociation.h:604
#define SCTP_COOKIE_LENGTH
Definition: SCTPAssociation.h:241
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
Definition: SCTPAssociation.h:59
uint8 localTieTag[32]
Definition: SCTPAssociation.h:636
L3Address localAddr
Definition: SCTPAssociation.h:912
std::list< SCTPAssociation * > assocList
Definition: SCTP.h:180
uint32 nextTSN
Definition: SCTPAssociation.h:613
Definition: SCTPAssociation.h:126
uint16_t uint16
Definition: Compat.h:32
void setPrimaryPath(SCTPPathVariables *path)
Definition: SCTPAssociation.h:545
#define INT32_MAX
Definition: lexer.cc:75
cFSM * fsm
Definition: SCTPAssociation.h:963
Definition: SCTPAssociation.h:57
SSFunctions ssFunctions
Definition: SCTPAssociation.h:1294
uint16 localPort
Definition: SCTPAssociation.h:913
Definition: SCTPAssociation.h:113
const double k
Definition: QAM16Modulation.cc:24
Definition: L3Address.h:46
AddressVector localAddresses
Definition: SCTPAssociation.h:607
bool streamReset
Definition: SCTPAssociation.h:785
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendInvalidStreamError ( uint16  sid)
protected

Referenced by processDataArrived().

1805 {
1806  SCTPMessage *sctpmsg = new SCTPMessage();
1807  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
1808  SCTPErrorChunk *errorChunk = new SCTPErrorChunk("ErrorChunk");
1809  errorChunk->setChunkType(ERRORTYPE);
1810  SCTPSimpleErrorCauseParameter *cause = new SCTPSimpleErrorCauseParameter("Cause");
1811  cause->setParameterType(INVALID_STREAM_IDENTIFIER);
1812  cause->setByteLength(8);
1813  cause->setValue(sid);
1814  errorChunk->setByteLength(4);
1815  errorChunk->addParameters(cause);
1816  sctpmsg->addChunk(errorChunk);
1817 
1819  state->ackState = 0;
1820  SCTPSackChunk *sackChunk = createSack();
1821 
1822  if (state->auth && state->peerAuth && typeInChunkList(SACK)) {
1823  SCTPAuthenticationChunk *authChunk = createAuthChunk();
1824  sctpmsg->addChunk(authChunk);
1825  auto it = sctpMain->assocStatMap.find(assocId);
1826  it->second.numAuthChunksSent++;
1827  }
1828  sctpmsg->addChunk(sackChunk);
1829  sendSACKviaSelectedPath(sctpmsg);
1830 }
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
Definition: SCTPAssociation.h:189
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
cMessage * SackTimer
Definition: SCTPAssociation.h:922
bool auth
Definition: SCTPAssociation.h:822
SCTP * sctpMain
Definition: SCTPAssociation.h:962
uint32 ackState
Definition: SCTPAssociation.h:618
AssocStatMap assocStatMap
Definition: SCTP.h:171
void sendSACKviaSelectedPath(SCTPMessage *sctpMsg)
Definition: SCTPAssociationSendAll.cc:507
Definition: SCTPAssociation.h:114
Definition: SCTPAssociation.h:120
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
SCTPSackChunk * createSack()
Definition: SCTPAssociationUtil.cc:1473
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendOnAllPaths ( SCTPPathVariables firstPath)

Referenced by process_ABORT(), process_CLOSE(), process_RCV_Message(), process_TIMEOUT_BLOCKING(), process_TIMEOUT_RTX(), inet::sctp::SCTPAlg::sendCommandInvoked(), and sendShutdownAck().

276 {
277  if (state->allowCMT) {
278  // ------ Send on provided path first ... -----------------------------
279  if (firstPath != nullptr) {
280  sendOnPath(firstPath);
281  }
282 
283  // ------ ... then, try sending on all other paths --------------------
284  std::vector<SCTPPathVariables *> sortedPaths = getSortedPathMap();
285  for (auto path : sortedPaths) {
286  EV << path->remoteAddress << " [" << path->lastTransmission << "]\t";
287  }
288  EV << endl;
289 
290  for (auto path : sortedPaths)
291  {
292  if (path != firstPath) {
293  sendOnPath(path);
294  path->sendAllRandomizer = RNGCONTEXT uniform(0, (1 << 31));
295  }
296  }
297  if ((state->strictCwndBooking) &&
298  (sctpPathMap.size() > 1)) // T.D. 08.02.2010: strict behaviour only for more than 1 paths!
299  { // T.D. 14.01.2010: Second pass for "Strict Cwnd Booking" option.
300  for (auto path : sortedPaths)
301  {
302  sendOnPath(path, false);
303  }
304  }
305  }
306  else {
307  // ------ Send on provided path first ... -----------------------------
308  if (firstPath != nullptr) {
309  sendOnPath(firstPath);
310  }
311 
312  // ------ ... then, try sending on all other paths --------------------
313  for (auto & elem : sctpPathMap) {
314  SCTPPathVariables *path = elem.second;
315  if (path != firstPath) {
316  sendOnPath(path);
317  }
318  }
319  if (state->strictCwndBooking) {
320  // T.D. 14.01.2010: Second pass for "Strict Cwnd Booking" option.
321  sendOnPath(firstPath, false);
322 
323  // ------ Then, try sending on all other paths ---------------------------
324  for (auto & elem : sctpPathMap) {
325  SCTPPathVariables *path = elem.second;
326  if (path != firstPath) {
327  sendOnPath(path, false);
328  }
329  }
330  }
331  }
334  state->resetPending = true;
335  }
336 }
bool resetRequested
Definition: SCTPAssociation.h:590
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
void sendStreamResetRequest(SCTPResetInfo *info)
Definition: SCTPAssociationStreamReset.cc:483
bool allowCMT
Definition: SCTPAssociation.h:705
SCTPResetInfo * resetInfo
Definition: SCTPAssociation.h:808
uint16 localRequestType
Definition: SCTPAssociation.h:810
#define RNGCONTEXT
Definition: INETDefs.h:85
std::vector< SCTPPathVariables * > getSortedPathMap()
Definition: SCTPAssociationSendAll.cc:128
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
bool strictCwndBooking
Definition: SCTPAssociation.h:745
uint64 outstandingBytes
Definition: SCTPAssociation.h:622
QueueCounter qCounter
Definition: SCTPAssociation.h:965
Definition: SCTPAssociation.h:153
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
bool resetPending
Definition: SCTPAssociation.h:589
void sendOnPath(SCTPPathVariables *pathId, const bool firstPass=true)
Utility: Send data from sendQueue.
Definition: SCTPAssociationSendAll.cc:668
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendOnPath ( SCTPPathVariables pathId,
const bool  firstPass = true 
)

Utility: Send data from sendQueue.

Referenced by sendBundledOutgoingResetAndResponse(), inet::sctp::SCTPAlg::sendCommandInvoked(), sendDoubleStreamResetResponse(), sendOnAllPaths(), sendOutgoingResetRequest(), sendStreamResetRequest(), and sendStreamResetResponse().

669 {
670  // ====== Variables ======================================================
671  SCTPPathVariables *path = nullptr; // Path to send next message to
672  SCTPMessage *sctpMsg = nullptr;
673  SCTPSackChunk *sackChunk = nullptr;
674  SCTPDataChunk *dataChunkPtr = nullptr;
675  SCTPForwardTsnChunk *forwardChunk = nullptr;
676 
677  uint16 chunksAdded = 0;
678  uint16 dataChunksAdded = 0;
679  uint32 totalChunksSent = 0;
680  uint32 totalPacketsSent = 0;
681  uint32 outstandingBytes = 0;
682 
683  uint32 tcount = 0; // Bytes in transmission queue on the selected path
684  uint32 Tcount = 0; // Bytes in transmission queue on all paths
685  uint32 scount = 0; // Bytes in send streams
686  int32 bytesToSend = 0;
687 
688  bool headerCreated = false;
689  bool sendOneMorePacket = false;
690  bool sendingAllowed = true;
691  bool authAdded = false;
692  bool sackAdded = false;
693  bool forwardPresent = false;
694 
695  // ====== Perform Chunk Rescheduling =====================================
696  if ((state->allowCMT) &&
698  {
699  chunkReschedulingControl((pathId == nullptr) ? state->getPrimaryPath() : pathId);
700  }
701 
702  // ====== Obtain path ====================================================
703  EV_INFO << endl << "##### sendAll(";
704  if (pathId) {
705  EV_INFO << pathId->remoteAddress;
706  }
707  EV_INFO << ") at t=" << simTime() << " #####" << endl;
708 
709  unsigned int safetyCounter = 0;
710  while (sendingAllowed && (!state->resetPending || state->waitForResponse)) {
711  if (safetyCounter++ >= 1000) {
712  throw cRuntimeError("Endless loop in SCTPAssociation::sendOnPath()?! This should not happen ...");
713  }
714 
715  headerCreated = false;
716  if (state->bytesToRetransmit > 0) {
717  // There are bytes in the transmissionQ. They have to be sent first.
719  assert(path != nullptr);
720  }
721  else {
722  if (pathId == nullptr) { // No path given => use primary path.
723  path = state->getPrimaryPath();
724  }
725  else {
726  path = pathId;
727  }
728  }
731  {
732  if (state->lastTransmission < simTime()) {
734  }
735  if (path->lastTransmission < simTime()) {
736  // T.D. 18.07.2011: Only reset packetsInBurst once per time-stamp!
737  path->packetsInBurst = 0;
738  }
739  }
740  // packetsInBurst must be checked here!
741  // sendOnPath() may be called multiple times at the same simTime!
745  (path->packetsInBurst >= state->maxBurst))
746  {
747  break;
748  }
749  // TotalMaxBurst variant: limit bursts on all paths.
752  {
753  break;
754  }
755  outstandingBytes = path->outstandingBytes;
756  assert((int32)outstandingBytes >= 0);
757  auto tq = qCounter.roomTransQ.find(path->remoteAddress);
758  tcount = tq->second;
759  Tcount = getAllTransQ();
760  scount = qCounter.roomSumSendStreams; // includes header and padding
761  EV_INFO << "\nsendAll: on " << path->remoteAddress << ":"
762  << " tcount=" << tcount
763  << " Tcount=" << Tcount
764  << " scount=" << scount
765  << " nextTSN=" << state->nextTSN << endl;
766 
767  bool sackOnly;
768  bool sackWithData;
769  timeForSack(sackOnly, sackWithData);
770  if ((tcount == 0 && scount == 0) || (!state->allowCMT && tcount == 0 && Tcount > 0)) {
771  // ====== No DATA chunks to send ===================================
772  EV_DETAIL << "No DATA chunk available!" << endl;
773  if (!sackOnly) { // SACK?, no data to send
774  EV_DETAIL << "No SACK to send either" << endl;
775  if (state->sctpMsg) {
776  EV_DETAIL << "packet was stored -> load packet" << endl;
777  loadPacket(path, &sctpMsg, &chunksAdded, &dataChunksAdded, &authAdded);
778  sendToIP(sctpMsg, path->remoteAddress);
779  }
780  return;
781  }
782  else {
783  bytes.bytesToSend = 0;
784  }
785  }
786  else {
787  bytesAllowedToSend(path, firstPass);
788  }
789  bytesToSend = bytes.bytesToSend;
790 
791  // As there is at least a SACK to be sent, a header can be created
792 
793  if (state->sctpMsg) {
794  EV_DETAIL << "packet was stored -> load packet" << endl;
795  loadPacket(path, &sctpMsg, &chunksAdded, &dataChunksAdded, &authAdded);
796  headerCreated = true;
797  }
798  else if (bytesToSend > 0 || bytes.chunk || bytes.packet || sackWithData || sackOnly || forwardPresent) {
799  sctpMsg = new SCTPMessage("send");
800  sctpMsg->setByteLength(SCTP_COMMON_HEADER);
801  headerCreated = true;
802  chunksAdded = 0;
803  }
804 
805  if (!sackAdded && (sackWithData || sackOnly)) {
806  // SACK can be sent
807  assert(headerCreated == true);
808  sackChunk = createSack();
809  // CMT DAC
810  if ((state->allowCMT == true) && (state->cmtUseDAC == true)) {
811  EV << "Adding dacPacketsRcvd=" << (unsigned int)dacPacketsRcvd << " to SACK" << endl;
812  sackChunk->setDacPacketsRcvd(dacPacketsRcvd);
813  }
814  dacPacketsRcvd = 0;
815 
816  chunksAdded++;
817  totalChunksSent++;
818  // ------ Create AUTH chunk, if necessary --------------------------
819  authAdded = addAuthChunkIfNecessary(sctpMsg, SACK, authAdded);
820 
821  // ------ Add SACK chunk -------------------------------------------
822  sctpMsg->addChunk(sackChunk);
823  sackAdded = true;
824  EV_DETAIL << assocId << ": SACK added, chunksAdded now " << chunksAdded << " sackOnly=" << sackOnly << " sackWithData=" << sackWithData << "\n";
825  if (sackOnly && !(bytesToSend > 0 || bytes.chunk || bytes.packet)) {
826  // There is no data to be sent, just the SACK
827  path->lastTransmission = simTime();
828  path->packetsInBurst++;
829  state->lastTransmission = simTime();
831  state->ackState = 0;
832  // Stop SACK timer if it is running...
835  state->sackAllowed = false;
836  sendSACKviaSelectedPath(sctpMsg);
837  sctpMsg = nullptr;
838  return;
839  }
840  }
841  // ====== FORWARD_TSN =================================================
842  if (!forwardPresent && !state->stopSending) {
843  if (peekAbandonedChunk(path) != nullptr) {
844  forwardChunk = createForwardTsnChunk(path->remoteAddress);
845  chunksAdded++;
846  totalChunksSent++;
847  state->ackPointAdvanced = false;
848  if (!headerCreated) {
849  sctpMsg = new SCTPMessage("send");
850  sctpMsg->setByteLength(SCTP_COMMON_HEADER);
851  headerCreated = true;
852  chunksAdded = 0;
853  }
854  // ------ Create AUTH chunk, if necessary -----------------------
855  authAdded = addAuthChunkIfNecessary(sctpMsg, FORWARD_TSN, authAdded);
856  sctpMsg->addChunk(forwardChunk);
857  forwardPresent = true;
858  if (!path->T3_RtxTimer->isScheduled()) {
859  // Start retransmission timer, if not scheduled before
860  startTimer(path->T3_RtxTimer, path->pathRto);
861  }
862  if (bytesToSend == 0) {
863  sendToIP(sctpMsg, path->remoteAddress);
864  forwardPresent = false;
865  headerCreated = false;
866  chunksAdded = 0;
867  sctpMsg = nullptr;
868  }
869  }
870  }
871 
872  // ####################################################################
873  // #### Data Transmission ####
874  // ####################################################################
875 
876  bool packetFull = false;
877 
878  while (!packetFull && headerCreated) {
879  assert(headerCreated == true);
880  EV_DETAIL << assocId << ": bytesToSend=" << bytesToSend
881  << " bytes.chunk=" << bytes.chunk
882  << " bytes.packet=" << bytes.packet << endl;
883 
884  // ====== How many bytes may be transmitted in next packet? ========
885  int32 allowance = path->pmtu; // Default behaviour: send 1 path MTU
886  // Restrict amount of data to send to cwnd size.
887  if ((state->strictCwndBooking) &&
888  (sctpPathMap.size() > 1)) // strict behaviour only for more than 1 paths!
889  { // T.D. 19.01.2010: bytesToSend may be less than 1 MTU on this path.
890  // Allow overbooking in second pass, if *total* cwnd allows it.
891  if (!firstPass) {
892  // No "one packet"/"one chunk" in second pass!
893  bytes.packet = false;
894  bytes.chunk = false;
895  }
896 
897  if (bytes.chunk) {
898  // Send 1 chunk: allow one path MTU.
899  }
900  else if (bytes.packet) {
901  // Send 1 chunk: allow one path MTU.
902  }
903  else if ((path->outstandingBytes == 0) && (firstPass)) {
904  // No outstanding data and first pass: allow one path MTU.
905  }
906  else { // There *may* be something more to send ...
907  if ((int32)path->cwnd - (int32)path->outstandingBytes >= (int32)path->pmtu) {
908  // Enough space -> allow one path MTU
909  }
910  else {
911  if (firstPass) {
912  // In first pass, disallow overbooking.
913  allowance = 0;
914  bytesToSend = 0;
915  }
916  else {
917  if (!state->allowCMT) {
918  // For non-CMT in second pass, allow 1 more MTU.
919  }
920  else {
921  // Not CMT in second pass, check total space ...
922  int32 totalOutstanding = 0;
923  int32 totalCwnd = 0;
924  for (SCTPPathMap::const_iterator pathMapIterator = sctpPathMap.begin();
925  pathMapIterator != sctpPathMap.end(); pathMapIterator++)
926  {
927  const SCTPPathVariables *myPath = pathMapIterator->second;
928  totalOutstanding += myPath->outstandingBytes;
929  totalCwnd += myPath->cwnd;
930  }
931  if ((int32)(totalCwnd - totalOutstanding) < (int32)(path->pmtu)) {
932  // ... and disallow overbooking if there is no more space for 1 MTU
933  allowance = 0;
934  bytesToSend = 0;
935  }
936  else {
937  // ... and allow 1 MTU if there is still space
938  }
939  }
940  }
941  }
942  }
943  }
944  else {
945  if ((bytesToSend > 0) || (bytes.chunk) || (bytes.packet)) {
946  // Allow 1 more MTU
947  }
948  else {
949  // No more sending allowed.
950  allowance = 0;
951  bytesToSend = 0;
952  }
953  }
954  if ((allowance > 0) || (bytes.chunk) || (bytes.packet)) {
955  bool firstTime = false; // Is DATA chunk send for the first time?
956  SCTPDataVariables *datVar = nullptr;
957  // ------ Create AUTH chunk, if necessary -----------------------
958  authAdded = addAuthChunkIfNecessary(sctpMsg, DATA, authAdded);
959  if (tcount > 0) {
960  // ====== Retransmission ========================================
961  // If bytes.packet is true, one packet is allowed to be retransmitted!
962  datVar = getOutboundDataChunk(path,
963  path->pmtu - sctpMsg->getByteLength() - 20,
964  (bytes.packet == true) ? path->pmtu : allowance);
965  if (datVar == nullptr) {
966  if (chunksAdded == 1 && sackAdded) {
967  datVar = getOutboundDataChunk(path,
968  path->pmtu - sctpMsg->getByteLength() + sackChunk->getByteLength() - 20,
969  (bytes.packet == true) ? path->pmtu : allowance);
970  if (!sackOnly) {
971  sctpMsg->removeChunk();
972  EV_DETAIL << "RTX: Remove SACK chunk\n";
973  delete sackChunk;
974  chunksAdded--;
975  sackAdded = false;
976  }
977  else {
978  path->lastTransmission = simTime();
979  path->packetsInBurst++;
980  state->lastTransmission = simTime();
982  if (dataChunksAdded > 0) {
983  state->ssNextStream = true;
984  }
985  state->ackState = 0;
986  // Stop SACK timer if it is running...
989  state->sackAllowed = false;
990  EV_DETAIL << "RTX: send only SACK\n";
991  sendSACKviaSelectedPath(sctpMsg);
992  sctpMsg = nullptr;
993 
994  // TD 17.02.2015: There is data to send (on current path) -> create new message structure!
995  sctpMsg = new SCTPMessage("send");
996  sctpMsg->setByteLength(SCTP_COMMON_HEADER);
997  headerCreated = true;
998  sackAdded = false;
999  chunksAdded = 0;
1000  }
1001  }
1002  }
1003 
1004  // Check for FORWARD-TSN again, might just have been triggered...
1005  if (datVar == nullptr && !forwardPresent && !state->stopSending) {
1006  if (peekAbandonedChunk(path) != nullptr) {
1007  forwardChunk = createForwardTsnChunk(path->remoteAddress);
1008  chunksAdded++;
1009  totalChunksSent++;
1010  state->ackPointAdvanced = false;
1011  // ------ Create AUTH chunk, if necessary -----------------------
1012  authAdded = addAuthChunkIfNecessary(sctpMsg, FORWARD_TSN, authAdded);
1013  sctpMsg->addChunk(forwardChunk);
1014  forwardPresent = true;
1015  if (!path->T3_RtxTimer->isScheduled()) {
1016  // Start retransmission timer, if not scheduled before
1017  startTimer(path->T3_RtxTimer, path->pathRto);
1018  }
1019  }
1020  }
1021 
1022  if (datVar != nullptr) {
1023  assert(datVar->getNextDestinationPath() == path);
1024  datVar->numberOfRetransmissions++;
1025  if (chunkHasBeenAcked(datVar) == false) {
1026  EV_DETAIL << simTime() << ": Retransmission #" << datVar->numberOfRetransmissions
1027  << " of TSN " << datVar->tsn
1028  << " on path " << datVar->getNextDestination()
1029  << " (last was " << datVar->getLastDestination() << ")" << endl;
1030  // The chunk is going to be retransmitted on another path.
1031  // On the original path, it is necessary to find another
1032  // PseudoCumAck!
1033  if (datVar->getLastDestinationPath() != datVar->getNextDestinationPath()) {
1034  SCTPPathVariables *oldPath = datVar->getLastDestinationPath();
1035  oldPath->findPseudoCumAck = true;
1036  oldPath->findRTXPseudoCumAck = true;
1037  SCTPPathVariables *newPath = datVar->getNextDestinationPath();
1038  newPath->findPseudoCumAck = true;
1039  newPath->findRTXPseudoCumAck = true;
1040  }
1041  datVar->wasDropped = false;
1042  datVar->countsAsOutstanding = true;
1043  datVar->hasBeenReneged = false;
1044  increaseOutstandingBytes(datVar, path); // NOTE: path == datVar->getNextDestinationPath()
1045  }
1046  }
1047  }
1048  // ====== First Transmission ====================================
1049  else if (((scount > 0) && (!state->nagleEnabled)) || // Data to send and Nagle off
1050  ((uint32)scount >= path->pmtu - 32 - 20) || // Data to fill at least one path MTU
1051  ((scount > 0) && (state->nagleEnabled) && ((outstandingBytes == 0) || (sackOnly && sackAdded))) || // Data to send, Nagle on and no outstanding bytes
1052  state->bundleReset)
1053  { // ====== Buffer Splitting ===================================
1054  bool rejected = false;
1055  const uint32 bytesOnPath = (state->cmtBufferSplittingUsesOSB == true) ?
1056  path->outstandingBytes : path->queuedBytes;
1057  if (state->allowCMT) {
1058  // ------ Sender Side -------------------------------------
1061  {
1062  // Limit is 1/n of current sender-side buffer allocation
1063  const uint32 limit = ((state->sendQueueLimit != 0) ? state->sendQueueLimit : 0xffffffff) / sctpPathMap.size();
1064  if (bytesOnPath + path->pmtu > limit) {
1065  rejected = true;
1066  EV << simTime() << ":\tSenderBufferSplitting: Rejecting transmission on "
1067  << path->remoteAddress << ", since "
1068  << bytesOnPath << " + " << path->pmtu << " > "
1069  << state->sendQueueLimit / sctpPathMap.size() << endl;
1070  }
1071  }
1072 
1073  // ------ Receiver Side -----------------------------------
1074  if ((rejected == false) &&
1077  {
1078  // Limit is 1/n of current receiver-side buffer allocation
1079  const uint32 limit = (state->peerRwnd + state->outstandingBytes)
1080  / sctpPathMap.size();
1081  if (bytesOnPath + path->pmtu > limit + path->pmtu) {
1082  // T.D. 09.07.2011: Allow overbooking by up to 1 MTU ...
1083  EV << simTime() << ":\tReceiverBufferSplitting: Rejecting transmission on "
1084  << path->remoteAddress << ", since "
1085  << bytesOnPath + path->pmtu << " > " << limit << endl;
1086  rejected = true;
1087  }
1088  }
1089  }
1090 
1091  // ====== Buffer Splitting ===================================
1092  if (((state->allowCMT) || (path == state->getPrimaryPath())) &&
1093  (!rejected))
1094  {
1095  // ------ Dequeue data message ----------------------------
1096  EV_DETAIL << assocId << "sendAll: sctpMsg->length=" << sctpMsg->getByteLength()
1097  << " length datMsg=" << path->pmtu - sctpMsg->getByteLength() - 20 << endl;
1098  SCTPDataMsg *datMsg = dequeueOutboundDataMsg(path, path->pmtu - sctpMsg->getByteLength() - 20,
1099  allowance);
1100  if (datMsg == nullptr) {
1101  if (chunksAdded == 1 && sackAdded) {
1102  datMsg = dequeueOutboundDataMsg(path, path->pmtu - sctpMsg->getByteLength() + sackChunk->getByteLength() - 20,
1103  allowance);
1104  if (!sackOnly) {
1105  sctpMsg->removeChunk();
1106  EV_DETAIL << assocId << ": delete SACK chunk to make room for datMsg (" << &datMsg << "). scount=" << scount << "\n";
1107  delete sackChunk;
1108  chunksAdded--;
1109  sackAdded = false;
1110  }
1111  else {
1112  path->lastTransmission = simTime();
1113  path->packetsInBurst++;
1114  state->lastTransmission = simTime();
1116  if (dataChunksAdded > 0) {
1117  state->ssNextStream = true;
1118  }
1119  state->ackState = 0;
1120  // Stop SACK timer if it is running...
1123  state->sackAllowed = false;
1124  EV_DETAIL << assocId << ": send SACK and make new header for datMsg (" << &datMsg << "). scount=" << scount << "\n";
1125  sendSACKviaSelectedPath(sctpMsg);
1126  sctpMsg = nullptr;
1127  if (datMsg != nullptr) {
1128  sctpMsg = new SCTPMessage("send");
1129  sctpMsg->setByteLength(SCTP_COMMON_HEADER);
1130  headerCreated = true;
1131  sackAdded = false;
1132  chunksAdded = 0;
1133  }
1134  }
1135  }
1136  }
1137  // ------ Handle data message -----------------------------
1138  if (datMsg) {
1139  firstTime = true;
1140  if (datMsg->getFragment()) {
1141  if (datMsg->getBBit() && !datMsg->getEBit()) {
1142  state->fragInProgress = true;
1143  setFragInProgressOfStream(datMsg->getSid(), true);
1144  }
1145  if (datMsg->getEBit()) {
1146  state->fragInProgress = false;
1147  setFragInProgressOfStream(datMsg->getSid(), true);
1148  }
1149  }
1150  state->queuedMessages--;
1151  if ((state->queueLimit > 0) &&
1153  (state->queueUpdate == false))
1154  {
1155  // Tell upper layer readiness to accept more data
1157  state->queueUpdate = true;
1158  }
1159 
1160  datVar = makeDataVarFromDataMsg(datMsg, path);
1161  delete datMsg;
1162 
1163  EV_DETAIL << assocId << ":: sendAll: chunk " << datVar << " dequeued from StreamQ "
1164  << datVar->sid << ": tsn=" << datVar->tsn
1165  << ", bytes now " << qCounter.roomSumSendStreams << "\n";
1166  }
1167  // ------ No data message has been dequeued ---------------
1168  else {
1169  EV_DETAIL << assocId << ": No data message has been dequeued" << endl;
1170  // ------ Are there any chunks to send? ----------------
1171  if (chunksAdded == 0) {
1172  // No -> nothing more to do.
1173  if (state->sctpMsg == sctpMsg) {
1174  state->sctpMsg = nullptr;
1175  state->packetBytes = 0;
1176  }
1177  packetFull = true; // chunksAdded==0, packetFull==true => leave inner while loop
1178  }
1179  else {
1180  // Yes.
1181  if (state->nagleEnabled && ((outstandingBytes > 0) && !(sackOnly && sackAdded)) &&
1182  nextChunkFitsIntoPacket(path, path->pmtu - sctpMsg->getByteLength() - 20) &&
1183  (sctpMsg->getByteLength() < path->pmtu - 32 - 20) && (tcount == 0))
1184  {
1185  EV_DETAIL << "Nagle: Packet has to be stored\n";
1186  storePacket(path, sctpMsg, chunksAdded, dataChunksAdded, authAdded);
1187  sctpMsg = nullptr;
1188  chunksAdded = 0;
1189  }
1190  packetFull = true; // chunksAdded==0, packetFull==true => leave inner while loop
1191  EV_DETAIL << "sendAll: packetFull: msg length = " << sctpMsg->getByteLength() + 20 << "\n";
1192  }
1193  }
1194  }
1195  else if (chunksAdded == 1 && sackAdded && !sackOnly) {
1196  sctpMsg->removeChunk();
1197  EV_DETAIL << "Nagle or no data: Remove SACK chunk, delete sctpmsg" << endl;
1198  delete sackChunk;
1199  packetFull = true;
1200  sackAdded = false;
1201  chunksAdded--;
1202  }
1203  else if ((chunksAdded == 1 && sackAdded && sackOnly) || headerCreated) {
1204  packetFull = true;
1205  /* TD 19.02.2015:
1206  If we are not on the primary path, and
1207  there is a small chunk to send (bytesToSend > 0),
1208  and Nagle turned on:
1209  leave inner loop. Otherwise, there will be an infinite loop! */
1210  bytesToSend = 0;
1211  }
1212  }
1213  else if (chunksAdded == 1 && sackAdded && !sackOnly) {
1214  sctpMsg->removeChunk();
1215  EV_DETAIL << "Nagle or no data: Remove SACK chunk, delete sctpmsg\n";
1216  delete sackChunk;
1217  packetFull = true;
1218  sackAdded = false;
1219  chunksAdded--;
1220  }
1221  else if (chunksAdded == 1 && sackAdded && sackOnly) {
1222  packetFull = true;
1223  }
1224  else if (datVar == nullptr || chunksAdded == 0) {
1225  EV_DETAIL << "HeaderCreated=" << headerCreated << ", chunksAdded=" << chunksAdded << " datVar=" << datVar << "\n";
1226  if (headerCreated) {
1227  packetFull = true;
1228  }
1229  }
1230 
1231  // ------ Handle DATA chunk -------------------------------------
1232  if (datVar != nullptr && !packetFull) {
1233  // ------ Assign TSN -----------------------------------------
1234  if (firstTime) {
1235  assert(datVar->tsn == 0);
1236  datVar->tsn = state->nextTSN;
1237  EV_DETAIL << "sendAll: set TSN=" << datVar->tsn
1238  << " sid=" << datVar->sid << ", ssn=" << datVar->ssn << "\n";
1239  state->nextTSN++;
1240  path->vectorPathSentTSN->record(datVar->tsn);
1241  }
1242  else {
1243  if (datVar->hasBeenFastRetransmitted) {
1244  path->vectorPathTSNFastRTX->record(datVar->tsn);
1245  }
1246  else {
1247  path->vectorPathTSNTimerBased->record(datVar->tsn);
1248  }
1249  }
1250 
1251  auto iterator = sctpMain->assocStatMap.find(assocId);
1252  iterator->second.transmittedBytes += datVar->len / 8;
1253 
1254  datVar->setLastDestination(path);
1255  datVar->countsAsOutstanding = true;
1256  datVar->hasBeenReneged = false;
1257  datVar->sendTime = simTime(); //I.R. to send Fast RTX just once a RTT
1258  if (datVar->firstSendTime == 0) {
1259  datVar->firstSendTime = simTime();
1260  }
1261 
1262  // ------ First transmission of datVar -----------------------
1263  if (datVar->numberOfTransmissions == 0) {
1264  EV_DETAIL << "sendAll: " << simTime() << " firstTime, TSN "
1265  << datVar->tsn << ": lastDestination set to "
1266  << datVar->getLastDestination() << endl;
1267 
1268  if (!state->firstDataSent) {
1269  state->firstDataSent = true;
1270  }
1271  EV_DETAIL << "sendAll: insert in retransmissionQ tsn=" << datVar->tsn << "\n";
1272  if (!retransmissionQ->checkAndInsertChunk(datVar->tsn, datVar)) {
1273  throw cRuntimeError("Cannot add datVar to retransmissionQ!");
1274  // Falls es hier aufschlaegt, muss ueberlegt werden, ob es OK ist, dass datVars nicht eingefuegt werden koennen.
1275  }
1276  else {
1277  EV_DETAIL << "sendAll: size of retransmissionQ=" << retransmissionQ->getQueueSize() << "\n";
1278  unackChunk(datVar);
1279  increaseOutstandingBytes(datVar, path);
1280  datVar->queuedOnPath = path;
1281  datVar->queuedOnPath->queuedBytes += datVar->booksize;
1282  datVar->queuedOnPath->statisticsPathQueuedSentBytes->record(path->queuedBytes);
1283 
1284  state->queuedSentBytes += datVar->booksize;
1286  }
1287  }
1288 
1289  /* datVar is already in the retransmissionQ */
1290  datVar->numberOfTransmissions++;
1291  datVar->gapReports = 0;
1292  datVar->hasBeenFastRetransmitted = false;
1293  EV_DETAIL << "sendAll(): adding new outbound data datVar to packet (tsn=" << datVar->tsn << ")...!!!\n";
1294  /* update counters */
1295  totalChunksSent++;
1296  chunksAdded++;
1297  dataChunksAdded++;
1298 
1299  dataChunkPtr = transformDataChunk(datVar);
1300  sctpMsg->addChunk(dataChunkPtr);
1301 
1302  EV_DETAIL << assocId << ": DataChunk added - TSN:" << dataChunkPtr->getTsn() << " - length:" << dataChunkPtr->getByteLength() << " - ssn:" << dataChunkPtr->getSsn() << "\n";
1303 
1304  if (datVar->numberOfTransmissions > 1) {
1305  auto tq = qCounter.roomTransQ.find(path->remoteAddress);
1306  if (tq->second > 0) {
1307  if (transmissionQ->getSizeOfFirstChunk(path->remoteAddress) > path->pmtu - sctpMsg->getByteLength() - 20)
1308  packetFull = true;
1309  }
1310  else if (nextChunkFitsIntoPacket(path, path->pmtu - sctpMsg->getByteLength() - 20) == false) {
1311  packetFull = true;
1312  }
1313  }
1314  else {
1315  if (nextChunkFitsIntoPacket(path, path->pmtu - sctpMsg->getByteLength() - 20) == false) {
1316  packetFull = true;
1317  }
1318  }
1319 
1320  state->peerRwnd -= (datVar->booksize + state->bytesToAddPerPeerChunk);
1321  if (state->peerAllowsChunks) {
1322  state->peerMsgRwnd--;
1323  }
1324  if ((bytes.chunk == false) && (bytes.packet == false)) {
1325  bytesToSend -= datVar->booksize;
1326  }
1327  else if (bytes.chunk) {
1328  bytes.chunk = false;
1329  }
1330  else if ((bytes.packet) && (packetFull)) {
1331  bytes.packet = false;
1332  }
1333 
1334  if (bytesToSend <= 0) {
1335  if ((!packetFull) && (qCounter.roomSumSendStreams > path->pmtu - 32 - 20 || tcount > 0)) {
1336  sendOneMorePacket = true;
1337  bytes.packet = true;
1338  EV_DETAIL << assocId << ": sendAll: one more packet allowed\n";
1339  }
1340  else {
1341  if (state->nagleEnabled && (outstandingBytes > 0) &&
1342  nextChunkFitsIntoPacket(path, path->pmtu - sctpMsg->getByteLength() - 20) &&
1343  (sctpMsg->getByteLength() < path->pmtu - 32 - 20) && (tcount == 0))
1344  {
1345  storePacket(path, sctpMsg, chunksAdded, dataChunksAdded, authAdded);
1346  sctpMsg = nullptr;
1347  chunksAdded = 0;
1348  packetFull = true; // chunksAdded==0, packetFull==true => leave inner while loop
1349  }
1350  else {
1351  packetFull = true;
1352  }
1353  }
1354  bytesToSend = 0;
1355  }
1356  else if ((qCounter.roomSumSendStreams == 0) && (tq->second == 0)) {
1357  packetFull = true;
1358  EV_DETAIL << "sendAll: no data in send and transQ: packet full\n";
1359  }
1360  EV_DETAIL << "sendAll: bytesToSend after reduction: " << bytesToSend << "\n";
1361  } // end if (datVar != nullptr && !packetFull)
1362  // ------ There is no DATA chunk, only control chunks possible --
1363  else {
1364  if (chunksAdded == 0) { // Nothing to do -> return
1365  packetFull = true; // chunksAdded==0, packetFull==true => leave inner while loop
1366  }
1367  else {
1368  packetFull = true;
1369  EV_DETAIL << assocId << ": sendAll: packetFull: msg length = " << sctpMsg->getByteLength() + 20 << "\n";
1370  datVar = nullptr;
1371  }
1372  delete datVar;
1373  }
1374 
1375  // ====== Send packet ===========================================
1376  if (packetFull) {
1377  if (chunksAdded == 0) { // Nothing to send
1378  delete sctpMsg;
1379  sctpMsg = nullptr;
1380  sendingAllowed = false; // sendingAllowed==false => leave outer while loop
1381  }
1382  else {
1383  EV_DETAIL << assocId << ":: sendAll: " << simTime() << " packet full:"
1384  << " totalLength=" << sctpMsg->getBitLength() / 8 + 20
1385  << ", path=" << path->remoteAddress
1386  << " " << dataChunksAdded << " chunks added, outstandingBytes now "
1387  << path->outstandingBytes << "\n";
1388 
1389  /* new chunks would exceed MTU, so we send old packet and build a new one */
1390  /* this implies that at least one data chunk is send here */
1391  if (dataChunksAdded > 0) {
1392  if (!path->T3_RtxTimer->isScheduled()) {
1393  // Start retransmission timer, if not scheduled before
1394  startTimer(path->T3_RtxTimer, path->pathRto);
1395  }
1396  else {
1397  EV_DETAIL << "sendAll: RTX Timer already scheduled -> no need to schedule it\n";
1398  }
1399  }
1400  else {
1401  bytes.packet = false; // TD 23.02.2015: no DATA chunks => done.
1402  }
1403 
1404  if (sendOneMorePacket) {
1405  sendOneMorePacket = false;
1406  bytesToSend = 0;
1407  bytes.packet = false;
1408  SCTPDataChunk *pkt = check_and_cast<SCTPDataChunk *>(sctpMsg->getChunks(sctpMsg->getChunksArraySize() - 1));
1409  pkt->setIBit(sctpMain->sackNow);
1410  sctpMsg->replaceChunk(pkt, sctpMsg->getChunksArraySize() - 1);
1411  }
1412 
1413  // Set I-bit when this is the final packet for this path!
1414  const int32 a = (int32)path->cwnd - (int32)path->outstandingBytes;
1415  if ((((a > 0) && (nextChunkFitsIntoPacket(path, a) == false)) || (!firstPass)) && !forwardPresent) {
1416  SCTPDataChunk *pkt = check_and_cast<SCTPDataChunk *>(sctpMsg->getChunks(sctpMsg->getChunksArraySize() - 1));
1417  pkt->setIBit(sctpMain->sackNow);
1418  sctpMsg->replaceChunk(pkt, sctpMsg->getChunksArraySize() - 1);
1419  }
1420 
1421  if (dataChunksAdded > 0) {
1422  state->ssNextStream = true;
1423  }
1424  EV_DETAIL << assocId << ":sendToIP: packet size=" << sctpMsg->getByteLength() << " numChunks=" << sctpMsg->getChunksArraySize() << "\n";
1425  sendToIP(sctpMsg, path->remoteAddress);
1426  sctpMsg = nullptr;
1427  pmDataIsSentOn(path);
1428  totalPacketsSent++;
1429  path->lastTransmission = simTime();
1430  path->packetsInBurst++;
1431  state->lastTransmission = simTime();
1433 
1434  // ------ Reset status ------------------------------------
1435  firstTime = false;
1436  headerCreated = false;
1437  chunksAdded = 0;
1438  dataChunksAdded = 0;
1439  authAdded = false;
1440 
1441  EV_INFO << "sendAll: sending Packet to path " << path->remoteAddress
1442  << " scount=" << scount
1443  << " tcount=" << tcount
1444  << " bytesToSend=" << bytesToSend << endl;
1445  }
1446  }
1447  EV_INFO << "sendAll: still " << bytesToSend
1448  << " bytes to send, headerCreated=" << headerCreated << endl;
1449  } // if (bytesToSend > 0 || bytes.chunk || bytes.packet)
1450  else if (headerCreated && state->bundleReset) {
1451  sendToIP(sctpMsg, path->remoteAddress);
1452  sctpMsg = nullptr;
1453  return;
1454  } else {
1455  packetFull = true; // Leave inner while loop
1456  delete sctpMsg; // T.D. 19.01.2010: Free unsent message
1457  sctpMsg = nullptr;
1458  }
1459 
1460  EV_INFO << "packetFull=" << packetFull << endl;
1461  } // while(!packetFull)
1462 
1463  EV_INFO << "bytesToSend=" << bytesToSend
1464  << " bytes.chunk=" << bytes.chunk
1465  << " bytes.packet=" << bytes.packet << endl;
1466  if (!(bytesToSend > 0 || bytes.chunk || bytes.packet)) {
1467  sendingAllowed = false;
1468  }
1469  } // while(sendingAllowed)
1470 
1471  if (state->ackState >= sackFrequency)
1472  sendSack();
1473 
1474  EV_INFO << "sendAll: nothing more to send... BYE!\n";
1475 }
uint64 sendQueueLimit
Definition: SCTPAssociation.h:659
MBVariant maxBurstVariant
Definition: SCTPAssociation.h:702
void pmDataIsSentOn(SCTPPathVariables *path)
Definition: SCTPAssociationUtil.cc:2650
uint32 queueLimit
Definition: SCTPAssociation.h:640
SCTPDataChunk * transformDataChunk(SCTPDataVariables *chunk)
Manipulating chunks.
Definition: SCTPAssociationUtil.cc:2011
Definition: SCTPAssociation.h:718
uint32 sackFrequency
Definition: SCTPAssociation.h:949
bool fragInProgress
Definition: SCTPAssociation.h:601
CounterMap roomTransQ
Definition: SCTPAssociation.h:878
Definition: SCTPAssociation.h:111
void bytesAllowedToSend(SCTPPathVariables *path, const bool firstPass)
Definition: SCTPAssociationSendAll.cc:556
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
bool sackNow
Definition: SCTP.h:213
uint32 maxBurst
Definition: SCTPAssociation.h:692
bool bundleReset
Definition: SCTPAssociation.h:788
Definition: SCTPAssociation.h:698
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
uint64 peerRwnd
Definition: SCTPAssociation.h:610
bool ssNextStream
Definition: SCTPAssociation.h:853
void unackChunk(SCTPDataVariables *chunk)
Definition: SCTPAssociation.h:1443
bool cmtBufferSplittingUsesOSB
Definition: SCTPAssociation.h:723
BytesToBeSent bytes
Definition: SCTPAssociation.h:961
Definition: SCTPAssociation.h:719
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
SCTPDataVariables * getOutboundDataChunk(const SCTPPathVariables *path, const int32 availableSpace, const int32 availableCwnd)
Definition: SCTPAssociationUtil.cc:2223
SCTPForwardTsnChunk * createForwardTsnChunk(const L3Address &pid)
Definition: SCTPAssociationUtil.cc:1283
bool sackAllowed
Definition: SCTPAssociation.h:586
bool allowCMT
Definition: SCTPAssociation.h:705
void increaseOutstandingBytes(SCTPDataVariables *chunk, SCTPPathVariables *path)
Definition: SCTPAssociationSendAll.cc:31
BufferSplitVariant cmtBufferSplitVariant
Definition: SCTPAssociation.h:722
bool addAuthChunkIfNecessary(SCTPMessage *sctpMsg, const uint16 chunkType, const bool authAdded)
Definition: SCTPAssociation.h:1483
ChunkReschedulingVariant cmtChunkReschedulingVariant
Definition: SCTPAssociation.h:732
bool nextChunkFitsIntoPacket(SCTPPathVariables *path, int32 bytes)
Definition: SCTPAssociationUtil.cc:2547
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
SCTPPathVariables * getPrimaryPath() const
Definition: SCTPAssociation.h:558
bool waitForResponse
Definition: SCTPAssociation.h:789
Definition: SCTPAssociation.h:700
void setFragInProgressOfStream(uint16 sid, bool frag)
Definition: SCTPAssociationUtil.cc:107
Definition: SCTPAssociation.h:720
SCTPPathVariables * choosePathForRetransmission()
Definition: SCTPAssociationSendAll.cc:237
void storePacket(SCTPPathVariables *pathVar, SCTPMessage *sctpMsg, const uint16 chunksAdded, const uint16 dataChunksAdded, const bool authAdded)
Definition: SCTPAssociationSendAll.cc:55
bool queueUpdate
Definition: SCTPAssociation.h:593
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
uint32 bytesToRetransmit
Definition: SCTPAssociation.h:632
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
bool cmtUseDAC
Definition: SCTPAssociation.h:740
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
cMessage * SackTimer
Definition: SCTPAssociation.h:922
uint8_t dacPacketsRcvd
Definition: SCTPAssociation.h:933
uint64 queuedMessages
Definition: SCTPAssociation.h:638
SCTPDataVariables * makeDataVarFromDataMsg(SCTPDataMsg *datMsg, SCTPPathVariables *path)
Definition: SCTPAssociationSendAll.cc:183
SCTP * sctpMain
Definition: SCTPAssociation.h:962
bool nagleEnabled
Definition: SCTPAssociation.h:585
uint32 ackState
Definition: SCTPAssociation.h:618
void timeForSack(bool &sackOnly, bool &sackWithData)
Definition: SCTPAssociationSendAll.cc:253
uint32 peerMsgRwnd
Definition: SCTPAssociation.h:841
bool chunk
Definition: SCTPAssociation.h:884
SCTPMessage * sctpMsg
Definition: SCTPAssociation.h:668
SCTPDataMsg * dequeueOutboundDataMsg(SCTPPathVariables *path, const int32 availableSpace, const int32 availableCwnd)
Definition: SCTPAssociationUtil.cc:2479
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
bool strictCwndBooking
Definition: SCTPAssociation.h:745
uint64 outstandingBytes
Definition: SCTPAssociation.h:622
SCTPDataVariables * peekAbandonedChunk(const SCTPPathVariables *path)
Definition: SCTPAssociationUtil.cc:2302
Definition: SCTPAssociation.h:726
uint32 packetsInTotalBurst
Definition: SCTPAssociation.h:620
AssocStatMap assocStatMap
Definition: SCTP.h:171
bool peerAllowsChunks
Definition: SCTPAssociation.h:838
uint32 bytesToAddPerPeerChunk
Definition: SCTPAssociation.h:845
void sendSACKviaSelectedPath(SCTPMessage *sctpMsg)
Definition: SCTPAssociationSendAll.cc:507
QueueCounter qCounter
Definition: SCTPAssociation.h:965
void chunkReschedulingControl(SCTPPathVariables *path)
Definition: SCTPAssociationSendAll.cc:338
bool checkAndInsertChunk(const uint32 key, SCTPDataVariables *chunk)
Definition: SCTPQueue.cc:50
bool packet
Definition: SCTPAssociation.h:885
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
cOutVector * statisticsQueuedSentBytes
Definition: SCTPAssociation.h:975
Definition: SCTPAssociation.h:114
void sendSack()
Definition: SCTPAssociationUtil.cc:1764
Definition: SCTPAssociation.h:129
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
int32 assocId
Definition: SCTPAssociation.h:908
bool firstDataSent
Definition: SCTPAssociation.h:594
void loadPacket(SCTPPathVariables *pathVar, SCTPMessage **sctpMsg, uint16 *chunksAdded, uint16 *dataChunksAdded, bool *authAdded)
Definition: SCTPAssociationSendAll.cc:92
uint32 getQueueSize() const
Definition: SCTPQueue.cc:60
uint32 nextTSN
Definition: SCTPAssociation.h:613
SCTPAlgorithm * sctpAlgorithm
Definition: SCTPAssociation.h:970
bool resetPending
Definition: SCTPAssociation.h:589
uint16_t uint16
Definition: Compat.h:32
uint32 packetBytes
Definition: SCTPAssociation.h:671
bool stopSending
Definition: SCTPAssociation.h:597
bool ackPointAdvanced
Definition: SCTPAssociation.h:574
virtual void sackSent()=0
Definition: SCTPCommand.h:74
uint64 queuedSentBytes
Definition: SCTPAssociation.h:623
uint32 getAllTransQ()
Definition: SCTPAssociationSendAll.cc:1477
simtime_t lastTransmission
Definition: SCTPAssociation.h:621
SCTPSackChunk * createSack()
Definition: SCTPAssociationUtil.cc:1473
uint32 bytesToSend
Definition: SCTPAssociation.h:886
uint32 getSizeOfFirstChunk(const L3Address &remoteAddress)
Definition: SCTPQueue.cc:238
if(!(yy_init))
Definition: lexer.cc:1644
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool chunkHasBeenAcked(const SCTPDataVariables *chunk) const
Definition: SCTPAssociation.h:1448
void inet::sctp::SCTPAssociation::sendOutgoingRequestAndResponse ( uint32  inRequestSn,
uint32  outRequestSn 
)
protected

Referenced by process_RCV_Message(), and processInAndOutResetRequestArrived().

384 {
385  EV_INFO << "sendOutgoingResetRequest to " << remoteAddr << "\n";
386  SCTPMessage *msg = new SCTPMessage();
387  msg->setByteLength(SCTP_COMMON_HEADER);
388  msg->setSrcPort(localPort);
389  msg->setDestPort(remotePort);
390  SCTPStreamResetChunk *resChunk = new SCTPStreamResetChunk("ReqResRE_CONFIG");
391  resChunk->setChunkType(RE_CONFIG);
392  resChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
394  SCTPResetTimer *rt = new SCTPResetTimer();
395  SCTPOutgoingSSNResetRequestParameter *outResetParam;
396  outResetParam = new SCTPOutgoingSSNResetRequestParameter("Outgoing_Request_Param");
397  outResetParam->setParameterType(OUTGOING_RESET_REQUEST_PARAMETER);
398  outResetParam->setSrReqSn(srsn++);
399  outResetParam->setSrResSn(inRequestSn);
400  outResetParam->setLastTsn(state->nextTSN - 1);
401  outResetParam->setByteLength(SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH);
402  resChunk->addParameter(outResetParam);
404  SCTPStreamResetResponseParameter *responseParam = new SCTPStreamResetResponseParameter("Response_Param");
405  responseParam->setParameterType(STREAM_RESET_RESPONSE_PARAMETER);
406  responseParam->setSrResSn(outRequestSn);
407  responseParam->setResult(1);
408  responseParam->setByteLength(SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH);
409  resChunk->addParameter(responseParam);
410  rt->setInSN(srsn - 1);
411  rt->setInAcked(false);
412  rt->setOutSN(outRequestSn);
413  rt->setOutAcked(false);
414  if (state->resetChunk != nullptr) {
415  delete state->resetChunk;
416  state->resetChunk = nullptr;
417  }
418  state->resetChunk = check_and_cast<SCTPStreamResetChunk *>(resChunk->dup());
419  state->resetChunk->setName("stateRstChunk");
420  msg->addChunk(resChunk);
421  sendToIP(msg, remoteAddr);
422  PK(getPath(remoteAddr)->ResetTimer)->encapsulate(rt);
423  startTimer(getPath(remoteAddr)->ResetTimer, getPath(remoteAddr)->pathRto);
424 }
uint32 streamResetSequenceNumber
Definition: SCTPAssociation.h:793
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
Definition: SCTPAssociation.h:159
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
uint16 remotePort
Definition: SCTPAssociation.h:914
#define SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH
Definition: SCTPAssociation.h:228
Definition: SCTPAssociation.h:156
Definition: SCTPAssociation.h:128
L3Address remoteAddr
Definition: SCTPAssociation.h:911
#define SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:225
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
IRoutingTable * rt
Definition: SCTPAssociation.h:936
uint32_t uint32
Definition: Compat.h:30
#define PK(msg)
Definition: INETDefs.h:92
uint32 nextTSN
Definition: SCTPAssociation.h:613
uint16 localPort
Definition: SCTPAssociation.h:913
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendOutgoingRequestAndResponse ( SCTPIncomingSSNResetRequestParameter inRequestParam,
SCTPOutgoingSSNResetRequestParameter outRequestParam 
)
protected
428 {
429  uint16 len = 0;
430  EV_INFO << "sendOutgoingRequestAndResponse to " << remoteAddr << "\n";
431  SCTPMessage *msg = new SCTPMessage();
432  msg->setByteLength(SCTP_COMMON_HEADER);
433  msg->setSrcPort(localPort);
434  msg->setDestPort(remotePort);
435  SCTPStreamResetChunk *resChunk = new SCTPStreamResetChunk("ReqResRE_CONFIG");
436  resChunk->setChunkType(RE_CONFIG);
437  resChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
439  SCTPResetTimer *rt = new SCTPResetTimer();
440  SCTPOutgoingSSNResetRequestParameter *outResetParam;
441  outResetParam = new SCTPOutgoingSSNResetRequestParameter("Outgoing_Reset_Request_Param");
442  outResetParam->setParameterType(OUTGOING_RESET_REQUEST_PARAMETER);
443  outResetParam->setSrReqSn(srsn++);
444  outResetParam->setSrResSn(inRequestParam->getSrReqSn());
445  outResetParam->setLastTsn(state->nextTSN - 1);
446  if (inRequestParam->getStreamNumbersArraySize() > 0) {
447  outResetParam->setStreamNumbersArraySize(inRequestParam->getStreamNumbersArraySize());
448  for (uint i = 0; i < inRequestParam->getStreamNumbersArraySize(); i++) {
449  outResetParam->setStreamNumbers(i, (uint16)inRequestParam->getStreamNumbers(i));
450  state->resetOutStreams.push_back(outResetParam->getStreamNumbers(i));
451  state->requests[srsn].streams.push_back(outResetParam->getStreamNumbers(i));
452  len++;
453  }
454  }
455  outResetParam->setByteLength(SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH + len * 2);
456  resChunk->addParameter(outResetParam);
458  SCTPStreamResetResponseParameter *responseParam = new SCTPStreamResetResponseParameter("Response_Param");
459  responseParam->setParameterType(STREAM_RESET_RESPONSE_PARAMETER);
460  responseParam->setSrResSn(outRequestParam->getSrReqSn());
461  responseParam->setResult(1);
462  responseParam->setByteLength(SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH);
463  resChunk->addParameter(responseParam);
464  rt->setInSN(srsn - 1);
465  rt->setInAcked(false);
466  rt->setOutSN(outRequestParam->getSrReqSn());
467  rt->setOutAcked(false);
468  if (state->resetChunk != nullptr) {
469  delete state->resetChunk;
470  state->resetChunk = nullptr;
471  }
472  state->resetChunk = check_and_cast<SCTPStreamResetChunk *>(resChunk->dup());
473  state->resetChunk->setName("stateRstChunk");
474  msg->addChunk(resChunk);
475  sendToIP(msg, remoteAddr);
476  if (PK(getPath(remoteAddr)->ResetTimer)->hasEncapsulatedPacket()) {
477  PK(getPath(remoteAddr)->ResetTimer)->decapsulate();
478  }
479  PK(getPath(remoteAddr)->ResetTimer)->encapsulate(rt);
480  startTimer(getPath(remoteAddr)->ResetTimer, getPath(remoteAddr)->pathRto);
481 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
uint32 streamResetSequenceNumber
Definition: SCTPAssociation.h:793
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
uint16_t len
Definition: TCP_NSC.cc:85
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
unsigned int uint
Definition: INETDefs.h:63
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
Definition: SCTPAssociation.h:159
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
uint16 remotePort
Definition: SCTPAssociation.h:914
#define SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH
Definition: SCTPAssociation.h:228
Definition: SCTPAssociation.h:156
Definition: SCTPAssociation.h:128
L3Address remoteAddr
Definition: SCTPAssociation.h:911
#define SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:225
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
IRoutingTable * rt
Definition: SCTPAssociation.h:936
uint32_t uint32
Definition: Compat.h:30
std::list< uint16 > resetOutStreams
Definition: SCTPAssociation.h:801
#define PK(msg)
Definition: INETDefs.h:92
uint32 nextTSN
Definition: SCTPAssociation.h:613
uint16_t uint16
Definition: Compat.h:32
uint16 localPort
Definition: SCTPAssociation.h:913
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendOutgoingResetRequest ( SCTPIncomingSSNResetRequestParameter requestParam)
protected

Referenced by processIncomingResetRequestArrived().

99 {
100  EV_INFO << "sendOutgoingResetRequest to " << remoteAddr << "\n";
101  uint16 len = 0;
102  uint32 srsn = 0;
103  if ((!(getPath(remoteAddr)->ResetTimer->isScheduled())) || state->requestsOverlap) {
104  state->requestsOverlap = false;
105  SCTPStreamResetChunk *resetChunk = new SCTPStreamResetChunk("OutRE_CONFIG");
106  resetChunk->setChunkType(RE_CONFIG);
107  resetChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
108  SCTPOutgoingSSNResetRequestParameter *outResetParam;
109  outResetParam = new SCTPOutgoingSSNResetRequestParameter("Outgoing_SSN_Request_Param");
110  outResetParam->setParameterType(OUTGOING_RESET_REQUEST_PARAMETER);
112  if (resDat != nullptr && resDat->sn == state->streamResetSequenceNumber - 1) {
113  srsn = state->streamResetSequenceNumber - 1;
114  } else {
116  state->requests[srsn].result = 100;
118  state->requests[srsn].sn = srsn;
120  }
121  outResetParam->setSrReqSn(srsn++);
122  outResetParam->setSrResSn(requestParam->getSrReqSn());
123  if (state->findPeerRequestNum(requestParam->getSrReqSn())) {
124  state->peerRequests[requestParam->getSrReqSn()].result = PERFORMED;
125  state->firstPeerRequest = false;
126  if (state->incomingRequestSet && state->incomingRequest != nullptr) {
127  delete state->incomingRequest;
128  state->incomingRequest = nullptr;
129  state->incomingRequestSet = false;
130  }
131  }
132  outResetParam->setLastTsn(state->nextTSN - 1);
133  if (state->peerStreamsToReset.size() > 0) {
134  outResetParam->setStreamNumbersArraySize(state->peerStreamsToReset.size());
135  uint16 i = 0;
136  for (std::list<uint16>::iterator it = state->peerStreamsToReset.begin(); it != state->peerStreamsToReset.end(); ++it) {
137  outResetParam->setStreamNumbers(i, *it);
138  state->resetOutStreams.push_back(outResetParam->getStreamNumbers(i));
139  state->requests[srsn-1].streams.push_back(outResetParam->getStreamNumbers(i));
140  i++;
141  }
142  len = state->peerStreamsToReset.size() * 2;
143  state->peerStreamsToReset.clear();
144  } else if (state->streamsToReset.size() > 0) {
145  outResetParam->setStreamNumbersArraySize(state->streamsToReset.size());
146  uint16 i = 0;
147  for (std::list<uint16>::iterator it = state->streamsToReset.begin(); it != state->streamsToReset.end(); ++it) {
148  outResetParam->setStreamNumbers(i, *it);
149  state->resetOutStreams.push_back(outResetParam->getStreamNumbers(i));
150  state->requests[srsn-1].streams.push_back(outResetParam->getStreamNumbers(i));
151  resetSsn(outResetParam->getStreamNumbers(i));
152  i++;
153  }
154  len = state->streamsToReset.size() * 2;
155  state->streamsToReset.clear();
156  } else if (requestParam->getStreamNumbersArraySize() > 0) {
157  outResetParam->setStreamNumbersArraySize(requestParam->getStreamNumbersArraySize());
158  for (uint16 i = 0; i < requestParam->getStreamNumbersArraySize(); i++) {
159  outResetParam->setStreamNumbers(i, requestParam->getStreamNumbers(i));
160  state->requests[srsn-1].streams.push_back(requestParam->getStreamNumbers(i));
161  }
162  len = requestParam->getStreamNumbersArraySize() * 2;
163  }
164  outResetParam->setByteLength(SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH + len);
165  resetChunk->addParameter(outResetParam);
167  state->resetRequested = true;
168 
169  SCTPResetTimer *rt = new SCTPResetTimer();
170  rt->setInSN(0);
171  rt->setInAcked(true);
172  rt->setOutSN(srsn - 1);
173  rt->setOutAcked(false);
174 
175  SCTPMessage *msg = new SCTPMessage();
176  msg->setByteLength(SCTP_COMMON_HEADER);
177  msg->setSrcPort(localPort);
178  msg->setDestPort(remotePort);
179  msg->addChunk(resetChunk);
181  if (state->resetChunk != nullptr) {
182  delete state->resetChunk;
183  state->resetChunk = nullptr;
184  }
185  state->resetChunk = check_and_cast<SCTPStreamResetChunk *>(resetChunk->dup());
186  if (qCounter.roomSumSendStreams != 0) {
187  storePacket(getPath(remoteAddr), msg, 1, 0, false);
188  state->bundleReset = true;
189  rt->setName("bundleReset");
190  sendOnPath(getPath(remoteAddr), true);
191  state->bundleReset = false;
192  } else {
193  sendToIP(msg, remoteAddr);
194  }
195  if (PK(getPath(remoteAddr)->ResetTimer)->hasEncapsulatedPacket()) {
196  delete (PK(getPath(remoteAddr)->ResetTimer)->decapsulate());
197  }
198  PK(getPath(remoteAddr)->ResetTimer)->encapsulate(rt);
199  if (getPath(remoteAddr)->ResetTimer->isScheduled()) {
200  stopTimer(getPath(remoteAddr)->ResetTimer);
201  }
202  startTimer(getPath(remoteAddr)->ResetTimer, getPath(remoteAddr)->pathRto);
203  }
204 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
uint32 streamResetSequenceNumber
Definition: SCTPAssociation.h:793
bool resetRequested
Definition: SCTPAssociation.h:590
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
bool bundleReset
Definition: SCTPAssociation.h:788
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
uint16_t len
Definition: TCP_NSC.cc:85
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
uint16 localRequestType
Definition: SCTPAssociation.h:810
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
bool firstPeerRequest
Definition: SCTPAssociation.h:790
void storePacket(SCTPPathVariables *pathVar, SCTPMessage *sctpMsg, const uint16 chunksAdded, const uint16 dataChunksAdded, const bool authAdded)
Definition: SCTPAssociationSendAll.cc:55
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
std::map< uint32, RequestData > peerRequests
Definition: SCTPAssociation.h:807
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
Definition: SCTPAssociation.h:150
uint16 remotePort
Definition: SCTPAssociation.h:914
bool requestsOverlap
Definition: SCTPAssociation.h:792
std::list< uint16 > peerStreamsToReset
Definition: SCTPAssociation.h:805
Definition: SCTPAssociation.h:156
Definition: SCTPAssociation.h:128
L3Address remoteAddr
Definition: SCTPAssociation.h:911
QueueCounter qCounter
Definition: SCTPAssociation.h:965
#define SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:225
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
IRoutingTable * rt
Definition: SCTPAssociation.h:936
uint16 numResetRequests
Definition: SCTPAssociation.h:644
uint32_t uint32
Definition: Compat.h:30
struct inet::sctp::SCTPStateVariables::requestData RequestData
void resetSsn(uint16 id)
Definition: SCTPAssociationStreamReset.cc:884
SCTPParameter * incomingRequest
Definition: SCTPAssociation.h:800
std::list< uint16 > resetOutStreams
Definition: SCTPAssociation.h:801
#define PK(msg)
Definition: INETDefs.h:92
std::list< uint16 > streamsToReset
Definition: SCTPAssociation.h:804
uint32 nextTSN
Definition: SCTPAssociation.h:613
uint16_t uint16
Definition: Compat.h:32
bool findPeerRequestNum(uint32 num)
Definition: SCTPAssociationBase.cc:518
Definition: SCTPAssociation.h:144
uint16 localPort
Definition: SCTPAssociation.h:913
void sendOnPath(SCTPPathVariables *pathId, const bool firstPass=true)
Utility: Send data from sendQueue.
Definition: SCTPAssociationSendAll.cc:668
RequestData * findTypeInRequests(uint16 type)
Definition: SCTPAssociationBase.cc:545
bool incomingRequestSet
Definition: SCTPAssociation.h:602
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendPacketDrop ( const bool  flag)
protected

Referenced by process_RCV_Message(), and processDataArrived().

1188 {
1189  EV_INFO << "sendPacketDrop:\t";
1190  SCTPMessage *drop = (SCTPMessage *)state->sctpmsg->dup(); //FIXME is the c-style conversion need here?
1191  if (drop->getChunksArraySize() == 1) {
1192  SCTPChunk *header = (SCTPChunk *)(drop->getChunks(0));
1193  if (header->getChunkType() == PKTDROP) {
1195  delete drop;
1196  return;
1197  }
1198  }
1199  SCTPMessage *sctpmsg = new SCTPMessage();
1200  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
1201  SCTPPacketDropChunk *pktdrop = new SCTPPacketDropChunk("PKTDROP");
1202  pktdrop->setChunkType(PKTDROP);
1203  pktdrop->setCFlag(false);
1204  pktdrop->setTFlag(false);
1205  pktdrop->setBFlag(flag);
1206  pktdrop->setMFlag(false);
1207  pktdrop->setMaxRwnd(sctpMain->par("arwnd"));
1208  pktdrop->setQueuedData(state->queuedReceivedBytes);
1209  pktdrop->setTruncLength(0);
1210  pktdrop->setByteLength(SCTP_PKTDROP_CHUNK_LENGTH);
1212  if (drop->getByteLength() > mss) {
1213  uint16 diff = drop->getByteLength() - mss;
1214  pktdrop->setTruncLength(drop->getByteLength());
1215  SCTPChunk *chunk = (SCTPChunk *)(drop->removeLastChunk());
1216  if (chunk->getChunkType() == DATA) {
1217  SCTPDataChunk *dataChunk = check_and_cast<SCTPDataChunk *>(chunk);
1218  SCTPSimpleMessage *smsg = check_and_cast<SCTPSimpleMessage *>(dataChunk->decapsulate());
1219  if (smsg->getDataLen() > diff) {
1220  uint16 newLength = smsg->getDataLen() - diff;
1221  smsg->setDataArraySize(newLength);
1222  for (uint16 i = 0; i < newLength; i++)
1223  smsg->setData(i, 'a');
1224  smsg->setDataLen(newLength);
1225  smsg->setEncaps(false);
1226  smsg->setByteLength(newLength);
1227  dataChunk->encapsulate(smsg);
1228  drop->addChunk(dataChunk);
1229  }
1230  else if (drop->getChunksArraySize() == 1) {
1231  delete chunk;
1232  delete pktdrop;
1234  EV_DETAIL << "laenge=" << drop->getByteLength() << " numberOfChunks=1\n";
1235  disposeOf(drop);
1236  return;
1237  }
1238  }
1239  else {
1240  delete pktdrop;
1242  EV_DETAIL << "laenge=" << drop->getByteLength() << " numberOfChunks=1\n";
1243  disposeOf(drop);
1244  return;
1245  }
1246  pktdrop->setTFlag(true);
1247  }
1248  pktdrop->encapsulate(drop);
1249  EV_DETAIL << "length of PKTDROP chunk=" << pktdrop->getBitLength() / 8 << "\n";
1250  sctpmsg->addChunk(pktdrop);
1251  EV_DETAIL << "total length now " << sctpmsg->getByteLength() << "\n";
1253  state->pktDropSent = true;
1255  sendToIP(sctpmsg);
1256 }
Definition: SCTPAssociation.h:111
SCTPMessage * sctpmsg
Definition: SCTPAssociation.h:658
Definition: SCTPAssociation.h:127
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
bool pktDropSent
Definition: SCTPAssociation.h:834
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
void disposeOf(SCTPMessage *sctpmsg)
Definition: SCTPAssociationUtil.cc:2800
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
#define IP_HEADER_LENGTH
Definition: SCTPAssociation.h:236
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
SCTP * sctpMain
Definition: SCTPAssociation.h:962
uint32 pmtu
Definition: SCTPAssociation.h:301
L3Address remoteAddr
Definition: SCTPAssociation.h:911
uint64 numPktDropReports
Definition: SCTP.h:214
uint16_t uint16
Definition: Compat.h:32
uint64 queuedReceivedBytes
Definition: SCTPAssociation.h:625
#define SCTP_PKTDROP_CHUNK_LENGTH
Definition: SCTPAssociation.h:234
virtual SCTPMessage * dup() const override
Definition: SCTPMessage.h:49
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendSack ( )
protected

Referenced by process_RCV_Message(), processPacketDropArrived(), pushUlp(), and sendOnPath().

1765 {
1766  SCTPAuthenticationChunk *authChunk;
1767  SCTPSackChunk *sackChunk;
1768 
1769  EV_INFO << "Sending SACK" << endl;
1770 
1771  /* sack timer has expired, reset flag, and send SACK */
1773  state->ackState = 0;
1774  sackChunk = createSack();
1775 
1776  SCTPMessage *sctpmsg = new SCTPMessage();
1777  sctpmsg->setByteLength(SCTP_COMMON_HEADER);
1778  if (state->auth && state->peerAuth && typeInChunkList(SACK)) {
1779  authChunk = createAuthChunk();
1780  sctpmsg->addChunk(authChunk);
1781  auto it = sctpMain->assocStatMap.find(assocId);
1782  it->second.numAuthChunksSent++;
1783  }
1784  sctpmsg->addChunk(sackChunk);
1785 
1786  sendSACKviaSelectedPath(sctpmsg);
1787 }
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
cMessage * SackTimer
Definition: SCTPAssociation.h:922
bool auth
Definition: SCTPAssociation.h:822
SCTP * sctpMain
Definition: SCTPAssociation.h:962
uint32 ackState
Definition: SCTPAssociation.h:618
AssocStatMap assocStatMap
Definition: SCTP.h:171
void sendSACKviaSelectedPath(SCTPMessage *sctpMsg)
Definition: SCTPAssociationSendAll.cc:507
Definition: SCTPAssociation.h:114
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
SCTPSackChunk * createSack()
Definition: SCTPAssociationUtil.cc:1473
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendSACKviaSelectedPath ( SCTPMessage sctpMsg)
private

Referenced by sendInvalidStreamError(), sendOnPath(), and sendSack().

508 {
509  SCTPPathVariables *sackPath =
510  (state->lastDataSourceList.size() > 0) ? state->lastDataSourceList.front() :
512  assert(sackPath != nullptr);
513 
514  if (state->allowCMT) {
516  /* Observation:
517  For same bandwidths but different delays, chunks on both paths arrive
518  with same interleave time =>
519  Chunk on A / Chunk on B => SACK on B
520  Chunk on A / Chunk on B => SACK on B
521  Chunk on A / Chunk on B => SACK on B
522  Chunk on A / Chunk on B => SACK on B
523  Chunk on A / Chunk on B => SACK on B
524  ...
525  RESULT: Losts of SACKs on B, no SACK on A => Bad performance! */
526 
527  // Solution is now to make a round-robin selection among paths,
528  // taking the path with the longest time passed since last SACK.
529  for (auto path : state->lastDataSourceList)
530  {
531  if (path->lastSACKSent < sackPath->lastSACKSent) {
532  sackPath = path;
533  }
534  }
535  }
537  /* Instead of RR among last DATA paths, send SACK on
538  the DATA path having the smallest SRTT. */
539  for (auto path : state->lastDataSourceList)
540  {
541  if (path->srtt < sackPath->srtt) {
542  sackPath = path;
543  }
544  }
545  }
547  sackPath = state->getPrimaryPath();
548  }
549  }
550  EV_INFO << assocId << ": sending SACK to " << sackPath->remoteAddress << endl;
551  sendToIP(sctpMsg, sackPath->remoteAddress);
552  sackPath->lastSACKSent = simTime();
553  state->lastDataSourceList.clear(); // Clear the address list!
554 }
SCTPPathVariables * lastDataSourcePath
Definition: SCTPAssociation.h:606
std::list< SCTPPathVariables * > lastDataSourceList
Definition: SCTPAssociation.h:605
Definition: SCTPAssociation.h:749
bool allowCMT
Definition: SCTPAssociation.h:705
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
SCTPPathVariables * getPrimaryPath() const
Definition: SCTPAssociation.h:558
Definition: SCTPAssociation.h:748
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
int32 assocId
Definition: SCTPAssociation.h:908
CSackPath cmtSackPath
Definition: SCTPAssociation.h:752
Definition: SCTPAssociation.h:750
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendShutdown ( )
protected

Referenced by process_CLOSE(), and process_RCV_Message().

1129 {
1130  SCTPAuthenticationChunk *authChunk;
1131  SCTPMessage *msg = new SCTPMessage();
1132  msg->setByteLength(SCTP_COMMON_HEADER);
1133 
1134  EV_INFO << "SCTPAssociationUtil:sendShutdown localPort=" << localPort << " remotePort=" << remotePort << "\n";
1135 
1136  msg->setSrcPort(localPort);
1137  msg->setDestPort(remotePort);
1138  SCTPShutdownChunk *shutdownChunk = new SCTPShutdownChunk("SHUTDOWN");
1139  shutdownChunk->setChunkType(SHUTDOWN);
1140  //shutdownChunk->setCumTsnAck(state->lastTsnAck);
1141  shutdownChunk->setCumTsnAck(state->gapList.getCumAckTSN());
1142  shutdownChunk->setByteLength(SCTP_SHUTDOWN_CHUNK_LENGTH);
1144  authChunk = createAuthChunk();
1145  msg->addChunk(authChunk);
1146  auto it = sctpMain->assocStatMap.find(assocId);
1147  it->second.numAuthChunksSent++;
1148  }
1155  state->shutdownChunk = check_and_cast<SCTPShutdownChunk *>(shutdownChunk->dup());
1156  msg->addChunk(shutdownChunk);
1157  sendToIP(msg, remoteAddr);
1159 }
#define SCTP_TIMEOUT_INIT_REXMIT
Definition: SCTPAssociation.h:246
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
Definition: SCTPAssociation.h:118
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
bool typeInChunkList(const uint16 type)
Definition: SCTPAssociationAddIP.cc:285
#define SCTP_SHUTDOWN_CHUNK_LENGTH
Definition: SCTPAssociation.h:221
SCTPAuthenticationChunk * createAuthChunk()
Definition: SCTPAssociationAddIP.cc:218
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
cMessage * T5_ShutdownGuardTimer
Definition: SCTPAssociation.h:921
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
bool auth
Definition: SCTPAssociation.h:822
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
#define SHUTDOWN_GUARD_TIMEOUT
Definition: SCTPAssociation.h:265
simtime_t initRexmitTimeout
Definition: SCTPAssociation.h:650
int16 initRetransCounter
Counter for init and cookie retransmissions.
Definition: SCTPAssociation.h:649
SCTPGapList gapList
Definition: SCTPAssociation.h:619
L3Address remoteAddr
Definition: SCTPAssociation.h:911
Definition: SCTPAssociation.h:86
AssocStatMap assocStatMap
Definition: SCTP.h:171
cMessage * T2_ShutdownTimer
Definition: SCTPAssociation.h:920
int32 assocId
Definition: SCTPAssociation.h:908
bool peerAuth
Definition: SCTPAssociation.h:821
SCTPShutdownChunk * shutdownChunk
pointer to the resetChunk (for retransmission)
Definition: SCTPAssociation.h:656
uint16 localPort
Definition: SCTPAssociation.h:913
uint32 getCumAckTSN() const
Definition: SCTPGapList.h:91
bool performStateTransition(const SCTPEventCode &event)
Implemements the pure SCTP state machine.
Definition: SCTPAssociationBase.cc:1182
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendShutdownAck ( const L3Address dest)
protected

Referenced by process_CLOSE(), and process_RCV_Message().

1058 {
1059  sendOnAllPaths(getPath(dest));
1060  if (getOutstandingBytes() == 0) {
1062  SCTPMessage *sctpshutdownack = new SCTPMessage();
1063  sctpshutdownack->setByteLength(SCTP_COMMON_HEADER);
1064 
1065  EV_INFO << "SCTPAssociationUtil:sendShutdownACK" << endl;
1066 
1067  sctpshutdownack->setSrcPort(localPort);
1068  sctpshutdownack->setDestPort(remotePort);
1069  SCTPShutdownAckChunk *shutdownAckChunk = new SCTPShutdownAckChunk("SHUTDOWN_ACK");
1070  shutdownAckChunk->setChunkType(SHUTDOWN_ACK);
1071  shutdownAckChunk->setByteLength(SCTP_COOKIE_ACK_LENGTH);
1072  sctpshutdownack->addChunk(shutdownAckChunk);
1079  state->shutdownAckChunk = check_and_cast<SCTPShutdownAckChunk *>(shutdownAckChunk->dup());
1080  sendToIP(sctpshutdownack, dest);
1081  }
1082 }
#define SCTP_TIMEOUT_INIT_REXMIT
Definition: SCTPAssociation.h:246
#define SCTP_COOKIE_ACK_LENGTH
Definition: SCTPAssociation.h:219
int32 getOutstandingBytes() const
Definition: SCTPAssociationUtil.cc:2721
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
Definition: SCTPAssociation.h:119
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
cMessage * T5_ShutdownGuardTimer
Definition: SCTPAssociation.h:921
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
SCTPShutdownAckChunk * shutdownAckChunk
Definition: SCTPAssociation.h:657
uint16 remotePort
Definition: SCTPAssociation.h:914
#define SHUTDOWN_GUARD_TIMEOUT
Definition: SCTPAssociation.h:265
simtime_t initRexmitTimeout
Definition: SCTPAssociation.h:650
int16 initRetransCounter
Counter for init and cookie retransmissions.
Definition: SCTPAssociation.h:649
Definition: SCTPAssociation.h:86
cMessage * T2_ShutdownTimer
Definition: SCTPAssociation.h:920
uint16 localPort
Definition: SCTPAssociation.h:913
bool performStateTransition(const SCTPEventCode &event)
Implemements the pure SCTP state machine.
Definition: SCTPAssociationBase.cc:1182
void sendOnAllPaths(SCTPPathVariables *firstPath)
Definition: SCTPAssociationSendAll.cc:275
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendShutdownComplete ( )
protected

Referenced by process_RCV_Message().

1085 {
1086  SCTPMessage *sctpshutdowncomplete = new SCTPMessage();
1087  sctpshutdowncomplete->setByteLength(SCTP_COMMON_HEADER);
1088 
1089  EV_INFO << "SCTPAssociationUtil:sendShutdownComplete\n";
1090 
1091  sctpshutdowncomplete->setSrcPort(localPort);
1092  sctpshutdowncomplete->setDestPort(remotePort);
1093  SCTPShutdownCompleteChunk *shutdownCompleteChunk = new SCTPShutdownCompleteChunk("SHUTDOWN_COMPLETE");
1094  shutdownCompleteChunk->setChunkType(SHUTDOWN_COMPLETE);
1095  shutdownCompleteChunk->setTBit(0);
1096  shutdownCompleteChunk->setByteLength(SCTP_SHUTDOWN_ACK_LENGTH);
1097  sctpshutdowncomplete->addChunk(shutdownCompleteChunk);
1098  sendToIP(sctpshutdowncomplete);
1099 }
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
uint16 remotePort
Definition: SCTPAssociation.h:914
#define SCTP_SHUTDOWN_ACK_LENGTH
Definition: SCTPAssociation.h:222
uint16 localPort
Definition: SCTPAssociation.h:913
Definition: SCTPAssociation.h:123
bool inet::sctp::SCTPAssociation::sendStreamPresent ( uint16  sid)
protected

Referenced by processIncomingResetRequestArrived().

892 {
893  auto iterator = sendStreams.find(id);
894  if (iterator == sendStreams.end())
895  return false;
896  else
897  return true;
898 }
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
void inet::sctp::SCTPAssociation::sendStreamResetRequest ( SCTPResetInfo info)
protected

Referenced by checkStreamsToReset(), process_STREAM_RESET(), and sendOnAllPaths().

484 {
485  EV_INFO << "StreamReset:sendStreamResetRequest\n";
486  SCTPParameter *param;
487  uint16 type;
488  SCTPMessage *msg = new SCTPMessage();
489  msg->setByteLength(SCTP_COMMON_HEADER);
490  msg->setSrcPort(localPort);
491  msg->setDestPort(remotePort);
492  SCTPStreamResetChunk *resetChunk = new SCTPStreamResetChunk("myRE_CONFIG");
493  resetChunk->setChunkType(RE_CONFIG);
494  resetChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
496  SCTPResetTimer *rt = new SCTPResetTimer();
497  auto it = sctpMain->assocStatMap.find(assocId);
498  if (rinfo)
499  type = rinfo->getRequestType();
500  else
501  type = state->localRequestType;
502  switch (type) {
503  case RESET_OUTGOING:
504  EV_INFO << "RESET_OUTGOING\n";
505  state->requests[srsn].result = 100;
507  state->requests[srsn].sn = srsn;
508  param = makeOutgoingStreamResetParameter(srsn, rinfo);
509  resetChunk->addParameter(param);
510  rt->setInSN(0);
511  rt->setInAcked(true);
512  rt->setOutSN(srsn);
513  rt->setOutAcked(false);
514  it->second.numResetRequestsSent++;
516 
517  state->waitForResponse = true;
518  state->resetRequested = true;
519  break;
520 
521  case RESET_INCOMING:
522  state->requests[srsn].result = 100;
524  state->requests[srsn].sn = srsn;
525  param = makeIncomingStreamResetParameter(srsn, rinfo);
526  resetChunk->addParameter(param);
527  rt->setInSN(srsn);
528  rt->setInAcked(false);
529  rt->setOutSN(0);
530  rt->setOutAcked(true);
531  it->second.numResetRequestsSent++;
533  state->waitForResponse = true;
534  break;
535 
536  case RESET_BOTH:
537  SCTPParameter *outParam;
538  state->requests[srsn].result = 100;
540  state->requests[srsn].sn = srsn;
541  outParam = makeOutgoingStreamResetParameter(srsn, rinfo);
542  rt->setOutSN(srsn++);
543  rt->setOutAcked(false);
544  resetChunk->addParameter(outParam);
545  state->requests[srsn].result = 100;
547  state->requests[srsn].sn = srsn;
548  SCTPParameter *inParam;
549  inParam = makeIncomingStreamResetParameter(srsn, rinfo);
550  resetChunk->addParameter(inParam);
551  rt->setInSN(srsn);
552  rt->setInAcked(false);
553  it->second.numResetRequestsSent += 2;
554  state->numResetRequests += 2;
555  state->waitForResponse = true;
556  break;
557 
558  case SSN_TSN:
559  param = makeSSNTSNResetParameter(srsn);
560  resetChunk->addParameter(param);
561  rt->setInSN(srsn);
562  rt->setInAcked(false);
563  rt->setOutSN(srsn);
564  rt->setOutAcked(false);
565  state->requests[srsn].result = 100;
567  it->second.numResetRequestsSent++;
569  break;
570 
571  case ADD_INCOMING:
572  case ADD_OUTGOING:
573  state->requests[srsn].result = 100;
574  param = makeAddStreamsRequestParameter(srsn, rinfo);
575  resetChunk->addParameter(param);
576  rt->setInSN(srsn);
577  rt->setInAcked(false);
578  rt->setOutSN(0);
579  rt->setOutAcked(true);
580  it->second.numResetRequestsSent++;
582  break;
583  default: printf("Request type %d not known\n", type);
584 
585  }
587  if (state->resetChunk != nullptr) {
588  state->resetChunk->setName("deletedStateReSetChunk");
589  delete state->resetChunk;
590  state->resetChunk = nullptr;
591  }
592  state->resetChunk = check_and_cast<SCTPStreamResetChunk *>(resetChunk->dup());
593  state->resetChunk->setName("stateReSetChunk");
594  msg->addChunk(resetChunk);
595  if (qCounter.roomSumSendStreams != 0) {
596  storePacket(getPath(remoteAddr), msg, 1, 0, false);
597  state->bundleReset = true;
598  rt->setName("bundleReset");
599  sendOnPath(getPath(remoteAddr), true);
600  state->bundleReset = false;
601  } else {
602  sendToIP(msg, remoteAddr);
603  }
604  if (PK(getPath(remoteAddr)->ResetTimer)->hasEncapsulatedPacket()) {
605  PK(getPath(remoteAddr)->ResetTimer)->decapsulate();
606  }
607  PK(getPath(remoteAddr)->ResetTimer)->encapsulate(rt);
608  if (getPath(remoteAddr)->ResetTimer->isScheduled()) {
609  stopTimer(getPath(remoteAddr)->ResetTimer);
610  }
611  startTimer(getPath(remoteAddr)->ResetTimer, getPath(remoteAddr)->pathRto);
612 }
std::map< uint32, RequestData > requests
Definition: SCTPAssociation.h:806
uint32 streamResetSequenceNumber
Definition: SCTPAssociation.h:793
bool resetRequested
Definition: SCTPAssociation.h:590
Definition: SCTPAssociation.h:155
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
bool bundleReset
Definition: SCTPAssociation.h:788
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
uint16 localRequestType
Definition: SCTPAssociation.h:810
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
bool waitForResponse
Definition: SCTPAssociation.h:789
void storePacket(SCTPPathVariables *pathVar, SCTPMessage *sctpMsg, const uint16 chunksAdded, const uint16 dataChunksAdded, const bool authAdded)
Definition: SCTPAssociationSendAll.cc:55
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
Definition: SCTPAssociation.h:150
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
Definition: SCTPAssociation.h:156
Definition: SCTPAssociation.h:128
L3Address remoteAddr
Definition: SCTPAssociation.h:911
AssocStatMap assocStatMap
Definition: SCTP.h:171
Definition: SCTPAssociation.h:152
Definition: SCTPAssociation.h:151
QueueCounter qCounter
Definition: SCTPAssociation.h:965
SCTPStreamResetChunk * resetChunk
Definition: SCTPAssociation.h:799
IRoutingTable * rt
Definition: SCTPAssociation.h:936
uint16 numResetRequests
Definition: SCTPAssociation.h:644
Definition: SCTPAssociation.h:157
SCTPParameter * makeOutgoingStreamResetParameter(uint32 srsn, SCTPResetInfo *info)
Definition: SCTPAssociationStreamReset.cc:298
uint32_t uint32
Definition: Compat.h:30
Definition: SCTPAssociation.h:158
Definition: SCTPAssociation.h:153
#define PK(msg)
Definition: INETDefs.h:92
int32 assocId
Definition: SCTPAssociation.h:908
SCTPParameter * makeAddStreamsRequestParameter(uint32 srsn, SCTPResetInfo *info)
Definition: SCTPAssociationStreamReset.cc:351
uint16_t uint16
Definition: Compat.h:32
SCTPParameter * makeSSNTSNResetParameter(uint32 srsn)
Definition: SCTPAssociationStreamReset.cc:372
Definition: SCTPAssociation.h:154
uint16 localPort
Definition: SCTPAssociation.h:913
void sendOnPath(SCTPPathVariables *pathId, const bool firstPass=true)
Utility: Send data from sendQueue.
Definition: SCTPAssociationSendAll.cc:668
SCTPParameter * makeIncomingStreamResetParameter(uint32 srsn, SCTPResetInfo *info)
Definition: SCTPAssociationStreamReset.cc:332
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendStreamResetResponse ( uint32  srrsn,
int  result 
)
protected

Referenced by checkStreamsToReset(), process_RCV_Message(), processIncomingResetRequestArrived(), processOutAndResponseArrived(), processOutgoingResetRequestArrived(), processSSNTSNResetRequestArrived(), and processStreamResetArrived().

764 {
765  SCTPStreamResetChunk *resetChunk;
766  EV_INFO << "sendStreamResetResponse to " << remoteAddr << "\n";
767  SCTPMessage *msg = new SCTPMessage();
768  msg->setByteLength(SCTP_COMMON_HEADER);
769  msg->setSrcPort(localPort);
770  msg->setDestPort(remotePort);
771  resetChunk = new SCTPStreamResetChunk("responseRE_CONFIG");
772  resetChunk->setChunkType(RE_CONFIG);
773  resetChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
774  SCTPStreamResetResponseParameter *responseParam = new SCTPStreamResetResponseParameter("Response_Param");
775  responseParam->setParameterType(STREAM_RESET_RESPONSE_PARAMETER);
776  responseParam->setSrResSn(srrsn);
777  responseParam->setResult(result);
778  state->peerRequests[srrsn].result = result;
779  responseParam->setByteLength(SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH);
780  resetChunk->addParameter(responseParam);
781  msg->addChunk(resetChunk);
782  if (qCounter.roomSumSendStreams != 0) {
783  storePacket(getPath(remoteAddr), msg, 1, 0, false);
784  state->bundleReset = true;
785  sendOnPath(getPath(remoteAddr), true);
786  state->bundleReset = false;
787  } else {
788  msg->addChunk(createSack());
790  state->ackState = 0;
791  state->sackAlreadySent = true;
792  if (state->incomingRequestSet && state->incomingRequest != nullptr) {
793  delete state->incomingRequest;
794  state->incomingRequest = nullptr;
795  state->incomingRequestSet = false;
796  }
797  sendToIP(msg, remoteAddr);
798  }
799  if (result != DEFERRED) {
800  state->resetRequested = false;
801  state->firstPeerRequest = false;
802  }
803 }
bool resetRequested
Definition: SCTPAssociation.h:590
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
bool bundleReset
Definition: SCTPAssociation.h:788
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
bool firstPeerRequest
Definition: SCTPAssociation.h:790
Definition: SCTPAssociation.h:159
void storePacket(SCTPPathVariables *pathVar, SCTPMessage *sctpMsg, const uint16 chunksAdded, const uint16 dataChunksAdded, const bool authAdded)
Definition: SCTPAssociationSendAll.cc:55
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
bool sackAlreadySent
Definition: SCTPAssociation.h:587
std::map< uint32, RequestData > peerRequests
Definition: SCTPAssociation.h:807
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
cMessage * SackTimer
Definition: SCTPAssociation.h:922
uint16 remotePort
Definition: SCTPAssociation.h:914
#define SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH
Definition: SCTPAssociation.h:228
uint32 ackState
Definition: SCTPAssociation.h:618
Definition: SCTPAssociation.h:128
L3Address remoteAddr
Definition: SCTPAssociation.h:911
Definition: SCTPAssociation.h:149
QueueCounter qCounter
Definition: SCTPAssociation.h:965
SCTPParameter * incomingRequest
Definition: SCTPAssociation.h:800
uint16 localPort
Definition: SCTPAssociation.h:913
void sendOnPath(SCTPPathVariables *pathId, const bool firstPass=true)
Utility: Send data from sendQueue.
Definition: SCTPAssociationSendAll.cc:668
SCTPSackChunk * createSack()
Definition: SCTPAssociationUtil.cc:1473
bool incomingRequestSet
Definition: SCTPAssociation.h:602
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendStreamResetResponse ( SCTPSSNTSNResetRequestParameter requestParam,
int  result,
bool  options 
)
protected
721 {
722  uint32 len = 0;
723  EV_INFO << "sendStreamResetResponse to " << remoteAddr << " with options\n";
724  SCTPMessage *msg = new SCTPMessage();
725  msg->setByteLength(SCTP_COMMON_HEADER);
726  msg->setSrcPort(localPort);
727  msg->setDestPort(remotePort);
728  SCTPStreamResetChunk *resetChunk = new SCTPStreamResetChunk("STREAM_RESET");
729  resetChunk->setChunkType(RE_CONFIG);
730  resetChunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
731  SCTPStreamResetResponseParameter *responseParam = new SCTPStreamResetResponseParameter("Response_Param");
732  responseParam->setParameterType(STREAM_RESET_RESPONSE_PARAMETER);
733  responseParam->setSrResSn(requestParam->getSrReqSn());
734  responseParam->setResult(result);
735  state->peerRequests[requestParam->getSrReqSn()].result = result;
737  if (options && result == PERFORMED) {
738  responseParam->setSendersNextTsn(state->nextTSN);
739  responseParam->setReceiversNextTsn(state->gapList.getHighestTSNReceived() + (1<<31) + 1);
740  resetSsns();
742  state->stopOldData = true;
743  if (state->incomingRequestSet && state->incomingRequest != nullptr) {
744  delete state->incomingRequest;
745  state->incomingRequest = nullptr;
746  state->incomingRequestSet = false;
747  }
748  len += 8;
749  resetGapLists();
751  state->firstPeerRequest = false;
752  }
753  responseParam->setByteLength(len);
754  resetChunk->addParameter(responseParam);
755  msg->addChunk(resetChunk);
757  msg->addChunk(createSack());
758  state->ackState = 0;
759  state->sackAlreadySent = true;
760  sendToIP(msg);
761 }
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
void resetExpectedSsns()
Definition: SCTPAssociationStreamReset.cc:845
uint16_t len
Definition: TCP_NSC.cc:85
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
bool firstPeerRequest
Definition: SCTPAssociation.h:790
Definition: SCTPAssociation.h:159
bool sackAlreadySent
Definition: SCTPAssociation.h:587
std::map< uint32, RequestData > peerRequests
Definition: SCTPAssociation.h:807
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
cMessage * SackTimer
Definition: SCTPAssociation.h:922
uint16 remotePort
Definition: SCTPAssociation.h:914
#define SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH
Definition: SCTPAssociation.h:228
uint32 ackState
Definition: SCTPAssociation.h:618
Definition: SCTPAssociation.h:128
SCTPGapList gapList
Definition: SCTPAssociation.h:619
L3Address remoteAddr
Definition: SCTPAssociation.h:911
uint32_t uint32
Definition: Compat.h:30
SCTPParameter * incomingRequest
Definition: SCTPAssociation.h:800
uint32 getHighestTSNReceived() const
Definition: SCTPGapList.h:96
void resetGapLists()
Definition: SCTPAssociationStreamReset.cc:714
bool stopOldData
Definition: SCTPAssociation.h:592
uint32 nextTSN
Definition: SCTPAssociation.h:613
Definition: SCTPAssociation.h:144
uint16 localPort
Definition: SCTPAssociation.h:913
void resetSsns()
Methods for Stream Reset.
Definition: SCTPAssociationStreamReset.cc:876
SCTPSackChunk * createSack()
Definition: SCTPAssociationUtil.cc:1473
bool incomingRequestSet
Definition: SCTPAssociation.h:602
uint32 peerTsnAfterReset
Definition: SCTPAssociation.h:797
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::sendToApp ( cMessage *  msg)
protected

Utility: sends packet to application.

Referenced by pathStatusIndication(), process_STATUS(), pushUlp(), and sendDataArrivedNotification().

458 {
459  sctpMain->send(msg, "to_appl", appGateIndex);
460 }
SCTP * sctpMain
Definition: SCTPAssociation.h:962
int32 appGateIndex
Definition: SCTPAssociation.h:907
void inet::sctp::SCTPAssociation::sendToIP ( SCTPMessage sctpmsg,
const L3Address dest 
)
protected

Utility: adds control info to message and sends it to IP.

Referenced by processAddInAndOutResetRequestArrived(), processAsconfArrived(), retransmitAsconf(), retransmitCookieEcho(), retransmitInit(), retransmitReset(), retransmitShutdown(), retransmitShutdownAck(), sendAbort(), sendAddInAndOutStreamsRequest(), sendAddOutgoingStreamsRequest(), sendAsconf(), sendAsconfAck(), sendBundledOutgoingResetAndResponse(), sendCookieAck(), sendCookieEcho(), sendDoubleStreamResetResponse(), sendHeartbeat(), sendHeartbeatAck(), sendInit(), sendInitAck(), sendOnPath(), sendOutgoingRequestAndResponse(), sendOutgoingResetRequest(), sendPacketDrop(), sendSACKviaSelectedPath(), sendShutdown(), sendShutdownAck(), sendShutdownComplete(), sendStreamResetRequest(), and sendStreamResetResponse().

359 {
360  // Final touches on the segment before sending
361  sctpmsg->setSrcPort(localPort);
362  sctpmsg->setDestPort(remotePort);
363  sctpmsg->setChecksumOk(true);
364  EV_INFO << "SendToIP: localPort=" << localPort << " remotePort=" << remotePort << " dest=" << dest << "\n";
365  const SCTPChunk *chunk = (const SCTPChunk *)(sctpmsg->peekFirstChunk());
366  uint8 chunkType = chunk->getChunkType();
367  if (chunkType == ABORT) {
368  const SCTPAbortChunk *abortChunk = check_and_cast<const SCTPAbortChunk *>(chunk);
369  if (abortChunk->getT_Bit() == 1) {
370  sctpmsg->setTag(peerVTag);
371  }
372  else {
373  sctpmsg->setTag(localVTag);
374  }
375  }
376  else if (sctpmsg->getTag() == 0) {
377  sctpmsg->setTag(localVTag);
378  }
379 
380  if ((bool)sctpMain->par("udpEncapsEnabled")) {
382  }
383  else {
384  IL3AddressType *addressType = dest.getAddressType();
385  INetworkProtocolControlInfo *controlInfo = addressType->createNetworkProtocolControlInfo();
386  controlInfo->setTransportProtocol(IP_PROT_SCTP);
387  //controlInfo->setSourceAddress();
388  controlInfo->setDestinationAddress(dest);
389  sctpmsg->setControlInfo(check_and_cast<cObject *>(controlInfo));
390  sctpMain->send_to_ip(sctpmsg);
391 
392  if (chunkType == HEARTBEAT) {
393  SCTPPathVariables *path = getPath(dest);
394  path->numberOfHeartbeatsSent++;
395  path->vectorPathHb->record(path->numberOfHeartbeatsSent);
396  }
397  else if (chunkType == HEARTBEAT_ACK) {
398  SCTPPathVariables *path = getPath(dest);
399  path->numberOfHeartbeatAcksSent++;
400  path->vectorPathHbAck->record(path->numberOfHeartbeatAcksSent);
401  }
402  }
403  EV_INFO << "Sent to " << dest << endl;
404 }
uint8_t uint8
Definition: Compat.h:34
uint32 localVTag
Definition: SCTPAssociation.h:915
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
Definition: SCTPAssociation.h:115
Definition: SCTPAssociation.h:116
SCTPPathVariables * getPath(const L3Address &pathId) const
Definition: SCTPAssociation.h:1055
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
virtual void send_to_ip(SCTPMessage *msg)
Definition: SCTP.cc:390
uint32 peerVTag
Definition: SCTPAssociation.h:916
L3Address remoteAddr
Definition: SCTPAssociation.h:911
#define SCTP_UDP_PORT
Definition: SCTP.h:41
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
Definition: SCTPAssociation.h:117
uint16 localPort
Definition: SCTPAssociation.h:913
Definition: IPProtocolId_m.h:91
void inet::sctp::SCTPAssociation::sendToIP ( SCTPMessage sctpmsg)
inlineprotected
1179  {
1180  sendToIP(sctpmsg, remoteAddr);
1181  }
void sendToIP(SCTPMessage *sctpmsg, const L3Address &dest)
Utility: adds control info to message and sends it to IP.
Definition: SCTPAssociationUtil.cc:357
L3Address remoteAddr
Definition: SCTPAssociation.h:911
void inet::sctp::SCTPAssociation::setFragInProgressOfStream ( uint16  sid,
bool  frag 
)
protected

Referenced by sendOnPath().

108 {
109  auto streamIterator = sendStreams.find(sid);
110  assert(streamIterator != sendStreams.end());
111  return (streamIterator->second)->setFragInProgress(frag);
112 }
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
void inet::sctp::SCTPAssociation::signalConnectionTimeout ( )
protected

Utility: signal to user that connection timed out.

407 {
409 }
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
Definition: SCTPCommand.h:70
static int16 inet::sctp::SCTPAssociation::ssnGt ( const uint16  ssn1,
const uint16  ssn2 
)
inlinestatic

Referenced by makeRoomForTsn().

1085 { return SCTP_SSN_GT(ssn1, ssn2); }
#define SCTP_SSN_GT(a, b)
Definition: SCTPAssociation.h:1078
void inet::sctp::SCTPAssociation::startTimer ( cMessage *  timer,
const simtime_t &  timeout 
)
protected
void inet::sctp::SCTPAssociation::stateEntered ( int32  state)
protected
1424 {
1425  switch (status) {
1426  case SCTP_S_COOKIE_WAIT:
1427  break;
1428 
1429  case SCTP_S_ESTABLISHED: {
1430  EV_INFO << "State ESTABLISHED entered" << endl;
1432 
1433  if (state->initChunk) {
1434  delete state->initChunk;
1435  state->initChunk = nullptr;
1436  }
1437 
1438  state->nagleEnabled = (bool)sctpMain->getNagle();
1440  state->sendHeartbeatsOnActivePaths = (bool)sctpMain->par("sendHeartbeatsOnActivePaths");
1441  state->numGapReports = sctpMain->par("numGapReports");
1443  state->rtxMethod = sctpMain->par("RTXMethod");
1444  state->nrSack = (bool)sctpMain->par("nrSack");
1445  state->disableReneging = (bool)sctpMain->par("disableReneging");
1446  state->checkSackSeqNumber = (bool)sctpMain->par("checkSackSeqNumber");
1450  state->highSpeedCC = (bool)sctpMain->par("highSpeedCC");
1451  state->initialWindow = (uint32)sctpMain->par("initialWindow");
1452  if (strcmp((const char *)sctpMain->par("maxBurstVariant"), "useItOrLoseIt") == 0) {
1454  }
1455  else if (strcmp((const char *)sctpMain->par("maxBurstVariant"), "congestionWindowLimiting") == 0) {
1457  }
1458  else if (strcmp((const char *)sctpMain->par("maxBurstVariant"), "maxBurst") == 0) {
1460  }
1461  else if (strcmp((const char *)sctpMain->par("maxBurstVariant"), "aggressiveMaxBurst") == 0) {
1463  }
1464  else if (strcmp((const char *)sctpMain->par("maxBurstVariant"), "totalMaxBurst") == 0) {
1466  }
1467  else if (strcmp((const char *)sctpMain->par("maxBurstVariant"), "useItOrLoseItTempCwnd") == 0) {
1469  }
1470  else if (strcmp((const char *)sctpMain->par("maxBurstVariant"), "congestionWindowLimitingTempCwnd") == 0) {
1472  }
1473  else {
1474  throw cRuntimeError("Invalid setting of maxBurstVariant: %s.",
1475  (const char *)sctpMain->par("maxBurstVariant"));
1476  }
1477 
1478  if (strcmp((const char *)sctpMain->par("cmtSendAllVariant"), "normal") == 0) {
1480  }
1481  else if (strcmp((const char *)sctpMain->par("cmtSendAllVariant"), "smallestLastTransmission") == 0) {
1483  }
1484  else if (strcmp((const char *)sctpMain->par("cmtSendAllVariant"), "randomized") == 0) {
1486  }
1487  else if (strcmp((const char *)sctpMain->par("cmtSendAllVariant"), "largestSSThreshold") == 0) {
1489  }
1490  else if (strcmp((const char *)sctpMain->par("cmtSendAllVariant"), "largestSpace") == 0) {
1492  }
1493  else if (strcmp((const char *)sctpMain->par("cmtSendAllVariant"), "largestSpaceAndSSThreshold") == 0) {
1495  }
1496  else {
1497  throw cRuntimeError("Invalid setting of cmtSendAllVariant: %s.",
1498  (const char *)sctpMain->par("cmtSendAllVariant"));
1499  }
1500 
1501  state->cmtRetransmissionVariant = sctpMain->par("cmtRetransmissionVariant");
1502  if (strcmp((const char *)sctpMain->par("cmtCUCVariant"), "normal") == 0) {
1504  }
1505  else if (strcmp((const char *)sctpMain->par("cmtCUCVariant"), "pseudoCumAck") == 0) {
1507  }
1508  else if (strcmp((const char *)sctpMain->par("cmtCUCVariant"), "pseudoCumAckV2") == 0) {
1510  }
1511  else {
1512  throw cRuntimeError("Bad setting for cmtCUCVariant: %s\n",
1513  (const char *)sctpMain->par("cmtCUCVariant"));
1514  }
1515  state->smartOverfullSACKHandling = (bool)sctpMain->par("smartOverfullSACKHandling");
1516 
1517  if (strcmp((const char *)sctpMain->par("cmtChunkReschedulingVariant"), "none") == 0) {
1519  }
1520  else if (strcmp((const char *)sctpMain->par("cmtChunkReschedulingVariant"), "senderOnly") == 0) {
1522  }
1523  else if (strcmp((const char *)sctpMain->par("cmtChunkReschedulingVariant"), "receiverOnly") == 0) {
1525  }
1526  else if (strcmp((const char *)sctpMain->par("cmtChunkReschedulingVariant"), "bothSides") == 0) {
1528  }
1529  else if (strcmp((const char *)sctpMain->par("cmtChunkReschedulingVariant"), "test") == 0) {
1531  }
1532  else {
1533  throw cRuntimeError("Bad setting for cmtChunkReschedulingVariant: %s\n",
1534  (const char *)sctpMain->par("cmtChunkReschedulingVariant"));
1535  }
1536 
1537  if (strcmp((const char *)sctpMain->par("cmtBufferSplitVariant"), "none") == 0) {
1539  }
1540  else if (strcmp((const char *)sctpMain->par("cmtBufferSplitVariant"), "senderOnly") == 0) {
1542  }
1543  else if (strcmp((const char *)sctpMain->par("cmtBufferSplitVariant"), "receiverOnly") == 0) {
1545  }
1546  else if (strcmp((const char *)sctpMain->par("cmtBufferSplitVariant"), "bothSides") == 0) {
1548  }
1549  else {
1550  throw cRuntimeError("Bad setting for cmtBufferSplitVariant: %s\n",
1551  (const char *)sctpMain->par("cmtBufferSplitVariant"));
1552  }
1553  state->cmtBufferSplittingUsesOSB = (bool)sctpMain->par("cmtBufferSplittingUsesOSB");
1554 
1555  if (strcmp((const char *)sctpMain->par("gapListOptimizationVariant"), "none") == 0) {
1557  }
1558  else if (strcmp((const char *)sctpMain->par("gapListOptimizationVariant"), "optimized1") == 0) {
1560  }
1561  else if (strcmp((const char *)sctpMain->par("gapListOptimizationVariant"), "optimized2") == 0) {
1563  }
1564  else if (strcmp((const char *)sctpMain->par("gapListOptimizationVariant"), "shrunken") == 0) {
1566  }
1567  else {
1568  throw cRuntimeError("Bad setting for gapListOptimizationVariant: %s\n",
1569  (const char *)sctpMain->par("gapListOptimizationVariant"));
1570  }
1571 
1572  state->cmtUseSFR = (bool)sctpMain->par("cmtUseSFR");
1573  state->cmtUseDAC = (bool)sctpMain->par("cmtUseDAC");
1574  state->cmtUseFRC = (bool)sctpMain->par("cmtUseFRC");
1575  state->gapReportLimit = (uint32)sctpMain->par("gapReportLimit");
1576  state->cmtSmartT3Reset = (bool)sctpMain->par("cmtSmartT3Reset");
1577  state->cmtSmartReneging = (bool)sctpMain->par("cmtSmartReneging");
1578  state->cmtSmartFastRTX = (bool)sctpMain->par("cmtSmartFastRTX");
1579  state->cmtSlowPathRTTUpdate = (bool)sctpMain->par("cmtSlowPathRTTUpdate");
1580  state->cmtMovedChunksReduceCwnd = (bool)sctpMain->par("cmtMovedChunksReduceCwnd");
1581  state->cmtChunkReschedulingThreshold = (double)sctpMain->par("cmtChunkReschedulingThreshold");
1582  state->movedChunkFastRTXFactor = (double)sctpMain->par("movedChunkFastRTXFactor");
1583  state->strictCwndBooking = (bool)sctpMain->par("strictCwndBooking");
1584 
1585  if (strcmp((const char *)sctpMain->par("cmtSackPath"), "standard") == 0) {
1587  }
1588  else if (strcmp((const char *)sctpMain->par("cmtSackPath"), "primary") == 0) {
1590  }
1591  else if (strcmp((const char *)sctpMain->par("cmtSackPath"), "roundRobin") == 0) {
1593  }
1594  else if (strcmp((const char *)sctpMain->par("cmtSackPath"), "smallestSRTT") == 0) {
1596  }
1597  else {
1598  throw cRuntimeError("Bad setting for cmtSackPath: %s\n",
1599  (const char *)sctpMain->par("cmtSackPath"));
1600  }
1601 
1602  if (strcmp((const char *)sctpMain->par("cmtCCVariant"), "off") == 0) {
1604  state->allowCMT = false;
1605  }
1606  else if (strcmp((const char *)sctpMain->par("cmtCCVariant"), "cmt") == 0) {
1608  state->allowCMT = true;
1609  }
1610  else if(strcmp((const char*)sctpMain->par("cmtCCVariant"), "lia") == 0){
1612  state->allowCMT = true;
1613  }
1614  else if(strcmp((const char*)sctpMain->par("cmtCCVariant"), "olia") == 0){
1616  state->allowCMT = true;
1617  }
1618  else if ((strcmp((const char *)sctpMain->par("cmtCCVariant"), "cmtrp") == 0) ||
1619  (strcmp((const char *)sctpMain->par("cmtCCVariant"), "cmtrpv1") == 0))
1620  {
1622  state->allowCMT = true;
1623  }
1624  else if (strcmp((const char *)sctpMain->par("cmtCCVariant"), "cmtrpv2") == 0) {
1626  state->allowCMT = true;
1627  }
1628  else if (strcmp((const char *)sctpMain->par("cmtCCVariant"), "cmtrp-t1") == 0) {
1630  state->allowCMT = true;
1631  }
1632  else if (strcmp((const char *)sctpMain->par("cmtCCVariant"), "cmtrp-t2") == 0) {
1634  state->allowCMT = true;
1635  }
1636  else {
1637  throw cRuntimeError("Bad setting for cmtCCVariant: %s\n",
1638  (const char *)sctpMain->par("cmtCCVariant"));
1639  }
1640 
1641  state->rpPathBlocking = (bool)sctpMain->par("rpPathBlocking");
1642  state->rpScaleBlockingTimeout = (bool)sctpMain->par("rpScaleBlockingTimeout");
1643  state->rpMinCwnd = sctpMain->par("rpMinCwnd");
1644 
1645  cStringTokenizer pathGroupsTokenizer(sctpMain->par("cmtCCPathGroups").stringValue());
1646  if (pathGroupsTokenizer.hasMoreTokens()) {
1647  auto pathIterator = sctpPathMap.begin();
1648  while (pathIterator != sctpPathMap.end()) {
1649  const char *token = pathGroupsTokenizer.nextToken();
1650  if (token == nullptr) {
1651  throw cRuntimeError("Too few cmtCCGroup values to cover all paths!");
1652  }
1653  SCTPPathVariables *path = pathIterator->second;
1654  path->cmtCCGroup = atol(token);
1655  pathIterator++;
1656  }
1657  }
1658 
1659  state->osbWithHeader = (bool)sctpMain->par("osbWithHeader");
1660  state->padding = (bool)sctpMain->par("padding");
1661  if (state->osbWithHeader)
1663  else
1664  state->header = 0;
1665  state->swsLimit = (uint32)sctpMain->par("swsLimit");
1666  state->fastRecoverySupported = (bool)sctpMain->par("fastRecoverySupported");
1667  state->reactivatePrimaryPath = (bool)sctpMain->par("reactivatePrimaryPath");
1669  state->auth = sctpMain->auth;
1670  state->messageAcceptLimit = sctpMain->par("messageAcceptLimit");
1671  state->bytesToAddPerRcvdChunk = sctpMain->par("bytesToAddPerRcvdChunk");
1672  state->bytesToAddPerPeerChunk = sctpMain->par("bytesToAddPerPeerChunk");
1673  state->tellArwnd = sctpMain->par("tellArwnd");
1674  state->throughputInterval = (double)sctpMain->par("throughputInterval");
1675  sackPeriod = (double)sctpMain->getSackPeriod();
1677  SCTP::AssocStat stat;
1678  stat.assocId = assocId;
1679  stat.start = simTime();
1680  stat.stop = 0;
1681  stat.rcvdBytes = 0;
1682  stat.ackedBytes = 0;
1683  stat.sentBytes = 0;
1684  stat.transmittedBytes = 0;
1685  stat.numFastRtx = 0;
1686  stat.numT3Rtx = 0;
1687  stat.numDups = 0;
1688  stat.numPathFailures = 0;
1689  stat.numForwardTsn = 0;
1690  stat.sumRGapRanges = 0;
1691  stat.sumNRGapRanges = 0;
1692  stat.numOverfullSACKs = 0;
1693  stat.lifeTime = 0;
1694  stat.throughput = 0;
1695  stat.numDropsBecauseNewTSNGreaterThanHighestTSN = 0;
1696  stat.numDropsBecauseNoRoomInBuffer = 0;
1697  stat.numChunksReneged = 0;
1698  stat.numAuthChunksSent = 0;
1699  stat.numAuthChunksAccepted = 0;
1700  stat.numAuthChunksRejected = 0;
1701  stat.numResetRequestsSent = 0;
1702  stat.numResetRequestsPerformed = 0;
1703  fairTimer = false;
1704  stat.fairStart = 0;
1705  stat.fairStop = 0;
1706  stat.fairLifeTime = 0;
1707  stat.fairThroughput = 0;
1708  stat.fairAckedBytes = 0;
1709  stat.numEndToEndMessages = 0;
1710  stat.cumEndToEndDelay = 0;
1711  stat.startEndToEndDelay = (uint32)sctpMain->par("startEndToEndDelay");
1712  stat.stopEndToEndDelay = (uint32)sctpMain->par("stopEndToEndDelay");
1713  sctpMain->assocStatMap[stat.assocId] = stat;
1714  ccModule = sctpMain->par("ccModule");
1715 
1716  switch (ccModule) {
1717  case RFC4960: {
1725  break;
1726  }
1727  }
1728 
1730  state->sendQueueLimit = (uint32)sctpMain->par("sendQueueLimit");
1732  if (sctpMain->hasPar("addIP")) {
1733  const bool addIP = (bool)sctpMain->par("addIP");
1734  EV_DETAIL << getFullPath() << ": addIP = " << addIP << " time = " << (double)sctpMain->par("addTime") << "\n";
1735  if (addIP == true && (double)sctpMain->par("addTime") > 0) {
1736  EV_DETAIL << "startTimer addTime to expire at " << simTime() + (double)sctpMain->par("addTime") << "\n";
1737 
1738  scheduleTimeout(StartAddIP, (double)sctpMain->par("addTime"));
1739  }
1740  }
1741  if ((double)sctpMain->par("fairStart") > 0) {
1742  sctpMain->scheduleAt(sctpMain->par("fairStart"), FairStartTimer);
1743  sctpMain->scheduleAt(sctpMain->par("fairStop"), FairStopTimer);
1744  sctpMain->recordScalar("rtoMin", (double)sctpMain->par("rtoMin"));
1745  }
1746  char str[128];
1747  snprintf(str, sizeof(str), "Cumulated TSN Ack of Association %d", assocId);
1748  cumTsnAck = new cOutVector(str);
1749  snprintf(str, sizeof(str), "Number of Gap Blocks in Last SACK of Association %d", assocId);
1750  numGapBlocks = new cOutVector(str);
1751  snprintf(str, sizeof(str), "SendQueue of Association %d", assocId);
1752  sendQueue = new cOutVector(str);
1753  state->sendQueueLimit = (uint32)sctpMain->par("sendQueueLimit");
1754  SCTP::VTagPair vtagPair;
1755  vtagPair.peerVTag = peerVTag;
1756  vtagPair.localVTag = localVTag;
1757  vtagPair.localPort = localPort;
1758  vtagPair.remotePort = remotePort;
1759  sctpMain->sctpVTagMap[assocId] = vtagPair;
1760  break;
1761  }
1762 
1763  case SCTP_S_CLOSED: {
1765  break;
1766  }
1767 
1768  case SCTP_S_SHUTDOWN_PENDING: {
1770  sendShutdown();
1771  break;
1772  }
1773 
1774  case SCTP_S_SHUTDOWN_RECEIVED: {
1775  EV_INFO << "Entered state SHUTDOWN_RECEIVED, osb=" << getOutstandingBytes()
1776  << ", transQ=" << transmissionQ->getQueueSize()
1777  << ", scount=" << qCounter.roomSumSendStreams << endl;
1778 
1781  }
1782  else {
1784  }
1785  break;
1786  }
1787  }
1788 }
uint64 sendQueueLimit
Definition: SCTPAssociation.h:659
Definition: SCTPAssociation.h:717
MBVariant maxBurstVariant
Definition: SCTPAssociation.h:702
bool smartOverfullSACKHandling
Definition: SCTPAssociation.h:686
bool sendHeartbeatsOnActivePaths
Definition: SCTPAssociation.h:667
double getSackPeriod()
Definition: SCTP.h:273
CUCVariant cmtCUCVariant
Definition: SCTPAssociation.h:714
bool cmtUseFRC
Definition: SCTPAssociation.h:741
Definition: SCTPAssociation.h:760
Definition: SCTPAssociation.h:718
uint16 ccModule
Definition: SCTPAssociation.h:952
uint32 sackFrequency
Definition: SCTPAssociation.h:949
Definition: SCTPAssociation.h:63
uint32 localVTag
Definition: SCTPAssociation.h:915
cMessage * FairStartTimer
Definition: SCTPAssociation.h:930
static bool pathMapLargestSpace(const SCTPPathVariables *left, const SCTPPathVariables *right)
Definition: SCTPAssociationSendAll.cc:165
int32 status
Definition: SCTPAssociation.h:946
bool rpScaleBlockingTimeout
Definition: SCTPAssociation.h:769
Definition: SCTPAssociation.h:682
Definition: SCTPAssociation.h:765
Definition: SCTPAssociation.h:730
int32 getOutstandingBytes() const
Definition: SCTPAssociationUtil.cc:2721
bool getEnableHeartbeats()
Definition: SCTP.h:277
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
void sendShutdown()
Definition: SCTPAssociationUtil.cc:1128
uint32 maxBurst
Definition: SCTPAssociation.h:692
Definition: SCTPAssociation.h:698
bool cmtMovedChunksReduceCwnd
Definition: SCTPAssociation.h:742
Definition: SCTPAssociation.h:759
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
Definition: SCTPCommand.h:67
bool cmtBufferSplittingUsesOSB
Definition: SCTPAssociation.h:723
Definition: SCTPAssociation.h:719
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
uint32 swsLimit
Definition: SCTPAssociation.h:664
Definition: SCTPAssociation.h:60
uint32 gapListOptimizationVariant
Definition: SCTPAssociation.h:685
cOutVector * sendQueue
Definition: SCTPAssociation.h:956
Definition: SCTPAssociation.h:710
Definition: SCTPAssociation.h:749
bool allowCMT
Definition: SCTPAssociation.h:705
Definition: SCTPAssociation.h:727
BufferSplitVariant cmtBufferSplitVariant
Definition: SCTPAssociation.h:722
uint32 fragPoint
Definition: SCTPAssociation.h:628
static bool pathMapLargestSSThreshold(const SCTPPathVariables *left, const SCTPPathVariables *right)
Definition: SCTPAssociationSendAll.cc:160
ChunkReschedulingVariant cmtChunkReschedulingVariant
Definition: SCTPAssociation.h:732
bool padding
Definition: SCTPAssociation.h:833
Definition: SCTPAssociation.h:58
bool checkSackSeqNumber
Definition: SCTPAssociation.h:773
bool nrSack
Definition: SCTPAssociation.h:677
uint32 initialWindow
Definition: SCTPAssociation.h:703
SCTPPathVariables * getPrimaryPath() const
Definition: SCTPAssociation.h:558
cMessage * FairStopTimer
Definition: SCTPAssociation.h:931
Definition: SCTPAssociation.h:700
bool fastRecoverySupported
Definition: SCTPAssociation.h:584
bool disableReneging
Definition: SCTPAssociation.h:687
void(SCTPAssociation::* ccUpdateAfterCwndTimeout)(SCTPPathVariables *path)
Definition: SCTPAssociation.h:893
Definition: SCTPAssociation.h:720
void(SCTPAssociation::* ccUpdateBeforeSack)()
Definition: SCTPAssociation.h:891
double cmtChunkReschedulingThreshold
Definition: SCTPAssociation.h:733
CCCVariant cmtCCVariant
Definition: SCTPAssociation.h:767
SCTPQueue * transmissionQ
Definition: SCTPAssociation.h:966
Definition: SCTPAssociation.h:728
Definition: SCTPAssociation.h:680
uint32 incomingSackSeqNum
Definition: SCTPAssociation.h:775
bool cmtUseDAC
Definition: SCTPAssociation.h:740
bool auth
Definition: SCTPAssociation.h:822
bool cmtSlowPathRTTUpdate
Definition: SCTPAssociation.h:738
uint16 remotePort
Definition: SCTPAssociation.h:914
SCTP * sctpMain
Definition: SCTPAssociation.h:962
bool osbWithHeader
Definition: SCTPAssociation.h:832
SCTPInitChunk * initChunk
pointer to the init chunk data structure (for retransmissions)
Definition: SCTPAssociation.h:652
bool nagleEnabled
Definition: SCTPAssociation.h:585
bool rpPathBlocking
Definition: SCTPAssociation.h:768
bool cmtSmartFastRTX
Definition: SCTPAssociation.h:736
int getMaxBurst()
Definition: SCTP.h:274
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
CCFunctions ccFunctions
Definition: SCTPAssociation.h:951
bool strictCwndBooking
Definition: SCTPAssociation.h:745
SctpVTagMap sctpVTagMap
Definition: SCTP.h:173
static bool pathMapLargestSpaceAndSSThreshold(const SCTPPathVariables *left, const SCTPPathVariables *right)
Definition: SCTPAssociationSendAll.cc:172
bool cmtUseSFR
Definition: SCTPAssociation.h:739
void(SCTPAssociation::* ccUpdateMaxBurst)(SCTPPathVariables *path)
Definition: SCTPAssociation.h:895
bool cmtSmartT3Reset
Definition: SCTPAssociation.h:735
uint32 peerVTag
Definition: SCTPAssociation.h:916
uint32 numGapReports
Definition: SCTPAssociation.h:603
void cwndUpdateBeforeSack()
Definition: SCTPCCFunctions.cc:140
L3Address remoteAddr
Definition: SCTPAssociation.h:911
uint32 outgoingSackSeqNum
Definition: SCTPAssociation.h:774
bool auth
Definition: SCTP.h:210
void(SCTPAssociation::* ccUpdateBytesAcked)(SCTPPathVariables *path, const uint32 ackedBytes, const bool ctsnaAdvanced)
Definition: SCTPAssociation.h:896
void pmStartPathManagement()
Flow control.
Definition: SCTPAssociationUtil.cc:2671
Definition: SCTPAssociation.h:726
uint32 packetsInTotalBurst
Definition: SCTPAssociation.h:620
Definition: SCTPAssociation.h:748
AssocStatMap assocStatMap
Definition: SCTP.h:171
Definition: SCTPAssociation.h:762
uint32 bytesToAddPerPeerChunk
Definition: SCTPAssociation.h:845
void(SCTPAssociation::* ccUpdateAfterRtxTimeout)(SCTPPathVariables *path)
Definition: SCTPAssociation.h:894
bool reactivatePrimaryPath
Definition: SCTPAssociation.h:588
static bool pathMapRandomized(const SCTPPathVariables *left, const SCTPPathVariables *right)
Definition: SCTPAssociationSendAll.cc:150
cOutVector * numGapBlocks
Definition: SCTPAssociation.h:957
const char * cmtRetransmissionVariant
Definition: SCTPAssociation.h:707
void initCCParameters(SCTPPathVariables *path)
SCTPCCFunctions.
Definition: SCTPCCFunctions.cc:399
QueueCounter qCounter
Definition: SCTPAssociation.h:965
static bool pathMapSmallestLastTransmission(const SCTPPathVariables *left, const SCTPPathVariables *right)
Definition: SCTPAssociationSendAll.cc:155
uint32 messageAcceptLimit
Definition: SCTPAssociation.h:639
uint32 rtxMethod
Definition: SCTPAssociation.h:690
void(SCTPAssociation::* ccInitParams)(SCTPPathVariables *path)
Definition: SCTPAssociation.h:890
void cwndUpdateBytesAcked(SCTPPathVariables *path, const uint32 ackedBytes, const bool ctsnaAdvanced)
Definition: SCTPCCFunctions.cc:607
double movedChunkFastRTXFactor
Definition: SCTPAssociation.h:743
bool fairTimer
Definition: SCTPAssociation.h:927
uint32_t uint32
Definition: Compat.h:30
void cwndUpdateMaxBurst(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:924
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
Definition: SCTPAssociation.h:747
uint32 bytesToAddPerRcvdChunk
Definition: SCTPAssociation.h:844
Definition: SCTPAssociation.h:694
Definition: SCTPAssociation.h:61
bool highSpeedCC
Definition: SCTPAssociation.h:754
int getFragPoint()
Definition: SCTP.h:275
uint16 header
Definition: SCTPAssociation.h:641
void(SCTPAssociation::* ccUpdateAfterSack)()
Definition: SCTPAssociation.h:892
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
int32 assocId
Definition: SCTPAssociation.h:908
Definition: SCTPAssociation.h:761
uint32 getQueueSize() const
Definition: SCTPQueue.cc:60
cMessage * StartAddIP
Definition: SCTPAssociation.h:924
Definition: SCTPAssociation.h:763
cOutVector * cumTsnAck
Definition: SCTPAssociation.h:955
Definition: SCTPAssociation.h:683
bool cmtSmartReneging
Definition: SCTPAssociation.h:737
bool enableHeartbeats
Definition: SCTPAssociation.h:666
Definition: SCTPAssociation.h:57
uint16 localPort
Definition: SCTPAssociation.h:913
uint32 gapReportLimit
Definition: SCTPAssociation.h:678
void cwndUpdateAfterCwndTimeout(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:980
void sendEstabIndicationToApp()
Utility: sends SCTP_I_ESTABLISHED indication with SCTPConnectInfo to application. ...
Definition: SCTPAssociationUtil.cc:429
int getNagle()
Definition: SCTP.h:276
Definition: SCTPAssociation.h:758
void cwndUpdateAfterSack()
Definition: SCTPCCFunctions.cc:435
Definition: SCTPAssociation.h:196
Definition: SCTPAssociation.h:764
bool(* cmtSendAllComparisonFunction)(const SCTPPathVariables *left, const SCTPPathVariables *right)
Definition: SCTPAssociation.h:706
cMessage * T1_InitTimer
Definition: SCTPAssociation.h:919
uint32 rpMinCwnd
Definition: SCTPAssociation.h:770
void scheduleTimeout(cMessage *msg, const simtime_t &timeout)
Utility: start a timer.
Definition: SCTPAssociation.h:1188
bool tellArwnd
Definition: SCTPAssociation.h:846
CSackPath cmtSackPath
Definition: SCTPAssociation.h:752
Definition: SCTPAssociation.h:729
Definition: SCTPAssociation.h:750
Definition: SCTPAssociation.h:711
void sendOnAllPaths(SCTPPathVariables *firstPath)
Definition: SCTPAssociationSendAll.cc:275
int getSackFrequency()
Definition: SCTP.h:272
Definition: SCTPAssociation.h:681
double sackPeriod
Definition: SCTPAssociation.h:950
void sendShutdownAck(const L3Address &dest)
Definition: SCTPAssociationUtil.cc:1057
double throughputInterval
Definition: SCTPAssociation.h:852
void cwndUpdateAfterRtxTimeout(SCTPPathVariables *path)
Definition: SCTPCCFunctions.cc:832
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
const char * inet::sctp::SCTPAssociation::stateName ( const int32  state)
static

Utility: returns name of SCTP_S_xxx constants.

Referenced by printAssocBrief(), process_RCV_Message(), process_STATUS(), and process_TIMEOUT_INIT_REXMIT().

142 {
143 #define CASE(x) case x: \
144  s = #x + 7; break
145  const char *s = "unknown";
146  switch (state) {
155  }
156  return s;
157 #undef CASE
158 }
Definition: SCTPAssociation.h:63
#define CASE(x)
Definition: SCTPAssociation.h:60
Definition: SCTPAssociation.h:64
Definition: SCTPAssociation.h:58
Definition: SCTPAssociation.h:62
Definition: SCTPAssociation.h:59
Definition: SCTPAssociation.h:61
value< double, units::s > s
Definition: Units.h:1049
Definition: SCTPAssociation.h:57
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::stopTimers ( )

Referenced by process_RCV_Message().

3624 {
3625  for (auto & elem : sctpPathMap) {
3626  stopTimer(elem.second->HeartbeatTimer);
3627  stopTimer(elem.second->HeartbeatIntervalTimer);
3628  }
3629 }
void stopTimer(cMessage *timer)
Definition: SCTPAssociationRcvMessage.cc:3631
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
void inet::sctp::SCTPAssociation::storePacket ( SCTPPathVariables pathVar,
SCTPMessage sctpMsg,
const uint16  chunksAdded,
const uint16  dataChunksAdded,
const bool  authAdded 
)
private

Referenced by sendBundledOutgoingResetAndResponse(), sendDoubleStreamResetResponse(), sendOnPath(), sendOutgoingResetRequest(), sendStreamResetRequest(), and sendStreamResetResponse().

60 {
61  uint32 packetBytes = 0;
62  for (uint16 i = 0; i < sctpMsg->getChunksArraySize(); i++) {
63  cPacketPtr& chunkPtr = sctpMsg->getChunks(i);
64  SCTPDataChunk* dataChunk = dynamic_cast<SCTPDataChunk*>(chunkPtr);
65  if(dataChunk != nullptr) {
66  const uint32_t tsn = dataChunk->getTsn();
67  SCTPDataVariables* chunk = retransmissionQ->payloadQueue.find(tsn)->second;
68  assert(chunk != nullptr);
70  chunk->queuedOnPath->queuedBytes -= chunk->booksize;
71  chunk->queuedOnPath = nullptr;
72  packetBytes += chunk->booksize;
73  }
74  }
75 
76  state->sctpMsg = sctpMsg;
77  state->chunksAdded = chunksAdded;
78  state->dataChunksAdded = dataChunksAdded;
79  state->packetBytes = packetBytes;
80  state->authAdded = authAdded;
81  EV_INFO << "storePacket: path=" << pathVar->remoteAddress
82  << " state->packetBytes=" << state->packetBytes
83  << " osb=" << pathVar->outstandingBytes << " -> "
84  << pathVar->outstandingBytes - state->packetBytes << endl;
85  if (state->osbWithHeader)
87  else
90 }
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
void decreaseOutstandingBytes(SCTPDataVariables *chunk)
Definition: SCTPAssociationRcvMessage.cc:41
uint64 roomSumSendStreams
Definition: SCTPAssociation.h:875
PayloadQueue payloadQueue
Definition: SCTPQueue.h:101
SCTPQueue * retransmissionQ
Definition: SCTPAssociation.h:967
cPacket * cPacketPtr
Definition: SCTPMessage_m.h:39
uint16 chunksAdded
Definition: SCTPAssociation.h:669
bool osbWithHeader
Definition: SCTPAssociation.h:832
SCTPMessage * sctpMsg
Definition: SCTPAssociation.h:668
uint64 bookedSumSendStreams
Definition: SCTPAssociation.h:876
QueueCounter qCounter
Definition: SCTPAssociation.h:965
uint32_t uint32
Definition: Compat.h:30
bool authAdded
Definition: SCTPAssociation.h:674
uint16_t uint16
Definition: Compat.h:32
uint32 packetBytes
Definition: SCTPAssociation.h:671
uint16 dataChunksAdded
Definition: SCTPAssociation.h:670
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int32 inet::sctp::SCTPAssociation::streamScheduler ( SCTPPathVariables path,
bool  peek 
)
protected

Dealing with streams.

Referenced by SCTPAssociation().

102 {
103  int32 sid, testsid;
104 
105  EV_INFO << "Stream Scheduler: RoundRobin\n";
106 
107  sid = -1;
108 
109  if ((state->ssLastDataChunkSizeSet == false || state->ssNextStream == false) &&
110  (sendStreams.find(state->lastStreamScheduled)->second->getUnorderedStreamQ()->getLength() > 0 ||
111  sendStreams.find(state->lastStreamScheduled)->second->getStreamQ()->getLength() > 0)) {
112  sid = state->lastStreamScheduled;
113  EV_DETAIL << "Stream Scheduler: again sid " << sid << ".\n";
114  state->ssNextStream = true;
115  } else {
116  testsid = state->lastStreamScheduled;
117 
118  do {
119  testsid = (testsid + 1) % outboundStreams;
120 
121  if (sendStreams.find(testsid)->second->getUnorderedStreamQ()->getLength() > 0 ||
122  sendStreams.find(testsid)->second->getStreamQ()->getLength() > 0)
123  {
124  sid = testsid;
125  EV_DETAIL << "Stream Scheduler: chose sid " << sid << ".\n";
126 
127  if (!peek) {
128  state->lastStreamScheduled = sid;
129  break;
130  }
131  }
132  } while (sid == -1 && testsid != (int32)state->lastStreamScheduled);
133  }
134 
135  EV_INFO << "streamScheduler sid=" << sid << " lastStream=" << state->lastStreamScheduled << " outboundStreams=" << outboundStreams << " next=" << state->ssNextStream << "\n";
136 
137  if (sid >= 0 && !peek)
138  state->ssLastDataChunkSizeSet = false;
139 
140  return sid;
141 }
uint32 lastStreamScheduled
Definition: SCTPAssociation.h:626
bool ssNextStream
Definition: SCTPAssociation.h:853
uint32 outboundStreams
Definition: SCTPAssociation.h:943
bool ssLastDataChunkSizeSet
Definition: SCTPAssociation.h:854
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
int32_t int32
Definition: Compat.h:31
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int32 inet::sctp::SCTPAssociation::streamSchedulerFairBandwidth ( SCTPPathVariables path,
bool  peek 
)
protected

Referenced by SCTPAssociation().

295 {
296  EV_INFO << "Stream Scheduler: FairBandwidth (peek: " << peek << ")" << endl;
297  state->ssNextStream = true;
298  return streamSchedulerFairBandwidthPacket(path, peek);
299 }
bool ssNextStream
Definition: SCTPAssociation.h:853
int32 streamSchedulerFairBandwidthPacket(SCTPPathVariables *path, bool peek)
Definition: SCTPSSFunctions.cc:301
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int32 inet::sctp::SCTPAssociation::streamSchedulerFairBandwidthPacket ( SCTPPathVariables path,
bool  peek 
)
protected

Referenced by SCTPAssociation(), and streamSchedulerFairBandwidth().

302 {
303  uint32 bandwidth = 0, packetsize = 0, lastDataChunkSize;
304  int32 sid = -1;
305  std::map<uint16, int32> peekMap;
306  std::map<uint16, int32> *mapPointer = &(state->ssFairBandwidthMap);
307 
308  EV_INFO << "Stream Scheduler: FairBandwidthPacket (peek: " << peek << ")" << endl;
309 
310  if (state->ssFairBandwidthMap.empty()) {
311  for (auto & elem : sendStreams) {
312  state->ssFairBandwidthMap[elem.first] = -1;
313  EV_DETAIL << "initialize sid " << elem.first << " in fb map." << endl;
314  }
315  }
316 
317  if (peek) {
318  EV_DETAIL << "just peeking, use duplicate fb map." << endl;
319  for (auto & elem : state->ssFairBandwidthMap) {
320  peekMap[elem.first] = elem.second;
321  }
322  mapPointer = &peekMap;
323  }
324 
325  lastDataChunkSize = (*mapPointer)[state->lastStreamScheduled];
326 
327  for (auto & elem : sendStreams) {
328  /* There is data in this stream */
329  if (elem.second->getUnorderedStreamQ()->getLength() > 0 || elem.second->getStreamQ()->getLength() > 0) {
330  /* Get size of the first packet in stream */
331  if (elem.second->getUnorderedStreamQ()->getLength() > 0) {
332  packetsize = check_and_cast<SCTPSimpleMessage *>(((SCTPDataMsg *)elem.second->getUnorderedStreamQ()->front())->getEncapsulatedPacket())->getByteLength();
333  }
334  else if (elem.second->getStreamQ()->getLength() > 0) {
335  packetsize = check_and_cast<SCTPSimpleMessage *>(((SCTPDataMsg *)elem.second->getStreamQ()->front())->getEncapsulatedPacket())->getByteLength();
336  }
337 
338  /* This stream is new to the map, so add it */
339  if ((*mapPointer)[elem.first] < 0) {
340  if (packetsize > 0) {
341  (*mapPointer)[elem.first] = packetsize;
342  if (!peek)
343  EV_DETAIL << "Stream Scheduler: add sid " << elem.first << " with size " << packetsize << " to fair bandwidth map.\n";
344  }
345  }
346  /* This stream is already in the map, so update it if necessary */
347  else if (state->ssLastDataChunkSizeSet) {
348  /* Subtract the size of the last scheduled chunk from all streams */
349  (*mapPointer)[elem.first] -= lastDataChunkSize;
350  if ((*mapPointer)[elem.first] < 0)
351  (*mapPointer)[elem.first] = 0;
352 
353  /* We sent from this stream the last time, so add a new message to it */
354  if (elem.first == state->lastStreamScheduled) {
355  (*mapPointer)[elem.first] += packetsize;
356  if (!peek)
357  EV_DETAIL << "Stream Scheduler: updated sid " << elem.first << " with new packet of size " << packetsize << endl;
358  }
359 
360  if (!peek)
361  EV_DETAIL << "Stream Scheduler: updated sid " << elem.first << " entry to size " << (*mapPointer)[elem.first] << endl;
362  }
363  }
364  /* There is no data in this stream, so delete it from map */
365  else {
366  (*mapPointer)[elem.first] = -1;
367  if (!peek)
368  EV_DETAIL << "Stream Scheduler: sid " << elem.first << " removed from fb map" << endl;
369  }
370  }
371 
372  if (!peek) {
373  state->ssLastDataChunkSizeSet = false;
374  }
375 
376  if (state->ssNextStream) {
377  for (auto & elem : *mapPointer) {
378  if ((sid < 0 || (uint32)elem.second < bandwidth) && elem.second >= 0) {
379  sid = elem.first;
380  bandwidth = elem.second;
381  if (!peek)
382  EV_DETAIL << "Stream Scheduler: chose sid " << sid << ".\n";
383  }
384  }
385  }
386  else {
387  if (sendStreams.find(state->lastStreamScheduled)->second->getUnorderedStreamQ()->getLength() > 0 ||
388  sendStreams.find(state->lastStreamScheduled)->second->getStreamQ()->getLength() > 0)
389  {
390  sid = state->lastStreamScheduled;
391  if (!peek)
392  EV_DETAIL << "Stream Scheduler: again sid " << sid << ".\n";
393  }
394  }
395 
396  if (sid >= 0 && !peek) {
397  state->lastStreamScheduled = sid;
398  state->ssNextStream = false;
399  }
400 
401  return sid;
402 }
uint32 lastStreamScheduled
Definition: SCTPAssociation.h:626
bool ssNextStream
Definition: SCTPAssociation.h:853
std::map< uint16, int32 > ssFairBandwidthMap
Definition: SCTPAssociation.h:857
bool ssLastDataChunkSizeSet
Definition: SCTPAssociation.h:854
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int32 inet::sctp::SCTPAssociation::streamSchedulerFCFS ( SCTPPathVariables path,
bool  peek 
)
protected

Referenced by SCTPAssociation().

405 {
406  int32 sid, testsid;
407  simtime_t oldestEnqueuing, testTime;
408 
409  EV_INFO << "Stream Scheduler: First-come, first-serve (peek: " << peek << ")" << endl;
410 
411  sid = -1;
412 
413  if (!state->ssNextStream) {
414  testsid = -1;
415  state->ssNextStream = true;
416  }
417  else
418  testsid = state->lastStreamScheduled;
419 
420  do {
421  testsid = (testsid + 1) % outboundStreams;
422 
423  if (sendStreams.find(testsid)->second->getUnorderedStreamQ()->getLength() > 0) {
424  testTime = ((SCTPDataMsg *)sendStreams.find(testsid)->second->getUnorderedStreamQ()->front())->getEnqueuingTime();
425  if (sid < 0 || oldestEnqueuing > testTime) {
426  oldestEnqueuing = testTime;
427  sid = testsid;
428  EV_DETAIL << "Stream Scheduler: chose sid " << sid << ".\n";
429  }
430  }
431 
432  if (sendStreams.find(testsid)->second->getStreamQ()->getLength() > 0) {
433  testTime = ((SCTPDataMsg *)sendStreams.find(testsid)->second->getStreamQ()->front())->getEnqueuingTime();
434  if (sid < 0 || oldestEnqueuing > testTime) {
435  oldestEnqueuing = testTime;
436  sid = testsid;
437  EV_DETAIL << "Stream Scheduler: chose sid " << sid << ".\n";
438  }
439  }
440  } while (testsid != (int32)state->lastStreamScheduled);
441 
442  if (!peek && sid >= 0)
443  state->lastStreamScheduled = sid;
444 
445  return sid;
446 }
uint32 lastStreamScheduled
Definition: SCTPAssociation.h:626
bool ssNextStream
Definition: SCTPAssociation.h:853
uint32 outboundStreams
Definition: SCTPAssociation.h:943
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
int32_t int32
Definition: Compat.h:31
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int32 inet::sctp::SCTPAssociation::streamSchedulerPriority ( SCTPPathVariables path,
bool  peek 
)
protected

Referenced by SCTPAssociation().

247 {
248  int32 sid = 0, testsid;
249  std::list<uint32> PriorityList;
250  std::list<uint32> StreamList;
251 
252  EV_INFO << "Stream Scheduler: Priority (peek: " << peek << ")" << endl;
253 
254  sid = -1;
255 
256  if ((state->ssLastDataChunkSizeSet == false && state->ssNextStream == true) &&
257  (sendStreams.find(state->lastStreamScheduled)->second->getUnorderedStreamQ()->getLength() > 0 ||
258  sendStreams.find(state->lastStreamScheduled)->second->getStreamQ()->getLength() > 0))
259  {
260  sid = state->lastStreamScheduled;
261  EV_DETAIL << "Stream Scheduler: again sid " << sid << ".\n";
262 
263  return sid;
264  }
265 
266  if (!state->ssNextStream) {
267  testsid = -1;
268  state->ssNextStream = true;
269  }
270  else
271  testsid = state->lastStreamScheduled;
272 
273  do {
274  testsid = (testsid + 1) % outboundStreams;
275 
276  if (sendStreams.find(testsid)->second->getUnorderedStreamQ()->getLength() > 0 ||
277  sendStreams.find(testsid)->second->getStreamQ()->getLength() > 0)
278  {
279  if (sid < 0 || state->ssPriorityMap[testsid] < state->ssPriorityMap[sid]) {
280  sid = testsid;
281  EV_DETAIL << "Stream Scheduler: chose sid " << sid << ".\n";
282  }
283  }
284  } while (testsid != (int32)state->lastStreamScheduled);
285 
286  if (!peek && sid >= 0) {
287  state->lastStreamScheduled = sid;
288  state->ssLastDataChunkSizeSet = false;
289  }
290 
291  return sid;
292 }
std::map< uint16, uint32 > ssPriorityMap
Definition: SCTPAssociation.h:856
uint32 lastStreamScheduled
Definition: SCTPAssociation.h:626
bool ssNextStream
Definition: SCTPAssociation.h:853
uint32 outboundStreams
Definition: SCTPAssociation.h:943
bool ssLastDataChunkSizeSet
Definition: SCTPAssociation.h:854
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
int32_t int32
Definition: Compat.h:31
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int32 inet::sctp::SCTPAssociation::streamSchedulerRandom ( SCTPPathVariables path,
bool  peek 
)
protected

Referenced by SCTPAssociation().

197 {
198  EV_INFO << "Stream Scheduler: Random (peek: " << peek << ")" << endl;
199  state->ssNextStream = true;
200  return streamSchedulerRandomPacket(path, peek);
201 }
bool ssNextStream
Definition: SCTPAssociation.h:853
int32 streamSchedulerRandomPacket(SCTPPathVariables *path, bool peek)
Definition: SCTPSSFunctions.cc:203
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int32 inet::sctp::SCTPAssociation::streamSchedulerRandomPacket ( SCTPPathVariables path,
bool  peek 
)
protected

Referenced by SCTPAssociation(), and streamSchedulerRandom().

204 {
205  int32 sid = -1, rnd;
206  uint32 lastsid = state->lastStreamScheduled;
207  std::vector<uint32> SCTPWaitingSendStreamsList;
208 
209  EV_INFO << "Stream Scheduler: RandomPacket (peek: " << peek << ")" << endl;
210 
211  if (state->ssNextStream) {
212  for (auto & elem : sendStreams) {
213  if (elem.second->getUnorderedStreamQ()->getLength() > 0 ||
214  elem.second->getStreamQ()->getLength() > 0)
215  {
216  SCTPWaitingSendStreamsList.push_back(elem.first);
217  EV_DETAIL << "Stream Scheduler: add sid " << elem.first << " to list of waiting streams.\n";
218  }
219  }
220  if (SCTPWaitingSendStreamsList.size() > 0) {
221  rnd = (int)(ceil(RNGCONTEXT uniform(1, SCTPWaitingSendStreamsList.size()) - 0.5));
222  EV_DETAIL << "Stream Scheduler: go to " << rnd << ". element of waiting stream list.\n";
223  sid = SCTPWaitingSendStreamsList[rnd - 1];
224  if (!peek)
225  state->lastStreamScheduled = sid;
226  EV_DETAIL << "Stream Scheduler: chose sid " << sid << ".\n";
227  }
228  }
229  else {
230  if (sendStreams.find(state->lastStreamScheduled)->second->getUnorderedStreamQ()->getLength() > 0 ||
231  sendStreams.find(state->lastStreamScheduled)->second->getStreamQ()->getLength() > 0)
232  {
233  sid = state->lastStreamScheduled;
234  EV_DETAIL << "Stream Scheduler: again sid " << sid << ".\n";
235  }
236  }
237 
238  EV_INFO << "streamScheduler sid=" << sid << " lastStream=" << lastsid << " outboundStreams=" << outboundStreams << " next=" << state->ssNextStream << "\n";
239 
240  if (sid >= 0 && !peek)
241  state->ssNextStream = false;
242 
243  return sid;
244 }
uint32 lastStreamScheduled
Definition: SCTPAssociation.h:626
bool ssNextStream
Definition: SCTPAssociation.h:853
#define RNGCONTEXT
Definition: INETDefs.h:85
uint32 outboundStreams
Definition: SCTPAssociation.h:943
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
int32 inet::sctp::SCTPAssociation::streamSchedulerRoundRobinPacket ( SCTPPathVariables path,
bool  peek 
)
protected

Referenced by SCTPAssociation().

155 {
156  int32 sid, testsid, lastsid = state->lastStreamScheduled;
157 
158  EV_INFO << "Stream Scheduler: RoundRobinPacket (peek: " << peek << ")" << endl;
159 
160  sid = -1;
161 
162  if (state->ssNextStream) {
163  testsid = state->lastStreamScheduled;
164 
165  do {
166  testsid = (testsid + 1) % outboundStreams;
167 
168  if (sendStreams.find(testsid)->second->getUnorderedStreamQ()->getLength() > 0 ||
169  sendStreams.find(testsid)->second->getStreamQ()->getLength() > 0)
170  {
171  sid = testsid;
172  EV_DETAIL << "Stream Scheduler: chose sid " << sid << ".\n";
173 
174  if (!peek)
175  state->lastStreamScheduled = sid;
176  }
177  } while (sid == -1 && testsid != (int32)state->lastStreamScheduled);
178  }
179  else {
180  if (sendStreams.find(state->lastStreamScheduled)->second->getUnorderedStreamQ()->getLength() > 0 ||
181  sendStreams.find(state->lastStreamScheduled)->second->getStreamQ()->getLength() > 0)
182  {
183  sid = state->lastStreamScheduled;
184  EV_DETAIL << "Stream Scheduler: again sid " << sid << ".\n";
185  }
186  }
187 
188  EV_INFO << "streamScheduler sid=" << sid << " lastStream=" << lastsid << " outboundStreams=" << outboundStreams << " next=" << state->ssNextStream << "\n";
189 
190  if (sid >= 0 && !peek)
191  state->ssNextStream = false;
192 
193  return sid;
194 }
uint32 lastStreamScheduled
Definition: SCTPAssociation.h:626
bool ssNextStream
Definition: SCTPAssociation.h:853
uint32 outboundStreams
Definition: SCTPAssociation.h:943
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
int32_t int32
Definition: Compat.h:31
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::timeForSack ( bool &  sackOnly,
bool &  sackWithData 
)
private

Referenced by sendOnPath().

254 {
255  sackOnly = sackWithData = false;
256  // CMT DAC implementation at the receiver side
257  // If CMT DAC is used, a SACK is *not* immediately transferred upon reordering
258  if (((state->gapList.getNumGaps(SCTPGapList::GT_Any) > 0) || (state->dupList.size() > 0)) &&
259  (state->sackAllowed) &&
260  (!((state->allowCMT == true) && (state->cmtUseDAC == true))))
261  {
262  // Schedule sending of SACKs at once, when we have fragments to report
264  sackOnly = sackWithData = true; // SACK necessary, regardless of data available
265  }
266  if (state->ackState >= sackFrequency) {
267  sackOnly = sackWithData = true; // SACK necessary, regardless of data available
268  }
269  else if (SackTimer->isScheduled()) {
270  sackOnly = false;
271  sackWithData = true; // Only send SACK when data is present.
272  }
273 }
uint32 sackFrequency
Definition: SCTPAssociation.h:949
uint32 getNumGaps(const GapType type) const
Definition: SCTPGapList.h:112
bool sackAllowed
Definition: SCTPAssociation.h:586
bool allowCMT
Definition: SCTPAssociation.h:705
bool cmtUseDAC
Definition: SCTPAssociation.h:740
cMessage * SackTimer
Definition: SCTPAssociation.h:922
uint32 ackState
Definition: SCTPAssociation.h:618
Definition: SCTPGapList.h:107
SCTPGapList gapList
Definition: SCTPAssociation.h:619
std::list< uint32 > dupList
Definition: SCTPAssociation.h:608
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
SCTPDataChunk * inet::sctp::SCTPAssociation::transformDataChunk ( SCTPDataVariables chunk)
protected

Manipulating chunks.

Referenced by sendOnPath().

2012 {
2013  SCTPDataChunk *dataChunk = new SCTPDataChunk("DATA");
2014  SCTPSimpleMessage *msg = check_and_cast<SCTPSimpleMessage *>(chunk->userData->dup());
2015  dataChunk->setChunkType(DATA);
2016  dataChunk->setBBit(chunk->bbit);
2017  dataChunk->setEBit(chunk->ebit);
2018  if (chunk->ordered) {
2019  dataChunk->setUBit(0);
2020  }
2021  else {
2022  dataChunk->setUBit(1);
2023  }
2024  dataChunk->setTsn(chunk->tsn);
2025  dataChunk->setSid(chunk->sid);
2026  dataChunk->setSsn(chunk->ssn);
2027  dataChunk->setPpid(chunk->ppid);
2028  dataChunk->setIBit(chunk->ibit);
2029  dataChunk->setEnqueuingTime(chunk->enqueuingTime);
2030  dataChunk->setFirstSendTime(chunk->firstSendTime);
2031  dataChunk->setByteLength(SCTP_DATA_CHUNK_LENGTH);
2032  msg->setBitLength(chunk->len);
2033  dataChunk->encapsulate(msg);
2034  return dataChunk;
2035 }
Definition: SCTPAssociation.h:111
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
static int32 inet::sctp::SCTPAssociation::tsnBetween ( const uint32  tsn1,
const uint32  midtsn,
const uint32  tsn2 
)
inlinestatic

Referenced by inet::sctp::SCTPSimpleGapList::removeFromGapList(), inet::sctp::SCTPSimpleGapList::tsnInGapList(), and inet::sctp::SCTPSimpleGapList::updateGapList().

1084 { return (SCTP_TSN_GE(midtsn, tsn1) && SCTP_TSN_GE(tsn2, midtsn)); }
#define SCTP_TSN_GE(a, b)
Definition: SCTPAssociation.h:1077
static int32 inet::sctp::SCTPAssociation::tsnGe ( const uint32  tsn1,
const uint32  tsn2 
)
inlinestatic

Referenced by createForwardTsnChunk(), dequeueAckedChunks(), inet::sctp::SCTPSimpleGapList::forwardCumAckTSN(), and processDataArrived().

1080 { return SCTP_TSN_GE(tsn1, tsn2); }
#define SCTP_TSN_GE(a, b)
Definition: SCTPAssociation.h:1077
static int32 inet::sctp::SCTPAssociation::tsnGt ( const uint32  tsn1,
const uint32  tsn2 
)
inlinestatic
bool inet::sctp::SCTPAssociation::tsnIsDuplicate ( const uint32  tsn) const
protected

Methods dealing with the handling of TSNs.

Referenced by processDataArrived().

2158 {
2159  for (std::list<uint32>::const_iterator iterator = state->dupList.begin();
2160  iterator != state->dupList.end(); iterator++)
2161  {
2162  if ((*iterator) == tsn)
2163  return true;
2164  }
2165  return state->gapList.tsnInGapList(tsn);
2166 }
SCTPGapList gapList
Definition: SCTPAssociation.h:619
bool tsnInGapList(const uint32 tsn) const
Definition: SCTPGapList.h:125
std::list< uint32 > dupList
Definition: SCTPAssociation.h:608
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
static int32 inet::sctp::SCTPAssociation::tsnLe ( const uint32  tsn1,
const uint32  tsn2 
)
inlinestatic

Referenced by inet::sctp::SCTPSimpleGapList::check(), processDataArrived(), processSackArrived(), and inet::sctp::SCTPSimpleGapList::updateGapList().

1082 { return SCTP_TSN_GE(tsn2, tsn1); }
#define SCTP_TSN_GE(a, b)
Definition: SCTPAssociation.h:1077
static int32 inet::sctp::SCTPAssociation::tsnLt ( const uint32  tsn1,
const uint32  tsn2 
)
inlinestatic

Referenced by handleChunkReportedAsAcked(), handleChunkReportedAsMissing(), and processSackArrived().

1083 { return SCTP_TSN_GT(tsn2, tsn1); }
#define SCTP_TSN_GT(a, b)
Definition: SCTPAssociation.h:1076
void inet::sctp::SCTPAssociation::tsnWasReneged ( SCTPDataVariables chunk,
const SCTPPathVariables sackPath,
const int  type 
)
protected

Referenced by handleChunkReportedAsMissing(), and processSackArrived().

941 {
942  if ((state->allowCMT) && (state->cmtSmartReneging) &&
943  (sackPath != chunk->ackedOnPath))
944  {
945  return;
946  }
947  EV_INFO << "TSN " << chunk->tsn << " has been reneged (type "
948  << type << ")" << endl;
949  unackChunk(chunk);
950  if (chunk->countsAsOutstanding) {
952  }
953  chunk->hasBeenReneged = true;
954  chunk->gapReports = 1;
955  if (!chunk->getLastDestinationPath()->T3_RtxTimer->isScheduled()) {
956  startTimer(chunk->getLastDestinationPath()->T3_RtxTimer,
957  chunk->getLastDestinationPath()->pathRto);
958  }
959 }
void startTimer(cMessage *timer, const simtime_t &timeout)
Definition: SCTPAssociationRcvMessage.cc:3639
void unackChunk(SCTPDataVariables *chunk)
Definition: SCTPAssociation.h:1443
void decreaseOutstandingBytes(SCTPDataVariables *chunk)
Definition: SCTPAssociationRcvMessage.cc:41
bool allowCMT
Definition: SCTPAssociation.h:705
bool cmtSmartReneging
Definition: SCTPAssociation.h:737
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::typeInChunkList ( const uint16  type)
protected

Referenced by process_RCV_Message(), processPacketDropArrived(), retransmitCookieEcho(), sendAbort(), sendCookieAck(), sendCookieEcho(), sendHeartbeat(), sendHeartbeatAck(), sendInvalidStreamError(), sendSack(), and sendShutdown().

286 {
287  for (auto & elem : state->peerChunkList) {
288  if ((elem) == type) {
289  return true;
290  }
291  }
292  return false;
293 }
std::vector< uint16 > peerChunkList
Definition: SCTPAssociation.h:824
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
bool inet::sctp::SCTPAssociation::typeInOwnChunkList ( const uint16  type)
protected

Referenced by cloneAssociation().

296 {
297  for (auto & elem : state->chunkList) {
298  if ((elem) == type) {
299  return true;
300  }
301  }
302  return false;
303 }
std::vector< uint16 > chunkList
Definition: SCTPAssociation.h:823
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::unackChunk ( SCTPDataVariables chunk)
inlineprivate

Referenced by sendOnPath(), and tsnWasReneged().

1444  {
1445  chunk->hasBeenAcked = false;
1446  }
bool inet::sctp::SCTPAssociation::unorderedQueueEmptyOfStream ( uint16  sid)
protected

Referenced by process_STREAM_RESET().

93 {
94  auto streamIterator = sendStreams.find(sid);
95  assert(streamIterator != sendStreams.end());
96  return (streamIterator->second)->getUnorderedStreamQ()->isEmpty();
97 }
SCTPSendStreamMap sendStreams
Definition: SCTPAssociation.h:968
int32 inet::sctp::SCTPAssociation::updateCounters ( SCTPPathVariables path)
protected

Referenced by process_TIMEOUT_ASCONF(), and process_TIMEOUT_RESET().

3668 {
3669  bool notifyUlp = false;
3671  EV_DETAIL << "Retransmission count during connection setup exceeds " << (int32)sctpMain->getAssocMaxRtx() << ", giving up\n";
3673  sendAbort();
3674  sctpMain->removeAssociation(this);
3675  return 0;
3676  }
3677  else if (++path->pathErrorCount > (uint32)sctpMain->getPathMaxRetrans()) {
3678  if (path->activePath) {
3679  /* tell the source */
3680  notifyUlp = true;
3681  }
3682 
3683  path->activePath = false;
3684  if (path == state->getPrimaryPath()) {
3686  }
3687  EV_DETAIL << "process_TIMEOUT_RESET(" << (path->remoteAddress) << ") : PATH ERROR COUNTER EXCEEDED, path status is INACTIVE\n";
3688  if (allPathsInactive()) {
3689  EV_DETAIL << "process_TIMEOUT_RESET : ALL PATHS INACTIVE --> closing ASSOC\n";
3691  sendAbort();
3692  sctpMain->removeAssociation(this);
3693  return 0;
3694  }
3695  else if (notifyUlp) {
3696  /* notify the application */
3697  pathStatusIndication(path, false);
3698  }
3699  EV_DETAIL << "process_TIMEOUT_RESET(" << (path->remoteAddress) << ") : PATH ERROR COUNTER now " << path->pathErrorCount << "\n";
3700  return 2;
3701  }
3702  return 1;
3703 }
Definition: SCTPCommand.h:67
int getPathMaxRetrans()
Definition: SCTP.h:278
SCTPPathVariables * getPrimaryPath() const
Definition: SCTPAssociation.h:558
uint32 errorCount
Definition: SCTPAssociation.h:609
Definition: SCTPCommand.h:73
int getAssocMaxRtx()
Definition: SCTP.h:279
SCTP * sctpMain
Definition: SCTPAssociation.h:962
void removeAssociation(SCTPAssociation *assoc)
Definition: SCTP.cc:799
void pathStatusIndication(const SCTPPathVariables *path, const bool status)
Definition: SCTPAssociationUtil.cc:2743
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
void sendIndicationToApp(const int32 code, const int32 value=0)
Utility: sends status indication (SCTP_I_xxx) to application.
Definition: SCTPAssociationUtil.cc:411
SCTPPathVariables * getNextPath(const SCTPPathVariables *oldPath) const
Definition: SCTPAssociationUtil.cc:2594
void sendAbort(uint16 tBit=0)
Definition: SCTPAssociationUtil.cc:1101
void setPrimaryPath(SCTPPathVariables *path)
Definition: SCTPAssociation.h:545
bool allPathsInactive() const
Definition: SCTPAssociationUtil.cc:2790
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::updateFastRecoveryStatus ( const uint32  lastTsnAck)
protected

Referenced by processSackArrived().

581 {
582  for (auto & elem : sctpPathMap) {
583  SCTPPathVariables *path = elem.second;
584 
585  if (path->fastRecoveryActive) {
586  if ((tsnGt(lastTsnAck, path->fastRecoveryExitPoint)) ||
587  (lastTsnAck == path->fastRecoveryExitPoint) || ((state->allowCMT) && (state->cmtUseFRC) &&
588  ((path->newPseudoCumAck && tsnGt(path->pseudoCumAck, path->fastRecoveryExitPoint)) ||
589  (path->newRTXPseudoCumAck && tsnGt(path->rtxPseudoCumAck, path->fastRecoveryExitPoint)))))
590  {
591  path->fastRecoveryActive = false;
592  path->fastRecoveryExitPoint = 0;
593 
594  EV_INFO << simTime() << ":\tCC [cwndUpdateAfterSack] Leaving Fast Recovery on path "
595  << path->remoteAddress
596  << ", lastTsnAck=" << lastTsnAck
597  << ", pseudoCumAck=" << path->pseudoCumAck
598  << ", rtxPseudoCumAck=" << path->rtxPseudoCumAck
599  << ", newPseudoCumAck=" << path->newPseudoCumAck
600  << ", newRTXPseudoCumAck=" << path->newRTXPseudoCumAck
601  << endl;
602  }
603  }
604  }
605 }
bool cmtUseFRC
Definition: SCTPAssociation.h:741
bool allowCMT
Definition: SCTPAssociation.h:705
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
static int32 tsnGt(const uint32 tsn1, const uint32 tsn2)
Definition: SCTPAssociation.h:1081
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
SCTPStateVariables * state
Definition: SCTPAssociation.h:960
void inet::sctp::SCTPAssociation::updateHighSpeedCCThresholdIdx ( SCTPPathVariables path)
private
124 {
125  ASSERT(path->highSpeedCCThresholdIdx < HIGHSPEED_ENTRIES);
126 
127  if (path->cwnd > HighSpeedCwndAdjustmentTable[path->highSpeedCCThresholdIdx].cwndThreshold * path->pmtu) {
128  while ((path->highSpeedCCThresholdIdx < HIGHSPEED_ENTRIES)
129  && (path->cwnd > HighSpeedCwndAdjustmentTable[path->highSpeedCCThresholdIdx].cwndThreshold * path->pmtu)) {
130  path->highSpeedCCThresholdIdx++;
131  }
132  } else {
133  while ((path->highSpeedCCThresholdIdx > 0) //FIXME check the condition: '>' or '>='
134  && (path->cwnd <= HighSpeedCwndAdjustmentTable[path->highSpeedCCThresholdIdx].cwndThreshold * path->pmtu)) {
135  path->highSpeedCCThresholdIdx--;
136  }
137  }
138 }
#define HIGHSPEED_ENTRIES
Definition: SCTPCCFunctions.cc:32
uint32 inet::sctp::SCTPAssociation::updateOLIA ( uint32  w,
const uint32  s,
const uint32  totalW,
double  a,
const uint32  mtu,
const uint32  ackedBytes,
SCTPPathVariables path 
)
private

w: cwnd of the path s: ssthresh of the path totalW: Sum of all cwnds of the association a: factor alpha of olia calculation - see https://tools.ietf.org/html/draft-khalili-mptcp-congestion-control-05 mtu: mtu of the path ackedBytes: ackednowlged bytes path: path variable (for further investigation, debug, etc)

259  {
260  int32 increase = 0;
261  bool isInCollectedPath = false;
262  bool isMaxWndPaths = false;
263 
264  if ((!(w < s)) && (!path->fastRecoveryActive)) {
265  // in CA
267 
268  int cnt = 0;
269  for (SCTPPathCollection::iterator it = assocCollectedPaths.begin();
270  it != assocCollectedPaths.end(); it++, cnt++) {
271  if (it->second == path) {
272  isInCollectedPath = true;
273  break;
274  }
275  }
276  cnt = 0;
277  for (SCTPPathCollection::iterator it = assocMaxWndPaths.begin();
278  it != assocMaxWndPaths.end(); it++, cnt++) {
279  if (it->second == path) {
280  isMaxWndPaths = true;
281  break;
282  }
283  }
284 
285  double r_sRTT = GET_SRTT(path->srtt.dbl());
286 
287  double numerator1 = path->cwnd / (r_sRTT * r_sRTT);
288  double denominator1 = 0;
289 
290  for (auto & elem : sctpPathMap) {
291  SCTPPathVariables* p_path = elem.second;
292  double p_sRTT = GET_SRTT(p_path->srtt.dbl());
293  denominator1 += (p_path->cwnd / p_sRTT);
294  }
295  denominator1 = denominator1 * denominator1;
296  double term1 = numerator1 / denominator1;
297 
298  if (isInCollectedPath) {
299  /*
300  For each ACK on the path r:
301  - If r is in collected_paths, increase w_r by
302 
303  w_r/rtt_r^2 1
304  ------------------- + ----------------------- (2)
305  (SUM (w_p/rtt_p))^2 w_r * number_of_paths * |collected_paths|
306 
307  multiplied by MSS_r * bytes_acked.
308  */
309 
310  double numerator2 = 1 / sctpPathMap.size();
311  double denominator2 = assocCollectedPaths.size();
312  double term2 = 0.0;
313  if (denominator2 > 0.0) {
314  term2 = numerator2 / denominator2;
315  }
316  increase = (uint32) ceil(
317  (term1 * path->cwnd * path->pmtu) + (term2 * path->pmtu));
318  } else if ((isMaxWndPaths) && (!assocCollectedPaths.empty())) {
319  /*
320  - If r is in max_w_paths and if collected_paths is not empty,
321  increase w_r by
322 
323  w_r/rtt_r^2 1
324  -------------------- - ------------------------ (3)
325  (SUM (w_p/rtt_p))^2 w_r * number_of_paths * |max_w_paths|
326 
327  multiplied by MSS_r * bytes_acked.
328  */
329  double numerator2 = 1.0 / (double)sctpPathMap.size();
330  double denominator2 = assocMaxWndPaths.size();
331  double term2 = 0.0;
332  if (denominator2 > 0.0) {
333  term2 = numerator2 / denominator2;
334  }
335  increase = (int32) ceil(
336  (term1 * path->cwnd * path->pmtu) - (term2 * path->pmtu)); // TODO
337  } else {
338  /*
339  - Otherwise, increase w_r by
340 
341  (w_r/rtt_r^2)
342  ---------------------------------- (4)
343  (SUM (w_p/rtt_p))^2
344 
345  multiplied by MSS_r * bytes_acked.
346  */
347  increase = (int32) ceil(term1 * path->cwnd * path->pmtu); // TODO std::min(acked,
348  }
349  } else {
350  increase = (int32) min(path->pmtu, ackedBytes); // slow start
351  }
352  return (w + increase);
353 }
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
SCTPPathCollection assocMaxWndPaths
Definition: SCTPAssociation.h:902
SCTPPathMap sctpPathMap
Definition: SCTPAssociation.h:964
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
friend class SCTPPathVariables
Definition: SCTPAssociation.h:867
value< double, units::s > s
Definition: Units.h:1049
void recalculateOLIABasis()
Definition: SCTPCCFunctions.cc:200
SCTPPathCollection assocCollectedPaths
Definition: SCTPAssociation.h:903

Friends And Related Function Documentation

friend class SCTP
friend

Member Data Documentation

cOutVector* inet::sctp::SCTPAssociation::advMsgRwnd

Referenced by createSack().

cOutVector* inet::sctp::SCTPAssociation::advRwnd
protected

Referenced by createSack().

SCTPPathCollection inet::sctp::SCTPAssociation::assocBestPaths
private
SCTPPathCollection inet::sctp::SCTPAssociation::assocCollectedPaths
private
SCTPPathCollection inet::sctp::SCTPAssociation::assocMaxWndPaths
private
cOutVector* inet::sctp::SCTPAssociation::assocThroughputVector

Referenced by process_RCV_Message().

BytesToBeSent inet::sctp::SCTPAssociation::bytes
protected

Referenced by bytesAllowedToSend(), and sendOnPath().

CCFunctions inet::sctp::SCTPAssociation::ccFunctions
protected
uint16 inet::sctp::SCTPAssociation::ccModule
protected
cOutVector* inet::sctp::SCTPAssociation::cumTsnAck
protected
uint8_t inet::sctp::SCTPAssociation::dacPacketsRcvd

Referenced by process_RCV_Message(), and sendOnPath().

cOutVector* inet::sctp::SCTPAssociation::EndToEndDelay

Referenced by pushUlp().

cMessage* inet::sctp::SCTPAssociation::FairStartTimer
cMessage* inet::sctp::SCTPAssociation::FairStopTimer
bool inet::sctp::SCTPAssociation::fairTimer

Referenced by nonRenegablyAckChunk().

IInterfaceTable* inet::sctp::SCTPAssociation::ift
protected
uint32 inet::sctp::SCTPAssociation::initInboundStreams
protected
uint32 inet::sctp::SCTPAssociation::initPeerTsn
protected
uint32 inet::sctp::SCTPAssociation::initTsn
protected

Referenced by sendInit(), and sendInitAck().

bool inet::sctp::SCTPAssociation::listening
AddressVector inet::sctp::SCTPAssociation::localAddressList
protected
uint32 inet::sctp::SCTPAssociation::numberOfRemoteAddresses
protected
cOutVector* inet::sctp::SCTPAssociation::numGapBlocks
protected

Referenced by processSackArrived().

uint32 inet::sctp::SCTPAssociation::peerVTag
uint32 inet::sctp::SCTPAssociation::sackFrequency
protected
double inet::sctp::SCTPAssociation::sackPeriod
protected

Referenced by scheduleSack().

SCTPAlgorithm* inet::sctp::SCTPAssociation::sctpAlgorithm
protected
SCTP* inet::sctp::SCTPAssociation::sctpMain
protected
cOutVector* inet::sctp::SCTPAssociation::sendQueue
protected
uint16 inet::sctp::SCTPAssociation::ssModule
protected
cMessage* inet::sctp::SCTPAssociation::StartAddIP
cMessage* inet::sctp::SCTPAssociation::StartTesting
SCTPStateVariables* inet::sctp::SCTPAssociation::state
protected

Referenced by addInStreams(), advancePeerTsn(), bytesAllowedToSend(), calculateAssocSharedKey(), calculateRcvBuffer(), checkStreamsToReset(), chunkReschedulingControl(), cloneAssociation(), compareRandom(), createForwardTsnChunk(), createSack(), cucProcessGapReports(), decreaseOutstandingBytes(), dequeueOutboundDataMsg(), fragmentOutboundDataMsgs(), generateSendQueueAbatedIndication(), getNextDestination(), getNextPath(), getSortedPathMap(), handleChunkReportedAsAcked(), handleChunkReportedAsMissing(), increaseOutstandingBytes(), initAssociation(), initStreams(), loadPacket(), makeAddStreamsRequestParameter(), makeDataVarFromDataMsg(), makeIncomingStreamResetParameter(), makeOutgoingStreamResetParameter(), makeRoomForTsn(), makeSSNTSNResetParameter(), makeVarFromMsg(), moveChunkToOtherPath(), nextChunkFitsIntoPacket(), nonRenegablyAckChunk(), pathStreamSchedulerManual(), peekAbandonedChunk(), pmClearPathCounter(), pmDataIsSentOn(), pmStartPathManagement(), process_ABORT(), process_ASSOCIATE(), process_CLOSE(), process_OPEN_PASSIVE(), process_PRIMARY(), process_QUEUE_BYTES_LIMIT(), process_QUEUE_MSGS_LIMIT(), process_RCV_Message(), process_RECEIVE_REQUEST(), process_SEND(), process_STREAM_RESET(), process_TIMEOUT_HEARTBEAT(), process_TIMEOUT_HEARTBEAT_INTERVAL(), process_TIMEOUT_INIT_REXMIT(), process_TIMEOUT_RESET(), process_TIMEOUT_RTX(), process_TIMEOUT_SHUTDOWN(), processAddInAndOutResetRequestArrived(), processAsconfAckArrived(), processAsconfArrived(), processCookieAckArrived(), processCookieEchoArrived(), processDataArrived(), processErrorArrived(), processForwardTsnArrived(), processHeartbeatAckArrived(), processInAndOutResetRequestArrived(), processIncomingResetRequestArrived(), processInitAckArrived(), processInitArrived(), processOutAndResponseArrived(), processOutgoingResetRequestArrived(), processPacketDropArrived(), processResetResponseArrived(), processSackArrived(), processSSNTSNResetRequestArrived(), processStreamResetArrived(), pushUlp(), putInDeliveryQ(), inet::sctp::SCTP::removeAssociation(), renegablyAckChunk(), resetGapLists(), retransmitAsconf(), retransmitCookieEcho(), retransmitInit(), retransmitReset(), retransmitShutdown(), retransmitShutdownAck(), scheduleSack(), sendAbort(), sendAddInAndOutStreamsRequest(), sendAddOutgoingStreamsRequest(), sendAsconf(), sendAsconfAck(), sendBundledOutgoingResetAndResponse(), sendCookieAck(), sendCookieEcho(), sendDoubleStreamResetResponse(), sendEstabIndicationToApp(), sendHeartbeat(), sendHeartbeatAck(), sendInit(), sendInitAck(), sendInvalidStreamError(), sendOnAllPaths(), sendOnPath(), sendOutgoingRequestAndResponse(), sendOutgoingResetRequest(), sendPacketDrop(), sendSack(), sendSACKviaSelectedPath(), sendShutdown(), sendShutdownAck(), sendStreamResetRequest(), sendStreamResetResponse(), storePacket(), streamScheduler(), streamSchedulerFairBandwidth(), streamSchedulerFairBandwidthPacket(), streamSchedulerFCFS(), streamSchedulerPriority(), streamSchedulerRandom(), streamSchedulerRandomPacket(), streamSchedulerRoundRobinPacket(), timeForSack(), tsnIsDuplicate(), tsnWasReneged(), typeInChunkList(), typeInOwnChunkList(), and updateCounters().

cOutVector* inet::sctp::SCTPAssociation::statisticsArwndInLastSACK
protected

Referenced by processSackArrived().

cOutVector* inet::sctp::SCTPAssociation::statisticsNonRevokableGapBlocksInLastSACK
protected

Referenced by processSackArrived().

cOutVector* inet::sctp::SCTPAssociation::statisticsNumDuplicatesSent
protected

Referenced by createSack().

cOutVector* inet::sctp::SCTPAssociation::statisticsNumDuplicatesStored
protected

Referenced by createSack().

cOutVector* inet::sctp::SCTPAssociation::statisticsNumNonRevokableGapBlocksSent
protected

Referenced by createSack().

cOutVector* inet::sctp::SCTPAssociation::statisticsNumNonRevokableGapBlocksStored
protected

Referenced by createSack().

cOutVector* inet::sctp::SCTPAssociation::statisticsNumRevokableGapBlocksSent
protected

Referenced by createSack().

cOutVector* inet::sctp::SCTPAssociation::statisticsNumRevokableGapBlocksStored
protected

Referenced by createSack().

cOutVector* inet::sctp::SCTPAssociation::statisticsNumTotalGapBlocksStored
protected

Referenced by createSack().

cOutVector* inet::sctp::SCTPAssociation::statisticsOutstandingBytes
protected
cOutVector* inet::sctp::SCTPAssociation::statisticsPeerRwnd
protected
cOutVector* inet::sctp::SCTPAssociation::statisticsQueuedReceivedBytes
protected

Referenced by createSack(), and pushUlp().

cOutVector* inet::sctp::SCTPAssociation::statisticsQueuedSentBytes
protected

Referenced by nonRenegablyAckChunk(), and sendOnPath().

cOutVector* inet::sctp::SCTPAssociation::statisticsRevokableGapBlocksInLastSACK
protected

Referenced by processSackArrived().

cOutVector* inet::sctp::SCTPAssociation::statisticsSACKLengthSent
protected

Referenced by createSack().

cOutVector* inet::sctp::SCTPAssociation::statisticsTotalBandwidth
protected
cOutVector* inet::sctp::SCTPAssociation::statisticsTotalCwnd
protected
cOutVector* inet::sctp::SCTPAssociation::statisticsTotalSSthresh
protected
int32 inet::sctp::SCTPAssociation::status
protected
std::map<uint16, cOutVector *> inet::sctp::SCTPAssociation::streamThroughputVectors
cMessage* inet::sctp::SCTPAssociation::T5_ShutdownGuardTimer

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