00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __SCTPASSOCIATION_H
00020 #define __SCTPASSOCIATION_H
00021
00022 #include <omnetpp.h>
00023 #include "IPvXAddress.h"
00024 #include "IPAddress.h"
00025 #include "SCTP.h"
00026 #include "RoutingTable.h"
00027 #include "RoutingTableAccess.h"
00028 #include "InterfaceTable.h"
00029 #include "InterfaceTableAccess.h"
00030 #include "SCTPQueue.h"
00031 #include "SCTPSendStream.h"
00032 #include "SCTPReceiveStream.h"
00033 #include "SCTPMessage.h"
00034 #include "IPControlInfo.h"
00035 #include <list>
00036 #include <iostream>
00037 #include <errno.h>
00038 #include <math.h>
00039 #include <platdep/intxtypes.h>
00040 #include "common.h"
00041
00042
00043 class SCTPMessage;
00044 class SCTPCommand;
00045 class SCTPOpenCommand;
00046 class SCTPReceiveStream;
00047 class SCTPSendStream;
00048 class SCTPAlgorithm;
00049 class SCTP;
00050
00051 typedef std::vector<IPvXAddress> AddressVector;
00052
00053 enum SctpState
00054 {
00055 SCTP_S_CLOSED = 0,
00056 SCTP_S_COOKIE_WAIT = FSM_Steady(1),
00057 SCTP_S_COOKIE_ECHOED = FSM_Steady(2),
00058 SCTP_S_ESTABLISHED = FSM_Steady(3),
00059 SCTP_S_SHUTDOWN_PENDING = FSM_Steady(4),
00060 SCTP_S_SHUTDOWN_SENT = FSM_Steady(5),
00061 SCTP_S_SHUTDOWN_RECEIVED = FSM_Steady(6),
00062 SCTP_S_SHUTDOWN_ACK_SENT = FSM_Steady(7)
00063 };
00064
00065
00066
00067
00068
00069
00070 enum SCTPEventCode
00071 {
00072 SCTP_E_ASSOCIATE,
00073 SCTP_E_OPEN_PASSIVE,
00074 SCTP_E_ABORT,
00075 SCTP_E_SHUTDOWN,
00076 SCTP_E_CLOSE,
00077 SCTP_E_SEND,
00078 SCTP_E_RCV_INIT,
00079 SCTP_E_RCV_ABORT,
00080 SCTP_E_RCV_VALID_COOKIE_ECHO,
00081 SCTP_E_RCV_INIT_ACK,
00082 SCTP_E_RCV_COOKIE_ACK,
00083 SCTP_E_RCV_SHUTDOWN,
00084 SCTP_E_RCV_SHUTDOWN_ACK,
00085 SCTP_E_RCV_SHUTDOWN_COMPLETE,
00086 SCTP_E_NO_MORE_OUTSTANDING,
00087 SCTP_E_TIMEOUT_INIT_TIMER,
00088 SCTP_E_TIMEOUT_SHUTDOWN_TIMER,
00089 SCTP_E_TIMEOUT_RTX_TIMER,
00090 SCTP_E_TIMEOUT_HEARTBEAT_TIMER,
00091 SCTP_E_IGNORE,
00092 SCTP_E_RECEIVE,
00093 SCTP_E_DUP_RECEIVED,
00094 SCTP_E_PRIMARY,
00095 SCTP_E_DELIVERED,
00096 SCTP_E_QUEUE_MSGS_LIMIT,
00097 SCTP_E_QUEUE_BYTES_LIMIT,
00098 SCTP_E_SEND_QUEUE_LIMIT,
00099 SCTP_E_SEND_SHUTDOWN_ACK,
00100 SCTP_E_STOP_SENDING
00101 };
00102
00103 enum SCTPChunkTypes
00104 {
00105 DATA = 0,
00106 INIT = 1,
00107 INIT_ACK = 2,
00108 SACK = 3,
00109 HEARTBEAT = 4,
00110 HEARTBEAT_ACK = 5,
00111 ABORT = 6,
00112 SHUTDOWN = 7,
00113 SHUTDOWN_ACK = 8,
00114 ERRORTYPE = 9,
00115 COOKIE_ECHO = 10,
00116 COOKIE_ACK = 11,
00117 SHUTDOWN_COMPLETE = 14,
00118
00119 };
00120
00121
00122 enum SCTPFlags
00123 {
00124 COMPLETE_MESG_UNORDERED = 1,
00125 COMPLETE_MESG_ORDERED = 0
00126 };
00127
00128
00129 enum SCTPParameterTypes
00130 {
00131 UNRECOGNIZED_PARAMETER = 8,
00132 SUPPORTED_ADDRESS_TYPES = 12,
00133 };
00134
00135
00136
00137
00138 enum SCTPCCModules
00139 {
00140 RFC4960 = 0
00141 };
00142
00143 enum SCTPStreamSchedulers
00144 {
00145 ROUND_ROBIN = 0
00146 };
00147
00148
00149 #define SCTP_COMMON_HEADER 12 // without options
00150 #define SCTP_INIT_CHUNK_LENGTH 20
00151 #define SCTP_DATA_CHUNK_LENGTH 16
00152 #define SCTP_SACK_CHUNK_LENGTH 16
00153 #define SCTP_HEARTBEAT_CHUNK_LENGTH 4
00154 #define SCTP_ABORT_CHUNK_LENGTH 4
00155 #define SCTP_COOKIE_ACK_LENGTH 4
00156 #define SCTP_FORWARD_TSN_CHUNK_LENGTH 8
00157 #define SCTP_SHUTDOWN_CHUNK_LENGTH 8
00158 #define SCTP_SHUTDOWN_ACK_LENGTH 4
00159 #define SCTP_ERROR_CHUNK_LENGTH 4 // without parameters
00160 #define IP_HEADER_LENGTH 20
00161 #define SCTP_DEFAULT_ARWND (1<<16)
00162 #define SCTP_DEFAULT_INBOUND_STREAMS 17
00163 #define SCTP_DEFAULT_OUTBOUND_STREAMS 17
00164 #define VALID_COOKIE_LIFE_TIME 10
00165 #define SCTP_COOKIE_LENGTH 76
00166 #define HB_INTERVAL 30
00167 #define PATH_MAX_RETRANS 5
00168
00169 #define SCTP_TIMEOUT_INIT_REXMIT 3 // initially 3 seconds
00170 #define SCTP_TIMEOUT_INIT_REXMIT_MAX 240 // 4 mins
00171 #define SACK_DELAY 0.2
00172 #define RTO_BETA 0.25
00173 #define RTO_ALPHA 0.125
00174 #define RTO_INITIAL 3
00175 #define IPTOS_DEFAULT 0x10 // IPTOS_LOWDELAY
00176
00177 #define DEFAULT_MAX_SENDQUEUE 0
00178 #define DEFAULT_MAX_RECVQUEUE 0
00179
00180 #define MAX_ASSOCS 10
00181
00182 #define SCTP_MAX_PAYLOAD 1488 // 12 bytes for common header
00183
00184 #define MAX_GAP_COUNT 500
00185 #define MAX_GAP_REPORTS 4
00186 #define ADD_PADDING(x) ((((x) + 3) >> 2) << 2)
00187
00188 #define DEBUG 1
00189
00190 #define SHUTDOWN_GUARD_TIMEOUT 180
00191
00195 inline double min(const double a, const double b) { return (a < b) ? a : b; }
00196
00200 inline double max(const double a, const double b) { return (a < b) ? b : a; }
00201
00202
00203 class INET_API SCTPPathVariables : public cPolymorphic
00204 {
00205 public:
00206 SCTPPathVariables(const IPvXAddress& addr, SCTPAssociation* assoc);
00207 ~SCTPPathVariables();
00208
00209 SCTPAssociation* association;
00210 IPvXAddress remoteAddress;
00211
00212
00213 bool activePath;
00214 bool confirmed;
00215 bool requiresRtx;
00216 bool primaryPathCandidate;
00217 bool forceHb;
00218
00219
00220
00221 bool newCumAck;
00222
00223 uint32 pathErrorCount;
00224 uint32 pathErrorThreshold;
00225 uint32 pmtu;
00226
00227 uint32 cwnd;
00228 uint32 ssthresh;
00229 uint32 partialBytesAcked;
00230 uint32 queuedBytes;
00231 uint32 outstandingBytes;
00232
00233 uint32 outstandingBytesBeforeUpdate;
00234 uint32 newlyAckedBytes;
00235
00236 bool fastRecoveryActive;
00237 uint32 fastRecoveryExitPoint;
00238 simtime_t fastRecoveryEnteringTime;
00239
00240 bool findLowestTSN;
00241 bool lowestTSNRetransmitted;
00242
00243
00244 cMessage* HeartbeatTimer;
00245 cMessage* HeartbeatIntervalTimer;
00246 cMessage* CwndTimer;
00247 cMessage* T3_RtxTimer;
00248
00249
00250 simtime_t heartbeatTimeout;
00251 simtime_t heartbeatIntervalTimeout;
00252 simtime_t rtxTimeout;
00253 simtime_t cwndTimeout;
00254 simtime_t updateTime;
00255 simtime_t lastAckTime;
00256 simtime_t pathRto;
00257 simtime_t srtt;
00258 simtime_t rttvar;
00259
00260
00261 unsigned int gapAcksInLastSACK;
00262 unsigned int gapNAcksInLastSACK;
00263 unsigned int numberOfDuplicates;
00264 unsigned int numberOfFastRetransmissions;
00265 unsigned int numberOfTimerBasedRetransmissions;
00266 unsigned int numberOfHeartbeatsSent;
00267 unsigned int numberOfHeartbeatAcksSent;
00268 unsigned int numberOfHeartbeatsRcvd;
00269 unsigned int numberOfHeartbeatAcksRcvd;
00270
00271
00272 cOutVector* pathTSN;
00273 cOutVector* pathRcvdTSN;
00274 cOutVector* pathHb;
00275 cOutVector* pathRcvdHb;
00276 cOutVector* pathHbAck;
00277 cOutVector* pathRcvdHbAck;
00278 cOutVector* statisticsPathRTO;
00279 cOutVector* statisticsPathRTT;
00280 cOutVector* statisticsPathSSthresh;
00281 cOutVector* statisticsPathCwnd;
00282 };
00283
00284
00285
00286 class INET_API SCTPDataVariables : public cPolymorphic
00287 {
00288 public:
00289 SCTPDataVariables();
00290 ~SCTPDataVariables();
00291
00292 inline void setInitialDestination(SCTPPathVariables* path) {
00293 initialDestination = path;
00294 }
00295 inline const IPvXAddress& getInitialDestination() const {
00296 if(initialDestination != NULL) {
00297 return(initialDestination->remoteAddress);
00298 }
00299 return(zeroAddress);
00300 }
00301 inline SCTPPathVariables* getInitialDestinationPath() const {
00302 return(initialDestination);
00303 }
00304
00305 inline void setLastDestination(SCTPPathVariables* path) {
00306 lastDestination = path;
00307 }
00308 inline const IPvXAddress& getLastDestination() const {
00309 if(lastDestination != NULL) {
00310 return(lastDestination->remoteAddress);
00311 }
00312 return(zeroAddress);
00313 }
00314 inline SCTPPathVariables* getLastDestinationPath() const {
00315 return(lastDestination);
00316 }
00317
00318 inline void setNextDestination(SCTPPathVariables* path) {
00319 nextDestination = path;
00320 }
00321 inline const IPvXAddress& getNextDestination() const {
00322 if(nextDestination != NULL) {
00323 return(nextDestination->remoteAddress);
00324 }
00325 return(zeroAddress);
00326 }
00327 inline SCTPPathVariables* getNextDestinationPath() const {
00328 return(nextDestination);
00329 }
00330
00331 cPacket* userData;
00332 uint32 len;
00333 uint32 booksize;
00334 uint32 tsn;
00335 uint16 sid;
00336 uint16 ssn;
00337 bool enqueuedInTransmissionQ;
00338 bool countsAsOutstanding;
00339 bool hasBeenFastRetransmitted;
00340 bool hasBeenAbandoned;
00341 bool hasBeenReneged;
00342 bool hasBeenAcked;
00343 bool bbit;
00344 bool ebit;
00345 bool ordered;
00346 uint32 ppid;
00347 uint32 gapReports;
00348 simtime_t enqueuingTime;
00349 simtime_t sendTime;
00350 simtime_t ackTime;
00351 simtime_t expiryTime;
00352 uint32 numberOfRetransmissions;
00353 uint32 numberOfTransmissions;
00354 uint32 allowedNoRetransmissions;
00355
00356 public:
00357 static const IPvXAddress zeroAddress;
00358
00359 private:
00360 SCTPPathVariables* initialDestination;
00361 SCTPPathVariables* lastDestination;
00362 SCTPPathVariables* nextDestination;
00363 };
00364
00365
00366
00367 class INET_API SCTPStateVariables : public cPolymorphic
00368 {
00369 public:
00370 SCTPStateVariables();
00371 ~SCTPStateVariables();
00372 public:
00373 inline void setPrimaryPath(SCTPPathVariables* path) {
00374 primaryPath = path;
00375 }
00376 inline const IPvXAddress& getPrimaryPathIndex() const {
00377 if(primaryPath != NULL) {
00378 return(primaryPath->remoteAddress);
00379 }
00380 return(SCTPDataVariables::zeroAddress);
00381 }
00382 inline SCTPPathVariables* getPrimaryPath() const {
00383 return(primaryPath);
00384 }
00385
00386 bool active;
00387 bool fork;
00388 bool ackPointAdvanced;
00389 bool dataChunkReceived;
00390 bool initReceived;
00391 bool cookieEchoReceived;
00392 bool newChunkReceived;
00393 bool firstChunkReceived;
00394 bool swsAvoidanceInvoked;
00395 bool probingIsAllowed;
00396 bool zeroWindowProbing;
00397 bool alwaysBundleSack;
00398 bool fastRecoverySupported;
00399 bool nagleEnabled;
00400 bool sackAllowed;
00401 bool reactivatePrimaryPath;
00402 bool resetPending;
00403 bool stopReceiving;
00404 bool stopOldData;
00405 bool queueUpdate;
00406 bool firstDataSent;
00407 bool peerWindowFull;
00408 bool zeroWindow;
00409 bool stopSending;
00410 bool inOut;
00411 bool noMoreOutstanding;
00412 uint32 numGapReports;
00413 IPvXAddress initialPrimaryPath;
00414 IPvXAddress lastDataSourceAddress;
00415 AddressVector localAddresses;
00416 std::list<uint32> dupList;
00417 uint32 errorCount;
00418 uint64 peerRwnd;
00419 uint64 initialPeerRwnd;
00420 uint64 localRwnd;
00421 uint32 nextTSN;
00422 uint32 lastTsnAck;
00423 uint32 cTsnAck;
00424 uint32 highestTsnReceived;
00425 uint32 highestTsnAcked;
00426 uint32 highestTsnStored;
00427 uint32 lastTsnReceived;
00428 uint32 lastTSN;
00429 uint32 ackState;
00430 uint32 numGaps;
00431 uint32 gapStartList[MAX_GAP_COUNT];
00432 uint32 gapStopList[MAX_GAP_COUNT];
00433 uint64 outstandingBytes;
00434 uint64 queuedReceivedBytes;
00435 uint32 lastStreamScheduled;
00436 uint32 assocPmtu;
00437 uint32 msgNum;
00438 uint64 bytesRcvd;
00439 uint32 numRequests;
00440 uint32 bytesToRetransmit;
00441 uint32 messagesToPush;
00442 int32 pushMessagesLeft;
00443 uint32 count;
00444 uint8 localTieTag[32];
00445 uint8 peerTieTag[32];
00446 uint64 queuedMessages;
00447 uint32 messageAcceptLimit;
00448 uint32 queueLimit;
00449 uint16 header;
00450 int32 probingTimeout;
00451 std::vector<int32> numMsgsReq;
00452 int32 cookieLifeTime;
00454 int16 initRetransCounter;
00455 simtime_t initRexmitTimeout;
00457 SCTPInitChunk* initChunk;
00459 SCTPCookieEchoChunk* cookieChunk;
00461 SCTPShutdownChunk* shutdownChunk;
00462 SCTPShutdownAckChunk* shutdownAckChunk;
00463 SCTPMessage* sctpmsg;
00464 uint64 sendQueueLimit;
00465 uint64 sendBuffer;
00466 bool appSendAllowed;
00467 simtime_t lastSendQueueAbated;
00468 uint32 nextRSid;
00469 uint32 swsLimit;
00470 bool lastMsgWasFragment;
00471 bool enableHeartbeats;
00472 SCTPMessage* sctpMsg;
00473 uint16 chunksAdded;
00474 uint16 dataChunksAdded;
00475 uint32 packetBytes;
00476 bool authAdded;
00477
00478 uint32 maxBurst;
00479 bool ssNextStream;
00480 bool ssLastDataChunkSizeSet;
00481
00482 private:
00483 SCTPPathVariables* primaryPath;
00484 };
00485
00486
00487
00488 class INET_API SCTPAssociation : public cObject
00489 {
00490 friend class SCTP;
00491 friend class SCTPPathVariables;
00492
00493
00494 typedef std::map<IPvXAddress,SCTPPathVariables*> SCTPPathMap;
00495
00496 typedef std::map<IPvXAddress, uint32> CounterMap;
00497 typedef struct counter {
00498 uint64 roomSumSendStreams;
00499 uint64 bookedSumSendStreams;
00500 uint64 roomSumRcvStreams;
00501 CounterMap roomTransQ;
00502 CounterMap bookedTransQ;
00503 CounterMap roomRetransQ;
00504 } QueueCounter;
00505 typedef struct calcBytesToSend {
00506 bool chunk;
00507 bool packet;
00508 uint32 bytesToSend;
00509 } BytesToBeSent;
00510 typedef struct congestionControlFunctions {
00511 void (SCTPAssociation::*ccInitParams)(SCTPPathVariables* path);
00512 void (SCTPAssociation::*ccUpdateAfterSack)();
00513 void (SCTPAssociation::*ccUpdateAfterCwndTimeout)(SCTPPathVariables* path);
00514 void (SCTPAssociation::*ccUpdateAfterRtxTimeout)(SCTPPathVariables* path);
00515 void (SCTPAssociation::*ccUpdateMaxBurst)(SCTPPathVariables* path);
00516 void (SCTPAssociation::*ccUpdateBytesAcked)(SCTPPathVariables* path, const uint32 ackedBytes, const bool ctsnaAdvanced);
00517 } CCFunctions;
00518 typedef std::map<uint32, SCTPSendStream*> SCTPSendStreamMap;
00519 typedef std::map<uint32, SCTPReceiveStream*> SCTPReceiveStreamMap;
00520
00521 public:
00522
00523 int32 appGateIndex;
00524 int32 assocId;
00525 IPvXAddress remoteAddr;
00526 IPvXAddress localAddr;
00527 uint16 localPort;
00528 uint16 remotePort;
00529 uint32 localVTag;
00530 uint32 peerVTag;
00531 bool listen;
00532
00533
00534 cMessage* T1_InitTimer;
00535 cMessage* T2_ShutdownTimer;
00536 cMessage* T5_ShutdownGuardTimer;
00537 cMessage* SackTimer;
00538 cMessage* StartTesting;
00539
00540 protected:
00541 AddressVector localAddressList;
00542 AddressVector remoteAddressList;
00543 uint32 numberOfRemoteAddresses;
00544 uint32 inboundStreams;
00545 uint32 outboundStreams;
00546
00547 int32 status;
00548 uint32 initTsn;
00549 uint32 initPeerTsn;
00550 uint32 sackFrequency;
00551 double sackPeriod;
00552 CCFunctions ccFunctions;
00553 uint16 ccModule;
00554
00555 cOutVector* advRwnd;
00556 cOutVector* cumTsnAck;
00557 cOutVector* sendQueue;
00558 cOutVector* numGapBlocks;
00559
00560
00561 SCTPStateVariables* state;
00562 BytesToBeSent bytes;
00563 SCTP* sctpMain;
00564 cFSM* fsm;
00565 SCTPPathMap sctpPathMap;
00566 QueueCounter qCounter;
00567 SCTPQueue* transmissionQ;
00568 SCTPQueue* retransmissionQ;
00569 SCTPSendStreamMap sendStreams;
00570 SCTPReceiveStreamMap receiveStreams;
00571 SCTPAlgorithm* sctpAlgorithm;
00572
00573 public:
00577 SCTPAssociation(SCTP* mod, int32 appGateIndex, int32 assocId);
00581 ~SCTPAssociation();
00585 void sendOnPath(SCTPPathVariables* pathId, const bool firstPass = true);
00586 void sendOnAllPaths(SCTPPathVariables* firstPath);
00587
00589 static const char* indicationName(const int32 code);
00590
00591
00593 inline int32 getFsmState() const { return fsm->getState(); };
00594 inline SCTPStateVariables* getState() const { return state; };
00595 inline SCTPQueue* getTransmissionQueue() const { return transmissionQ; };
00596 inline SCTPQueue* getRetransmissionQueue() const { return retransmissionQ; };
00597 inline SCTPAlgorithm* getSctpAlgorithm() const { return sctpAlgorithm; };
00598 inline SCTP* getSctpMain() const { return sctpMain; };
00599 inline cFSM* getFsm() const { return fsm; };
00600 inline cMessage* getInitTimer() const { return T1_InitTimer; };
00601 inline cMessage* getShutdownTimer() const { return T2_ShutdownTimer; };
00602 inline cMessage* getSackTimer() const { return SackTimer; };
00603
00605 static const char* stateName(const int32 state);
00606
00607 static uint32 chunkToInt(const char* type);
00608
00609
00610
00611
00612
00613 bool processTimer(cMessage* msg);
00619 bool processSCTPMessage(SCTPMessage* sctpmsg, const IPvXAddress& srcAddr, const IPvXAddress& destAddr);
00625 bool processAppCommand(cPacket* msg);
00626 void removePath();
00627 void removePath(const IPvXAddress& addr);
00628 void deleteStreams();
00629 void stopTimer(cMessage* timer);
00630 void stopTimers();
00631 inline SCTPPathVariables* getPath(const IPvXAddress& pathId) const {
00632 SCTPPathMap::const_iterator iterator = sctpPathMap.find(pathId);
00633 if (iterator !=sctpPathMap.end()) {
00634 return iterator->second;
00635 }
00636 return NULL;
00637 }
00638 void printSctpPathMap() const;
00639
00640
00641 protected:
00645 SCTPEventCode preanalyseAppCommandEvent(int32 commandCode);
00647 bool performStateTransition(const SCTPEventCode& event);
00648 void stateEntered(int32 state);
00650
00652 void process_ASSOCIATE(SCTPEventCode& event, SCTPCommand* sctpCommand, cPacket* msg);
00653 void process_OPEN_PASSIVE(SCTPEventCode& event, SCTPCommand* sctpCommand, cPacket* msg);
00654 void process_SEND(SCTPEventCode& event, SCTPCommand* sctpCommand, cPacket* msg);
00655 void process_CLOSE(SCTPEventCode& event);
00656 void process_ABORT(SCTPEventCode& event);
00657 void process_STATUS(SCTPEventCode& event, SCTPCommand* sctpCommand, cPacket* msg);
00658 void process_RECEIVE_REQUEST(SCTPEventCode& event, SCTPCommand* sctpCommand);
00659 void process_PRIMARY(SCTPEventCode& event, SCTPCommand* sctpCommand);
00661
00664 bool process_RCV_Message(SCTPMessage* sctpseg, const IPvXAddress& src, const IPvXAddress& dest);
00668 bool processInitArrived(SCTPInitChunk* initChunk, int32 sport, int32 dport);
00669 bool processInitAckArrived(SCTPInitAckChunk* initAckChunk);
00670 bool processCookieEchoArrived(SCTPCookieEchoChunk* cookieEcho, IPvXAddress addr);
00671 bool processCookieAckArrived();
00672 SCTPEventCode processDataArrived(SCTPDataChunk* dataChunk);
00673 SCTPEventCode processSackArrived(SCTPSackChunk* sackChunk);
00674 SCTPEventCode processHeartbeatAckArrived(SCTPHeartbeatAckChunk* heartbeatack, SCTPPathVariables* path);
00676
00679 int32 process_TIMEOUT_RTX(SCTPPathVariables* path);
00680 void process_TIMEOUT_HEARTBEAT(SCTPPathVariables* path);
00681 void process_TIMEOUT_HEARTBEAT_INTERVAL(SCTPPathVariables* path, bool force);
00682 void process_TIMEOUT_INIT_REXMIT(SCTPEventCode& event);
00683 void process_TIMEOUT_PROBING();
00684 void process_TIMEOUT_SHUTDOWN(SCTPEventCode& event);
00685 int32 updateCounters(SCTPPathVariables* path);
00687
00688 void startTimer(cMessage* timer, const simtime_t& timeout);
00689
00691 SCTPAssociation* cloneAssociation();
00692
00694 void initAssociation(SCTPOpenCommand* openCmd);
00695
00697 bool tsnIsDuplicate(const uint32 tsn) const;
00698 bool advanceCtsna();
00699 bool updateGapList(const uint32 tsn);
00700 void removeFromGapList(const uint32 removedTsn);
00701 bool makeRoomForTsn(const uint32 tsn, const uint32 length, const bool uBit);
00702
00704 void sendInit();
00705 void sendInitAck(SCTPInitChunk* initchunk);
00706 void sendCookieEcho(SCTPInitAckChunk* initackchunk);
00707 void sendCookieAck(const IPvXAddress& dest);
00708 void sendAbort();
00709 void sendHeartbeat(const SCTPPathVariables* path);
00710 void sendHeartbeatAck(const SCTPHeartbeatChunk* heartbeatChunk,
00711 const IPvXAddress& src,
00712 const IPvXAddress& dest);
00713 void sendSack();
00714 void sendShutdown();
00715 void sendShutdownAck(const IPvXAddress& dest);
00716 void sendShutdownComplete();
00717 SCTPSackChunk* createSack();
00719 void retransmitInit();
00720 void retransmitCookieEcho();
00721 void retransmitShutdown();
00722 void retransmitShutdownAck();
00723
00725 void sendToIP(SCTPMessage* sctpmsg, const IPvXAddress& dest, const bool qs = false);
00726 inline void sendToIP(SCTPMessage* sctpmsg, const bool qs = false) {
00727 sendToIP(sctpmsg, remoteAddr, qs);
00728 }
00729 void recordInPathVectors(SCTPMessage* pMsg, const IPvXAddress& rDest);
00730 void scheduleSack();
00732 void signalConnectionTimeout();
00733
00735 inline void scheduleTimeout(cMessage* msg, const simtime_t& timeout) {
00736 sctpMain->scheduleAt(simulation.getSimTime() + timeout, msg);
00737 }
00738
00740 inline cMessage* cancelEvent(cMessage* msg) {
00741 return sctpMain->cancelEvent(msg);
00742 }
00743
00745 void sendToApp(cPacket* msg);
00746
00748 void sendIndicationToApp(const int32 code, const int32 value = 0);
00749
00751 void sendEstabIndicationToApp();
00752 void pushUlp();
00753 void sendDataArrivedNotification(uint16 sid);
00754 void putInDeliveryQ(uint16 sid);
00756 void printConnBrief();
00758 static void printSegmentBrief(SCTPMessage* sctpmsg);
00759
00760
00762 static const char* eventName(const int32 event);
00763
00764 void addPath(const IPvXAddress& addr);
00765 SCTPPathVariables* getNextPath(const SCTPPathVariables* oldPath) const;
00766 inline const IPvXAddress& getNextAddress(const SCTPPathVariables* oldPath) const {
00767 const SCTPPathVariables* nextPath = getNextPath(oldPath);
00768 if(nextPath != NULL) {
00769 return(nextPath->remoteAddress);
00770 }
00771 return(SCTPDataVariables::zeroAddress);
00772 }
00773 SCTPPathVariables* getNextDestination(SCTPDataVariables* chunk) const;
00774
00775 void bytesAllowedToSend(SCTPPathVariables* path, const bool firstPass);
00776
00777 void pathStatusIndication(const SCTPPathVariables* path, const bool status);
00778
00779 bool allPathsInactive() const;
00780
00784 SCTPDataChunk* transformDataChunk(SCTPDataVariables* chunk);
00785 SCTPDataVariables* makeVarFromMsg(SCTPDataChunk* datachunk);
00786
00791 int32 streamScheduler(bool peek);
00792 void initStreams(uint32 inStreams, uint32 outStreams);
00793 int32 numUsableStreams();
00794 typedef struct streamSchedulingFunctions {
00795 void (SCTPAssociation::*ssInitStreams)(uint32 inStreams, uint32 outStreams);
00796 int32 (SCTPAssociation::*ssGetNextSid)(bool peek);
00797 int32 (SCTPAssociation::*ssUsableStreams)();
00798 } SSFunctions;
00799 SSFunctions ssFunctions;
00800 uint16 ssModule;
00801
00805 void process_QUEUE_MSGS_LIMIT(const SCTPCommand* sctpCommand);
00806 void process_QUEUE_BYTES_LIMIT(const SCTPCommand* sctpCommand);
00807 int32 getOutstandingBytes() const;
00808 uint32 dequeueAckedChunks(const uint32 tsna,
00809 SCTPPathVariables* path,
00810 simtime_t& rttEstimation);
00811 SCTPDataMsg* peekOutboundDataMsg();
00812 SCTPDataVariables* peekAbandonedChunk(const SCTPPathVariables* path);
00813 SCTPDataVariables* getOutboundDataChunk(const SCTPPathVariables* path,
00814 const int32 availableSpace,
00815 const int32 availableCwnd);
00816 SCTPDataMsg* dequeueOutboundDataMsg(const int32 availableSpace,
00817 const int32 availableCwnd);
00818 bool nextChunkFitsIntoPacket(int32 bytes);
00819 void putInTransmissionQ(uint32 tsn, SCTPDataVariables* chunk);
00823 void pmStartPathManagement();
00824 void pmDataIsSentOn(SCTPPathVariables* path);
00825 void pmClearPathCounter(SCTPPathVariables* path);
00826 void pmRttMeasurement(SCTPPathVariables* path,
00827 const simtime_t& rttEstimation);
00831 inline static int32 tsnLt (const uint32 tsn1, const uint32 tsn2) { return ((int32)(tsn1-tsn2)<0); }
00832 inline static int32 tsnLe (const uint32 tsn1, const uint32 tsn2) { return ((int32)(tsn1-tsn2)<=0); }
00833 inline static int32 tsnGe (const uint32 tsn1, const uint32 tsn2) { return ((int32)(tsn1-tsn2)>=0); }
00834 inline static int32 tsnGt (const uint32 tsn1, const uint32 tsn2) { return ((int32)(tsn1-tsn2)>0); }
00835 inline static int32 tsnBetween (const uint32 tsn1, const uint32 midtsn, const uint32 tsn2) { return ((tsn2-tsn1)>=(midtsn-tsn1)); }
00836
00837 inline static int16 ssnGt (const uint16 ssn1, const uint16 ssn2) { return ((int16)(ssn1-ssn2)>0); }
00838
00839 void disposeOf(SCTPMessage* sctpmsg);
00840 void tsnWasReneged(SCTPDataVariables* chunk,
00841 const int type);
00842 void printOutstandingTsns();
00843
00845 void initCCParameters(SCTPPathVariables* path);
00846 void updateFastRecoveryStatus(const uint32 lastTsnAck);
00847 void cwndUpdateAfterSack();
00848 void cwndUpdateAfterCwndTimeout(SCTPPathVariables* path);
00849 void cwndUpdateAfterRtxTimeout(SCTPPathVariables* path);
00850 void cwndUpdateMaxBurst(SCTPPathVariables* path);
00851 void cwndUpdateBytesAcked(SCTPPathVariables* path,
00852 const uint32 ackedBytes,
00853 const bool ctsnaAdvanced);
00854
00855 private:
00856 SCTPDataVariables* makeDataVarFromDataMsg(SCTPDataMsg* datMsg,
00857 SCTPPathVariables* path);
00858 SCTPPathVariables* choosePathForRetransmission();
00859 void timeForSack(bool& sackOnly, bool& sackWithData);
00860 void recordCwndUpdate(SCTPPathVariables* path);
00861 void handleChunkReportedAsAcked(uint32& highestNewAck,
00862 simtime_t& rttEstimation,
00863 SCTPDataVariables* myChunk,
00864 SCTPPathVariables* sackPath);
00865 void handleChunkReportedAsMissing(const SCTPSackChunk* sackChunk,
00866 const uint32 highestNewAck,
00867 SCTPDataVariables* myChunk,
00868 const SCTPPathVariables* sackPath);
00869 void moveChunkToOtherPath(SCTPDataVariables* chunk,
00870 SCTPPathVariables* newPath);
00871 void decreaseOutstandingBytes(SCTPDataVariables* chunk);
00872 void increaseOutstandingBytes(SCTPDataVariables* chunk,
00873 SCTPPathVariables* path);
00874 int32 calculateBytesToSendOnPath(const SCTPPathVariables* pathVar);
00875 void storePacket(SCTPPathVariables* pathVar,
00876 SCTPMessage* sctpMsg,
00877 const uint16 chunksAdded,
00878 const uint16 dataChunksAdded,
00879 const uint32 packetBytes,
00880 const bool authAdded);
00881 void loadPacket(SCTPPathVariables* pathVar,
00882 SCTPMessage** sctpMsg,
00883 uint16* chunksAdded,
00884 uint16* dataChunksAdded,
00885 uint32* packetBytes,
00886 bool* authAdded);
00887 inline void ackChunk(SCTPDataVariables* chunk) {
00888 chunk->hasBeenAcked = true;
00889 }
00890 inline void unackChunk(SCTPDataVariables* chunk) {
00891 chunk->hasBeenAcked = false;
00892 }
00893 inline bool chunkHasBeenAcked(const SCTPDataVariables* chunk) const {
00894 return(chunk->hasBeenAcked);
00895 }
00896 inline bool chunkHasBeenAcked(const uint32 tsn) const {
00897 const SCTPDataVariables* chunk = retransmissionQ->getChunk(tsn);
00898 if(chunk) {
00899 return(chunkHasBeenAcked(chunk));
00900 }
00901 return(false);
00902 }
00903 };
00904
00905 #endif