• Main Page
  • Classes
  • Files
  • File List

/Users/yzchen/ns/ns-allinone-2.33/ns-2.33/sctp/sctp.h

00001 /*
00002  * Copyright (c) 2006-2007 by the Protocol Engineering Lab, U of Delaware
00003  * All rights reserved.
00004  *
00005  * Protocol Engineering Lab web page : http://pel.cis.udel.edu/
00006  *
00007  * Paul D. Amer        <amer@@cis,udel,edu>
00008  * Armando L. Caro Jr. <acaro@@cis,udel,edu>
00009  * Janardhan Iyengar   <iyengar@@cis,udel,edu>
00010  * Preethi Natarajan   <nataraja@@cis,udel,edu>
00011  * Nasif Ekiz          <nekiz@@cis,udel,edu>
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions
00015  * are met:
00016  *
00017  * 1. Redistributions of source code must retain the above copyright
00018  *    notice, this list of conditions and the following disclaimer.
00019  *
00020  * 2. Redistributions in binary form must reproduce the above copyright
00021  *    notice, this list of conditions and the following disclaimer in the
00022  *    documentation and/or other materials provided with the distribution.
00023  *
00024  * 3. Neither the name of the University nor of the Laboratory may be used
00025  *    to endorse or promote products derived from this software without
00026  *    specific prior written permission.
00027  *
00028  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00029  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00030  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00031  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00032  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00033  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00034  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00035  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00036  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00037  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00038  * SUCH DAMAGE.
00039  *
00040  * @(#) $Header: /cvsroot/nsnam/ns-2/sctp/sctp.h,v 1.10 2007/06/17 21:44:45 tom_henderson Exp $ (UD/PEL)
00041  */
00042 
00043 #ifndef ns_sctp_h
00044 #define ns_sctp_h
00045 
00046 #include "agent.h"
00047 #include "node.h"
00048 #include "packet.h"
00049 
00050 /* The SCTP Common header is 12 bytes.
00051  */
00052 #define SCTP_HDR_SIZE         12
00053 
00054 #define MAX_RWND_SIZE         0xffffffff
00055 #define MAX_DATA_CHUNK_SIZE   0xffffffff
00056 #define MIN_DATA_CHUNK_SIZE   16
00057 #define MAX_NUM_STREAMS       0x0000ffff
00058 
00059 #define DELAYED_SACK_TRIGGER  2      // sack for every 2 data packets
00060 
00061 #define RTO_ALPHA             0.125  // RTO.alpha is 1/8
00062 #define RTO_BETA              0.25   // RTO.Beta is 1/4
00063 
00064 #define MAX_BURST             4
00065 enum MaxBurstUsage_E
00066 {
00067   MAX_BURST_USAGE_OFF,      // 0
00068   MAX_BURST_USAGE_ON        // 1
00069 };
00070 
00071 /* Let us use OUR typedef'd enum for FALSE and TRUE. It's much better this way.
00072  * ...why? because NOW all boolean variables can be explicitly declared as
00073  * such. There is no longer any ambiguity between a regular int variable and a
00074  * boolean variable.  
00075  */
00076 #undef FALSE
00077 #undef TRUE
00078 enum Boolean_E
00079 {
00080   FALSE,
00081   TRUE
00082 };
00083 
00084 /* Each time the sender retransmits marked chunks, how many can be sent? Well,
00085  * immediately after a timeout or when the 4 missing report is received, only
00086  * one packet of retransmits may be sent. Later, the number of packets is gated
00087  * by cwnd
00088  */
00089 enum SctpRtxLimit_E
00090 {
00091   RTX_LIMIT_ONE_PACKET,
00092   RTX_LIMIT_CWND,
00093   RTX_LIMIT_ZERO
00094 };
00095 
00096 enum MarkedForRtx_E
00097 {
00098   NO_RTX,
00099   FAST_RTX,
00100   TIMEOUT_RTX
00101 };
00102 
00103 enum RtxToAlt_E
00104 {
00105   RTX_TO_ALT_OFF,
00106   RTX_TO_ALT_ON,
00107   RTX_TO_ALT_TIMEOUTS_ONLY
00108 };
00109 
00110 /* What behavior is used during dormant state (ie, all destinations have
00111  * failed) when timeouts persist?
00112  */
00113 enum DormantAction_E
00114 {
00115   DORMANT_HOP,        // keep hopping to another destination
00116   DORMANT_PRIMARY,    // goto primary and stay there
00117   DORMANT_LASTDEST    // stay at the last destination used before dormant state
00118 };
00119 
00120 /* Who controls the data sending, app layer or the transport layer 
00121  * (as in the case of infinite data)
00122  */
00123 enum DataSource_E
00124 {
00125   DATA_SOURCE_APPLICATION,
00126   DATA_SOURCE_INFINITE
00127 };
00128 
00129 /* SCTP chunk types 
00130  */
00131 enum SctpChunkType_E
00132 {
00133   SCTP_CHUNK_DATA,
00134   SCTP_CHUNK_INIT,
00135   SCTP_CHUNK_INIT_ACK,
00136   SCTP_CHUNK_SACK,
00137   SCTP_CHUNK_HB,
00138   SCTP_CHUNK_HB_ACK,
00139   SCTP_CHUNK_ABORT,
00140   SCTP_CHUNK_SHUTDOWN,
00141   SCTP_CHUNK_SHUTDOWN_ACK,
00142   SCTP_CHUNK_ERROR,
00143   SCTP_CHUNK_COOKIE_ECHO,
00144   SCTP_CHUNK_COOKIE_ACK,
00145   SCTP_CHUNK_ECNE,                  // reserved in rfc2960
00146   SCTP_CHUNK_CWR,                   // reserved in rfc2960
00147   SCTP_CHUNK_SHUTDOWN_COMPLETE,
00148 
00149   /* RFC2960 leaves room for later defined chunks */
00150 
00151   /* for U-SCTP/PR-SCTP
00152    */
00153   SCTP_CHUNK_FORWARD_TSN,    // should be 192, but this is a simulation! :-)
00154 
00155   /* for timestamp option (sctp-timestamp.cc)
00156    */
00157   SCTP_CHUNK_TIMESTAMP
00158 };
00159 
00160 struct AppData_S 
00161 {
00162   /* Parameters needed for establishing an association 
00163    */
00164   u_short usNumStreams;     // Number of streams to associate
00165   u_short usNumUnreliable;  // first usNumUnreliable streams will be unreliable
00166 
00167   /* Parameters needed for app data messages 
00168    */
00169   u_short    usStreamId;     // Which stream does this message go on?
00170   u_short    usReliability;  // What level of relability does this message have
00171   Boolean_E  eUnordered;     // Is this an unordered message?
00172   u_int      uiNumBytes;     // Number of databytes in message
00173 };
00174 
00175 /* ns specific header fields used for tracing SCTP traffic
00176  * (This was done so that the 'trace' module wouldn't have to look into the
00177  * payload of SCTP packets)
00178  */
00179 struct SctpTrace_S
00180 {
00181   SctpChunkType_E  eType;
00182   u_int            uiTsn;   // (cum ack for sacks, -1 for other control chunks)
00183   u_short          usStreamId;     // -1 for control chunks
00184   u_short          usStreamSeqNum; // -1 for control chunks
00185 };
00186 
00187 struct hdr_sctp
00188 {
00189   /* ns required header fields/methods 
00190    */
00191   static int offset_;   // offset for this header
00192   inline static int& offset() { return offset_; }
00193   inline static hdr_sctp* access(Packet* p) 
00194   {
00195     return (hdr_sctp*) p->access(offset_);
00196   }
00197 
00198   /* ns specific header fields used for tracing SCTP traffic
00199    * (This was done so that the 'trace' module wouldn't have to look into the
00200    * payload of SCTP packets)
00201    */
00202   u_int         uiNumChunks;
00203   SctpTrace_S  *spSctpTrace;
00204 
00205   u_int&        NumChunks() { return uiNumChunks; }
00206   SctpTrace_S*& SctpTrace() { return spSctpTrace; }
00207 };
00208 
00209 struct SctpChunkHdr_S
00210 {
00211   u_char  ucType;
00212   u_char  ucFlags;
00213   u_short usLength;
00214 };
00215 
00216 /* INIT paramater types
00217  */
00218 #define SCTP_INIT_PARAM_UNREL  0xC000
00219 struct SctpUnrelStreamsParam_S
00220 {
00221   u_short  usType;
00222   u_short  usLength;
00223 
00224   /* unreliable stream start-end pairs are appended dynamically
00225    */
00226 };
00227 
00228 struct SctpUnrelStreamPair_S
00229 {
00230   u_short  usStart;
00231   u_short  usEnd;
00232 };
00233 
00234 struct SctpInitChunk_S  // this is used for init ack, too 
00235 {
00236   SctpChunkHdr_S  sHdr;
00237   u_int           uiInitTag;             // tag of mine (not used)
00238   u_int           uiArwnd;               // referred to as a_rwnd in rfc2960
00239   u_short         usNumOutboundStreams;  // referred to as OS in rfc2960
00240   u_short         usMaxInboundStreams;   // referred to as MIS in rfc2960
00241   u_int           uiInitialTsn;          
00242 
00243   SctpUnrelStreamsParam_S  sUnrelStream;        
00244 };
00245 typedef SctpInitChunk_S SctpInitAckChunk_S;
00246 
00247 struct SctpCookieEchoChunk_S
00248 {
00249   SctpChunkHdr_S  sHdr;
00250         
00251   /* cookie would go here, but we aren't implementing this at the moment */
00252 };
00253 typedef SctpCookieEchoChunk_S SctpCookieAckChunk_S;
00254 
00255 struct SctpDataChunkHdr_S
00256 {
00257   SctpChunkHdr_S  sHdr;
00258   u_int           uiTsn;
00259   u_short         usStreamId;
00260   u_short         usStreamSeqNum;
00261   u_int           uiPayloadType;     // not used
00262 
00263   /* user data must be appended dynamically when filling packets */
00264 };
00265 
00266 /* Data Chunk Specific Flags
00267  */
00268 #define SCTP_DATA_FLAG_END        0x01  // indicates last fragment
00269 #define SCTP_DATA_FLAG_BEGINNING  0x02  // indicates first fragment
00270 #define SCTP_DATA_FLAG_UNORDERED  0x04  // indicates unordered DATA chunk
00271 
00272 /* SACK has the following structure and following it will be some number of
00273  * gap acks and duplicate tsns.
00274  */
00275 struct SctpSackChunk_S
00276 {
00277   SctpChunkHdr_S  sHdr;
00278   u_int           uiCumAck;
00279   u_int           uiArwnd;
00280   u_short         usNumGapAckBlocks;
00281   u_short         usNumDupTsns;
00282 
00283   /* Gap Ack Blocks and Duplicate TSNs are appended dynamically
00284    */
00285 };
00286 
00287 struct SctpGapAckBlock_S
00288 {
00289   u_short  usStartOffset;
00290   u_short  usEndOffset;
00291 };
00292 
00293 struct SctpDupTsn_S
00294 {
00295   u_int  uiTsn;
00296 };
00297 
00298 #define SCTP_CHUNK_FORWARD_TSN_LENGTH  8
00299 struct SctpForwardTsnChunk_S
00300 {
00301   SctpChunkHdr_S  sHdr;
00302   u_int           uiNewCum;
00303 };
00304 
00305 struct SctpDest_S;
00306 #define SCTP_CHUNK_HEARTBEAT_LENGTH  24
00307 struct SctpHeartbeatChunk_S
00308 {
00309   SctpChunkHdr_S  sHdr;
00310   u_short         usInfoType;      // filled in, but not really used
00311   u_short         usInfoLength;    // filled in, but not really used
00312   double          dTimestamp;
00313   SctpDest_S     *spDest;
00314 };
00315 typedef SctpHeartbeatChunk_S SctpHeartbeatAckChunk_S;
00316 
00317 /* SCTP state defines for internal state machine */
00318 enum SctpState_E
00319 {
00320   SCTP_STATE_UNINITIALIZED,
00321   SCTP_STATE_CLOSED,
00322   SCTP_STATE_ESTABLISHED,
00323   SCTP_STATE_COOKIE_WAIT,
00324   SCTP_STATE_COOKIE_ECHOED,
00325   SCTP_STATE_SHUTDOWN_SENT,        // not currently used
00326   SCTP_STATE_SHUTDOWN_RECEIVED,    // not currently used
00327   SCTP_STATE_SHUTDOWN_ACK_SENT,    // not currently used
00328   SCTP_STATE_SHUTDOWN_PENDING      // not currently used
00329 };
00330 
00331 class SctpAgent;
00332 
00333 class T1InitTimer : public TimerHandler 
00334 {
00335 public:
00336   T1InitTimer(SctpAgent *a) : TimerHandler(), opAgent(a) { }
00337         
00338 protected:
00339   virtual void expire(Event *);
00340   SctpAgent *opAgent;
00341 };
00342 
00343 class T1CookieTimer : public TimerHandler 
00344 {
00345 public:
00346   T1CookieTimer(SctpAgent *a) : TimerHandler(), opAgent(a) { }
00347         
00348 protected:
00349   virtual void expire(Event *);
00350   SctpAgent *opAgent;
00351 };
00352 
00353 class T3RtxTimer : public TimerHandler 
00354 {
00355 public:
00356   T3RtxTimer(SctpAgent *a, SctpDest_S *d) 
00357     : TimerHandler(), opAgent(a) {spDest = d;}
00358         
00359 protected:
00360   virtual void expire(Event *);
00361   SctpAgent  *opAgent;
00362   SctpDest_S *spDest;  // destination this timer corresponds to
00363 };
00364 
00365 class CwndDegradeTimer : public TimerHandler 
00366 {
00367 public:
00368   CwndDegradeTimer(SctpAgent *a, SctpDest_S *d) 
00369     : TimerHandler(), opAgent(a) {spDest = d;}
00370         
00371 protected:
00372   virtual void expire(Event *);
00373   SctpAgent  *opAgent;
00374   SctpDest_S *spDest;  // destination this timer corresponds to
00375 };
00376 
00377 class HeartbeatGenTimer : public TimerHandler 
00378 {
00379 public:
00380   HeartbeatGenTimer(SctpAgent *a) 
00381     : TimerHandler(), opAgent(a) {}
00382 
00383   double      dStartTime; // timestamp of when timer started
00384         
00385 protected:
00386   virtual void expire(Event *);
00387   SctpAgent  *opAgent;
00388 };
00389 
00390 class HeartbeatTimeoutTimer : public TimerHandler 
00391 {
00392 public:
00393   HeartbeatTimeoutTimer(SctpAgent *a, SctpDest_S *d) 
00394     : TimerHandler(), opAgent(a) {spDest = d;}
00395         
00396   SctpDest_S *spDest;  // destination this timer corresponds to
00397 
00398 protected:
00399   virtual void expire(Event *);
00400   SctpAgent  *opAgent;
00401 };
00402 
00403 /* This timer simulates the route lifetime in the routing tables of
00404  * reactive routing protocols for MANETs, etc. When this timer expires,
00405  * the route is flushed and any future data sent to this dest will cause a 
00406  * route calculation.
00407  *
00408  * Note: This timer is not normally used. It's only for our simulated reactive
00409  * routing overheads for MANETs, etc. 
00410  */
00411 class RouteCacheFlushTimer : public TimerHandler 
00412 {
00413 public:
00414   RouteCacheFlushTimer(SctpAgent *a, SctpDest_S *d) 
00415     : TimerHandler(), opAgent(a) {spDest = d;}
00416         
00417 protected:
00418   virtual void expire(Event *);
00419   SctpAgent  *opAgent;
00420   SctpDest_S *spDest;  // destination this timer corresponds to
00421 };
00422 
00423 /* This timer simulates the time it takes to calculate a route in
00424  * reactive routing protocols for MANETs, etc. 
00425  *
00426  * Note: This timer is not normally used. It's only for our simulated reactive
00427  * routing overheads for MANETs, etc. 
00428  */
00429 class RouteCalcDelayTimer : public TimerHandler 
00430 {
00431 public:
00432   RouteCalcDelayTimer(SctpAgent *a, SctpDest_S *d) 
00433     : TimerHandler(), opAgent(a) {spDest = d;}
00434         
00435 protected:
00436   virtual void expire(Event *);
00437   SctpAgent  *opAgent;
00438   SctpDest_S *spDest;  // destination this timer corresponds to
00439 };
00440 
00441 struct SctpInterface_S
00442 {
00443   int        iNsAddr;
00444   int        iNsPort;
00445   NsObject  *opTarget;
00446   NsObject  *opLink;
00447 };
00448 
00449 enum SctpDestStatus_E
00450 {
00451   SCTP_DEST_STATUS_INACTIVE,
00452   SCTP_DEST_STATUS_POSSIBLY_FAILED,
00453   SCTP_DEST_STATUS_ACTIVE,
00454   SCTP_DEST_STATUS_UNCONFIRMED
00455 };
00456 
00457 enum NodeType_E
00458 {
00459   NODE_TYPE_STREAM_BUFFER,
00460   NODE_TYPE_RECV_TSN_BLOCK,
00461   NODE_TYPE_DUP_TSN,
00462   NODE_TYPE_SEND_BUFFER,
00463   NODE_TYPE_APP_LAYER_BUFFER,
00464   NODE_TYPE_INTERFACE_LIST,
00465   NODE_TYPE_DESTINATION_LIST,
00466   NODE_TYPE_PACKET_BUFFER
00467 };
00468 
00469 struct Node_S
00470 {
00471   NodeType_E  eType;
00472   void       *vpData;   // u can put any data type into the node
00473   Node_S     *spNext;
00474   Node_S     *spPrev;
00475 };
00476 
00477 struct List_S
00478 {
00479   u_int    uiLength;
00480   Node_S  *spHead;
00481   Node_S  *spTail;
00482 };
00483 
00484 struct SctpSendBufferNode_S;
00485 struct SctpDest_S
00486 {
00487   int        iNsAddr;  // ns "IP address"
00488   int        iNsPort;  // ns "port"
00489 
00490   /* Packet is simply used for determing src addr. The header stores dest addr,
00491    * which makes it easy to determine src target using
00492    * Connector->find(Packet *). Then with the target, we can determine src 
00493    * addr.
00494    */
00495   Packet    *opRoutingAssistPacket;
00496 
00497   int           iCwnd;                // current congestion window
00498   int           iSsthresh;            // current ssthresh value
00499   Boolean_E     eFirstRttMeasurement; // is this our first RTT measurement?
00500   double        dRto;                 // current retransmission timeout value
00501   double        dSrtt;                // current smoothed round trip time
00502   double        dRttVar;              // current RTT variance
00503   int           iPmtu;                // current known path MTU (not used)
00504   Boolean_E     eRtxTimerIsRunning;   // is there a timer running already?
00505   T3RtxTimer   *opT3RtxTimer;         // retransmission timer
00506   Boolean_E     eRtoPending;          // DATA chunk being used to measure RTT?
00507 
00508   int  iPartialBytesAcked; // helps to modify cwnd in congestion avoidance mode
00509   int  iOutstandingBytes;  // outstanding bytes still in flight (unacked)
00510 
00511   int                     iTimeoutCount;           // total number of timeouts
00512   int                     iErrorCount;             // destination error counter
00513   SctpDestStatus_E        eStatus;                 // active/inactive
00514   CwndDegradeTimer       *opCwndDegradeTimer;      // timer to degrade cwnd
00515   double                  dIdleSince;              // timestamp since idle
00516   HeartbeatTimeoutTimer  *opHeartbeatTimeoutTimer; // heartbeat timeout timer
00517 
00518   float fLossrate;          // Set from tcl, in SetLossrate(). Allows an
00519                             // Oracle to tell sender a given destination's
00520                             // lossrate. Used in CMT's RTX_LOSSRATE rtx
00521                             // policy.
00522 
00523   /* these are temporary variables needed per destination and they should
00524    * be cleared for each usage.
00525    */
00526   Boolean_E              eCcApplied;          // cong control already applied?
00527   SctpSendBufferNode_S  *spFirstOutstanding;  // first outstanding on this dest
00528   int                    iNumNewlyAckedBytes; // newly ack'd bytes in a sack
00529 
00530   /* These variables are generally not used. They are only for our
00531    * simulated reactive routing overheads for MANETs, etc. 
00532    */
00533   int                    iRcdCount;     // total count of route calc delays
00534   Boolean_E              eRouteCached;  // route cache hit or miss?
00535   RouteCacheFlushTimer  *opRouteCacheFlushTimer;
00536   RouteCalcDelayTimer   *opRouteCalcDelayTimer;  
00537   List_S                 sBufferedPackets;
00538 
00539   /* CMT variables follow. These are used only when CMT is used. 
00540    */
00541   Boolean_E  eSawNewAck;                // was this destination acked 
00542                                         // in the current SACK?
00543   u_int uiHighestTsnInSackForDest;      // highest TSN newly acked sent to this 
00544                                         // destination in SACK
00545   u_int      uiExpectedPseudoCum;       // expected pseudo cumack for this dest
00546   Boolean_E  eNewPseudoCum;             // is there a new pseudo cum for dest?
00547   Boolean_E  eFindExpectedPseudoCum;    // find a new expected pseudo cumack?
00548   u_int      uiExpectedRtxPseudoCum;    // expected rtx pseudo cum for dest
00549   Boolean_E  eFindExpectedRtxPseudoCum; // find a new expected rtx pseudo cum?
00550   u_int uiLowestTsnInSackForDest;       // lowest TSN newly acked sent to this 
00551                                         // destination in SACK
00552 
00553   u_int iNumPacketsSent;    // for the one packet limit during rtx. With 
00554                             // independent bottlenecks, apply limit per path.
00555   u_int uiBurstLength;      // tracks sending burst per SACK per dest
00556   Boolean_E eMarkedChunksPending;  // added global var per dest
00557   u_int uiRecover;                 // To enable newreno recovery per dest
00558   SctpRtxLimit_E eRtxLimit; // Which destination should use 
00559                             // RTX_ONE_PACKET_LIMIT
00560                             // when calling rtxmarkedchunks()
00561 
00562   u_int uiNumTimeouts;      // track number of timeouts for this dest
00563 
00564   Boolean_E eHBTimerIsRunning;   // CMT-PF: Track & stop HB timer when 
00565                                  // destination state changes from PF->Active 
00566   double dPFSince;               // CMT-PF: time when destination is marked PF
00567 
00568   /* End of CMT variables
00569    */
00570   
00571 };
00572 
00573 struct SctpRecvTsnBlock_S
00574 {
00575   u_int  uiStartTsn;
00576   u_int  uiEndTsn;
00577 };
00578 
00579 struct SctpSendBufferNode_S
00580 {
00581   SctpDataChunkHdr_S  *spChunk;
00582   Boolean_E            eAdvancedAcked;     // acked via rtx expiration (u-sctp)
00583   Boolean_E            eGapAcked;          // acked via a Gap Ack Block
00584   Boolean_E            eAddedToPartialBytesAcked; // already accounted for?
00585   int                  iNumMissingReports; // # times reported missing
00586   int                  iUnrelRtxLimit;     // limit on # of unreliable rtx's
00587   MarkedForRtx_E       eMarkedForRtx;      // has it been marked for rtx?
00588   Boolean_E            eIneligibleForFastRtx; // ineligible for fast rtx??
00589   int                  iNumTxs;            // # of times transmitted (orig+rtx)
00590   double               dTxTimestamp;  
00591   SctpDest_S          *spDest;             // destination last sent to
00592 
00593   /* variables used for extensions
00594    */
00595   u_int                uiFastRtxRecover;   // sctp-multipleFastRtxs.cc uses this
00596 
00597   Boolean_E eMeasuringRtt;  // Maintain which TSN is being used for RTT
00598                             // measurement, so that all TSNs can have
00599                             // their timestamp. This timestamp can be used
00600                             // for different things, and is used by CMT
00601                             // for the RTT heuristic to determine whether
00602                             // a TSN should be rtxd or not.  If now <=
00603                             // timestamp + srtt, then no rtx.
00604 };
00605 
00606 struct SctpStreamBufferNode_S
00607 {
00608   SctpDataChunkHdr_S  *spChunk;
00609 };
00610 
00611 enum SctpStreamMode_E
00612 {
00613   SCTP_STREAM_RELIABLE,
00614   SCTP_STREAM_UNRELIABLE
00615 };
00616 
00617 struct SctpInStream_S
00618 {
00619   SctpStreamMode_E  eMode;
00620   u_short           usNextStreamSeqNum;
00621   List_S            sBufferedChunkList;
00622 };
00623 
00624 struct SctpOutStream_S
00625 {
00626   SctpStreamMode_E  eMode;
00627   u_short           usNextStreamSeqNum; 
00628 };
00629 
00630 class SackGenTimer : public TimerHandler 
00631 {
00632 public:
00633   SackGenTimer(SctpAgent *a) : TimerHandler(), opAgent(a) { }
00634         
00635 protected:
00636   virtual void expire(Event *);
00637   SctpAgent *opAgent;
00638 };
00639 
00640 class SctpAgent : public Agent 
00641 {
00642 public:
00643   SctpAgent();
00644   ~SctpAgent();
00645         
00646   virtual void  recv(Packet *pkt, Handler*);
00647   virtual void  sendmsg(int nbytes, const char *flags = 0);
00648   virtual int   command(int argc, const char*const* argv);
00649         
00650   void          T1InitTimerExpiration();
00651   void          T1CookieTimerExpiration();
00652   virtual void  Timeout(SctpChunkType_E, SctpDest_S *);
00653   virtual void  CwndDegradeTimerExpiration(SctpDest_S *);
00654   virtual void  HeartbeatGenTimerExpiration(double);
00655   void          SackGenTimerExpiration();
00656   void          RouteCacheFlushTimerExpiration(SctpDest_S *);
00657   void          RouteCalcDelayTimerExpiration(SctpDest_S *);
00658 
00659 protected:
00660   virtual void  delay_bind_init_all();
00661   virtual int   delay_bind_dispatch(const char *varName, const char *localName,
00662                                     TclObject *tracer);
00663 
00664   /* initialization stuff
00665    */
00666   void           SetDebugOutFile();
00667   virtual void   Reset();
00668   virtual void   OptionReset();
00669   virtual u_int  ControlChunkReservation();
00670 
00671   /* tracing functions
00672    */
00673   virtual void  TraceVar(const char*);
00674   virtual void  TraceAll();
00675   void          trace(TracedVar*);
00676 
00677   /* generic list functions
00678    */
00679   void       InsertNode(List_S *, Node_S *, Node_S *, Node_S *);
00680   void       DeleteNode(List_S *, Node_S *);
00681   void       ClearList(List_S *);
00682 
00683   /* multihome functions
00684    */
00685   void       AddInterface(int, int, NsObject *, NsObject *);
00686   void       AddDestination(int, int);
00687   int        SetPrimary(int);
00688   int        ForceSource(int);
00689   int        SetLossrate(int, float); // Oracle tells sender lossrate to
00690                                       // dest. Called by handling of tcl
00691                                       // set-destination-lossrate command
00692 
00693   /* chunk generation functions
00694    */
00695   virtual int  GenChunk(SctpChunkType_E, u_char *);
00696   u_int        GetNextDataChunkSize();
00697   int          GenOneDataChunk(u_char *);
00698   virtual int  GenMultipleDataChunks(u_char *, int);
00699   virtual int  BundleControlChunks(u_char *);
00700 
00701   /* sending functions
00702    */
00703   void          StartT3RtxTimer(SctpDest_S *);
00704   void          StopT3RtxTimer(SctpDest_S *);
00705   virtual void  AddToSendBuffer(SctpDataChunkHdr_S *,int, u_int, SctpDest_S *);
00706   void          RttUpdate(double, SctpDest_S *);
00707   virtual void  SendBufferDequeueUpTo(u_int);
00708   virtual void  AdjustCwnd(SctpDest_S *);
00709   void          AdvancePeerAckPoint();
00710   virtual u_int GetHighestOutstandingTsn();
00711   virtual void  FastRtx();
00712   void          TimeoutRtx(SctpDest_S *);
00713   void          MarkChunkForRtx(SctpSendBufferNode_S *, MarkedForRtx_E);
00714   Boolean_E     AnyMarkedChunks();
00715   virtual void  RtxMarkedChunks(SctpRtxLimit_E);
00716   void          SendHeartbeat(SctpDest_S *);
00717   SctpDest_S   *GetNextDest(SctpDest_S *);
00718   double        CalcHeartbeatTime(double);
00719   void          SetSource(SctpDest_S *);
00720   void          SetDestination(SctpDest_S *);
00721   void          SendPacket(u_char *, int, SctpDest_S *);
00722   SctpDest_S   *GetReplyDestination(hdr_ip *);
00723   u_int         TotalOutstanding();
00724   virtual void  SendMuch();
00725 
00726   /* receiving functions
00727    */
00728   Boolean_E  UpdateHighestTsn(u_int);
00729   Boolean_E  IsDuplicateChunk(u_int);
00730   void       InsertDuplicateTsn(u_int);
00731   void       UpdateCumAck();
00732   void       UpdateRecvTsnBlocks(u_int);
00733   void       PassToUpperLayer(SctpDataChunkHdr_S *);
00734   void       InsertInStreamBuffer(List_S *, SctpDataChunkHdr_S *);
00735   void       PassToStream(SctpDataChunkHdr_S *);
00736   void       UpdateAllStreams();
00737 
00738   /* processing functions
00739    */
00740   void               ProcessInitChunk(u_char *);
00741   void               ProcessInitAckChunk(u_char *);
00742   void               ProcessCookieEchoChunk(SctpCookieEchoChunk_S *);
00743   void               ProcessCookieAckChunk(SctpCookieAckChunk_S *);
00744   void               ProcessDataChunk(SctpDataChunkHdr_S *);
00745   virtual Boolean_E  ProcessGapAckBlocks(u_char *, Boolean_E);
00746   virtual void       ProcessSackChunk(u_char *);
00747   void               ProcessForwardTsnChunk(SctpForwardTsnChunk_S *);  
00748   void               ProcessHeartbeatAckChunk(SctpHeartbeatChunk_S *);  
00749   virtual void       ProcessOptionChunk(u_char *);
00750   virtual int        ProcessChunk(u_char *, u_char **);
00751   void               NextChunk(u_char **, int *);
00752 
00753   /* misc functions
00754    */
00755   void       Close();
00756 
00757   /* debugging functions
00758    */
00759   void DumpSendBuffer();
00760 
00761   /* sctp association state variable
00762    */
00763   SctpState_E     eState;
00764 
00765   /* App Layer buffer
00766    */
00767   List_S          sAppLayerBuffer;
00768 
00769   /* multihome variables
00770    */
00771   Classifier         *opCoreTarget;
00772   List_S              sInterfaceList;
00773   List_S              sDestList;
00774   SctpDest_S         *spPrimaryDest;       // primary destination
00775   SctpDest_S         *spNewTxDest;         // destination for new transmissions
00776   SctpDest_S         *spReplyDest; // reply with sacks or control chunk replies
00777   Boolean_E           eForceSource;
00778   int                 iAssocErrorCount;  // total error counter for the assoc
00779 
00780   /* heartbeat variables
00781    */
00782   HeartbeatGenTimer      *opHeartbeatGenTimer;      // to trigger a heartbeat
00783 
00784   /* sending variables
00785    */
00786   T1InitTimer       *opT1InitTimer;    // T1-init timer
00787   T1CookieTimer     *opT1CookieTimer;  // T1-cookie timer
00788   int                iInitTryCount;    // # of unsuccessful INIT attempts
00789   u_int              uiNextTsn;
00790   u_short            usNextStreamId; // used to round-robin the streams
00791   SctpOutStream_S   *spOutStreams;
00792   u_int              uiPeerRwnd;
00793   u_int              uiCumAckPoint;  
00794   u_int              uiAdvancedPeerAckPoint;
00795   u_int              uiHighestTsnNewlyAcked; // global for HTNA
00796   u_int              uiRecover;
00797   List_S             sSendBuffer;
00798   Boolean_E          eForwardTsnNeeded;  // is a FORWARD TSN chunk needed?
00799   Boolean_E          eSendNewDataChunks; // should we send new data chunks too?
00800   Boolean_E          eMarkedChunksPending; // chunks waiting to be rtx'd?
00801   Boolean_E          eApplyMaxBurst; 
00802   DataSource_E       eDataSource;
00803   u_int              uiBurstLength;  // tracks sending burst per SACK
00804 
00805   /* receiving variables
00806    */
00807   u_int            uiMyRwnd;
00808   u_int            uiCumAck;       
00809   u_int            uiHighestRecvTsn; // higest tsn recv'd of entire assoc
00810   List_S           sRecvTsnBlockList;
00811   List_S           sDupTsnList;
00812   int              iNumInStreams;
00813   SctpInStream_S  *spInStreams;
00814   Boolean_E        eStartOfPacket;             // for delayed sack triggering
00815   int              iDataPktCountSinceLastSack; // for delayed sack triggering
00816   Boolean_E        eSackChunkNeeded; // do we need to transmit a sack chunk?
00817   SackGenTimer    *opSackGenTimer;    // sack generation timer
00818 
00819   /* tcl bindable variables
00820    */
00821   u_int            uiDebugMask;     // 32 bits for fine level debugging
00822   int              iDebugFileIndex; // 1 debug output file per agent 
00823   u_int            uiPathMaxRetrans;
00824   u_int            uiChangePrimaryThresh;
00825   u_int            uiAssociationMaxRetrans;
00826   u_int            uiMaxInitRetransmits;
00827   u_int            uiHeartbeatInterval;
00828   u_int            uiMtu;
00829   u_int            uiInitialRwnd;
00830   int              iInitialSsthresh;
00831   u_int            uiIpHeaderSize;
00832   u_int            uiDataChunkSize;
00833   u_int            uiNumOutStreams;
00834   Boolean_E        eUseDelayedSacks; // are we using delayed sacks?
00835   double           dSackDelay;
00836   MaxBurstUsage_E  eUseMaxBurst;
00837   int              iInitialCwnd;
00838   double           dInitialRto;
00839   double           dMinRto;
00840   double           dMaxRto;
00841   int              iFastRtxTrigger;
00842   u_int            uiNumUnrelStreams;
00843   u_int            uiReliability; // k-rtx on all chunks & all unrel streams
00844   Boolean_E        eUnordered;    // sets for all chunks on all streams :-(
00845   RtxToAlt_E       eRtxToAlt;     // rtxs to alternate destination?
00846   DormantAction_E  eDormantAction;// behavior during dormant state
00847   double           dRouteCacheLifetime; 
00848   double           dRouteCalcDelay; 
00849   Boolean_E        eTraceAll;     // trace all variables on one line?
00850   TracedInt        tiCwnd;        // trace cwnd for all destinations
00851   TracedInt        tiRwnd;        // trace rwnd
00852   TracedDouble     tdRto;         // trace rto for all destinations
00853   TracedInt        tiErrorCount;  // trace error count for all destinations
00854   TracedInt        tiFrCount;     // trace each time a fast rtx gets triggered
00855   TracedInt        tiTimeoutCount;// trace each time a timeout occurs
00856   TracedInt        tiRcdCount;    // trace each time a route calc delay occurs
00857 
00858   /* globally used non-tcl bindable variables, but rely on the tcl bindable
00859    */
00860   u_int           uiMaxPayloadSize; // we don't want this to be tcl bindable
00861   u_int           uiMaxDataSize; // max payload size - reserved control bytes
00862   FILE           *fhpDebugFile;            // file pointer for debugging output
00863 
00864   /* tracing variables that will be copied into hdr_sctp
00865    */
00866   u_int           uiNumChunks;
00867   SctpTrace_S    *spSctpTrace;  
00868 };
00869 
00870 #endif

Generated on Tue Aug 10 2010 16:16:08 for ns-2.33 by  doxygen 1.7.1