sctp.h
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:27k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 2006-2007 by the Protocol Engineering Lab, U of Delaware
  3.  * All rights reserved.
  4.  *
  5.  * Protocol Engineering Lab web page : http://pel.cis.udel.edu/
  6.  *
  7.  * Paul D. Amer        <amer@@cis,udel,edu>
  8.  * Armando L. Caro Jr. <acaro@@cis,udel,edu>
  9.  * Janardhan Iyengar   <iyengar@@cis,udel,edu>
  10.  * Preethi Natarajan   <nataraja@@cis,udel,edu>
  11.  * Nasif Ekiz          <nekiz@@cis,udel,edu>
  12.  *
  13.  * Redistribution and use in source and binary forms, with or without
  14.  * modification, are permitted provided that the following conditions
  15.  * are met:
  16.  *
  17.  * 1. Redistributions of source code must retain the above copyright
  18.  *    notice, this list of conditions and the following disclaimer.
  19.  *
  20.  * 2. Redistributions in binary form must reproduce the above copyright
  21.  *    notice, this list of conditions and the following disclaimer in the
  22.  *    documentation and/or other materials provided with the distribution.
  23.  *
  24.  * 3. Neither the name of the University nor of the Laboratory may be used
  25.  *    to endorse or promote products derived from this software without
  26.  *    specific prior written permission.
  27.  *
  28.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  29.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  32.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  37.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  38.  * SUCH DAMAGE.
  39.  *
  40.  * @(#) $Header: /cvsroot/nsnam/ns-2/sctp/sctp.h,v 1.10 2007/06/17 21:44:45 tom_henderson Exp $ (UD/PEL)
  41.  */
  42. #ifndef ns_sctp_h
  43. #define ns_sctp_h
  44. #include "agent.h"
  45. #include "node.h"
  46. #include "packet.h"
  47. /* The SCTP Common header is 12 bytes.
  48.  */
  49. #define SCTP_HDR_SIZE         12
  50. #define MAX_RWND_SIZE         0xffffffff
  51. #define MAX_DATA_CHUNK_SIZE   0xffffffff
  52. #define MIN_DATA_CHUNK_SIZE   16
  53. #define MAX_NUM_STREAMS       0x0000ffff
  54. #define DELAYED_SACK_TRIGGER  2      // sack for every 2 data packets
  55. #define RTO_ALPHA             0.125  // RTO.alpha is 1/8
  56. #define RTO_BETA              0.25   // RTO.Beta is 1/4
  57. #define MAX_BURST             4
  58. enum MaxBurstUsage_E
  59. {
  60.   MAX_BURST_USAGE_OFF,      // 0
  61.   MAX_BURST_USAGE_ON        // 1
  62. };
  63. /* Let us use OUR typedef'd enum for FALSE and TRUE. It's much better this way.
  64.  * ...why? because NOW all boolean variables can be explicitly declared as
  65.  * such. There is no longer any ambiguity between a regular int variable and a
  66.  * boolean variable.  
  67.  */
  68. #undef FALSE
  69. #undef TRUE
  70. enum Boolean_E
  71. {
  72.   FALSE,
  73.   TRUE
  74. };
  75. /* Each time the sender retransmits marked chunks, how many can be sent? Well,
  76.  * immediately after a timeout or when the 4 missing report is received, only
  77.  * one packet of retransmits may be sent. Later, the number of packets is gated
  78.  * by cwnd
  79.  */
  80. enum SctpRtxLimit_E
  81. {
  82.   RTX_LIMIT_ONE_PACKET,
  83.   RTX_LIMIT_CWND,
  84.   RTX_LIMIT_ZERO
  85. };
  86. enum MarkedForRtx_E
  87. {
  88.   NO_RTX,
  89.   FAST_RTX,
  90.   TIMEOUT_RTX
  91. };
  92. enum RtxToAlt_E
  93. {
  94.   RTX_TO_ALT_OFF,
  95.   RTX_TO_ALT_ON,
  96.   RTX_TO_ALT_TIMEOUTS_ONLY
  97. };
  98. /* What behavior is used during dormant state (ie, all destinations have
  99.  * failed) when timeouts persist?
  100.  */
  101. enum DormantAction_E
  102. {
  103.   DORMANT_HOP,        // keep hopping to another destination
  104.   DORMANT_PRIMARY,    // goto primary and stay there
  105.   DORMANT_LASTDEST    // stay at the last destination used before dormant state
  106. };
  107. /* Who controls the data sending, app layer or the transport layer 
  108.  * (as in the case of infinite data)
  109.  */
  110. enum DataSource_E
  111. {
  112.   DATA_SOURCE_APPLICATION,
  113.   DATA_SOURCE_INFINITE
  114. };
  115. /* SCTP chunk types 
  116.  */
  117. enum SctpChunkType_E
  118. {
  119.   SCTP_CHUNK_DATA,
  120.   SCTP_CHUNK_INIT,
  121.   SCTP_CHUNK_INIT_ACK,
  122.   SCTP_CHUNK_SACK,
  123.   SCTP_CHUNK_HB,
  124.   SCTP_CHUNK_HB_ACK,
  125.   SCTP_CHUNK_ABORT,
  126.   SCTP_CHUNK_SHUTDOWN,
  127.   SCTP_CHUNK_SHUTDOWN_ACK,
  128.   SCTP_CHUNK_ERROR,
  129.   SCTP_CHUNK_COOKIE_ECHO,
  130.   SCTP_CHUNK_COOKIE_ACK,
  131.   SCTP_CHUNK_ECNE,                  // reserved in rfc2960
  132.   SCTP_CHUNK_CWR,                   // reserved in rfc2960
  133.   SCTP_CHUNK_SHUTDOWN_COMPLETE,
  134.   /* RFC2960 leaves room for later defined chunks */
  135.   /* for U-SCTP/PR-SCTP
  136.    */
  137.   SCTP_CHUNK_FORWARD_TSN,    // should be 192, but this is a simulation! :-)
  138.   /* for timestamp option (sctp-timestamp.cc)
  139.    */
  140.   SCTP_CHUNK_TIMESTAMP
  141. };
  142. struct AppData_S 
  143. {
  144.   /* Parameters needed for establishing an association 
  145.    */
  146.   u_short usNumStreams;     // Number of streams to associate
  147.   u_short usNumUnreliable;  // first usNumUnreliable streams will be unreliable
  148.   /* Parameters needed for app data messages 
  149.    */
  150.   u_short    usStreamId;     // Which stream does this message go on?
  151.   u_short    usReliability;  // What level of relability does this message have
  152.   Boolean_E  eUnordered;     // Is this an unordered message?
  153.   u_int      uiNumBytes;     // Number of databytes in message
  154. };
  155. /* ns specific header fields used for tracing SCTP traffic
  156.  * (This was done so that the 'trace' module wouldn't have to look into the
  157.  * payload of SCTP packets)
  158.  */
  159. struct SctpTrace_S
  160. {
  161.   SctpChunkType_E  eType;
  162.   u_int            uiTsn;   // (cum ack for sacks, -1 for other control chunks)
  163.   u_short          usStreamId;     // -1 for control chunks
  164.   u_short          usStreamSeqNum; // -1 for control chunks
  165. };
  166. struct hdr_sctp
  167. {
  168.   /* ns required header fields/methods 
  169.    */
  170.   static int offset_; // offset for this header
  171.   inline static int& offset() { return offset_; }
  172.   inline static hdr_sctp* access(Packet* p) 
  173.   {
  174.     return (hdr_sctp*) p->access(offset_);
  175.   }
  176.   /* ns specific header fields used for tracing SCTP traffic
  177.    * (This was done so that the 'trace' module wouldn't have to look into the
  178.    * payload of SCTP packets)
  179.    */
  180.   u_int         uiNumChunks;
  181.   SctpTrace_S  *spSctpTrace;
  182.   u_int&        NumChunks() { return uiNumChunks; }
  183.   SctpTrace_S*& SctpTrace() { return spSctpTrace; }
  184. };
  185. struct SctpChunkHdr_S
  186. {
  187.   u_char  ucType;
  188.   u_char  ucFlags;
  189.   u_short usLength;
  190. };
  191. /* INIT paramater types
  192.  */
  193. #define SCTP_INIT_PARAM_UNREL  0xC000
  194. struct SctpUnrelStreamsParam_S
  195. {
  196.   u_short  usType;
  197.   u_short  usLength;
  198.   /* unreliable stream start-end pairs are appended dynamically
  199.    */
  200. };
  201. struct SctpUnrelStreamPair_S
  202. {
  203.   u_short  usStart;
  204.   u_short  usEnd;
  205. };
  206. struct SctpInitChunk_S  // this is used for init ack, too 
  207. {
  208.   SctpChunkHdr_S  sHdr;
  209.   u_int           uiInitTag;  // tag of mine (not used)
  210.   u_int           uiArwnd;           // referred to as a_rwnd in rfc2960
  211.   u_short         usNumOutboundStreams;  // referred to as OS in rfc2960
  212.   u_short         usMaxInboundStreams;   // referred to as MIS in rfc2960
  213.   u_int           uiInitialTsn;          
  214.   SctpUnrelStreamsParam_S  sUnrelStream;
  215. };
  216. typedef SctpInitChunk_S SctpInitAckChunk_S;
  217. struct SctpCookieEchoChunk_S
  218. {
  219.   SctpChunkHdr_S  sHdr;
  220.   /* cookie would go here, but we aren't implementing this at the moment */
  221. };
  222. typedef SctpCookieEchoChunk_S SctpCookieAckChunk_S;
  223. struct SctpDataChunkHdr_S
  224. {
  225.   SctpChunkHdr_S  sHdr;
  226.   u_int           uiTsn;
  227.   u_short         usStreamId;
  228.   u_short         usStreamSeqNum;
  229.   u_int           uiPayloadType;     // not used
  230.   /* user data must be appended dynamically when filling packets */
  231. };
  232. /* Data Chunk Specific Flags
  233.  */
  234. #define SCTP_DATA_FLAG_END        0x01  // indicates last fragment
  235. #define SCTP_DATA_FLAG_BEGINNING  0x02  // indicates first fragment
  236. #define SCTP_DATA_FLAG_UNORDERED  0x04  // indicates unordered DATA chunk
  237. /* SACK has the following structure and following it will be some number of
  238.  * gap acks and duplicate tsns.
  239.  */
  240. struct SctpSackChunk_S
  241. {
  242.   SctpChunkHdr_S  sHdr;
  243.   u_int           uiCumAck;
  244.   u_int           uiArwnd;
  245.   u_short         usNumGapAckBlocks;
  246.   u_short         usNumDupTsns;
  247.   /* Gap Ack Blocks and Duplicate TSNs are appended dynamically
  248.    */
  249. };
  250. struct SctpGapAckBlock_S
  251. {
  252.   u_short  usStartOffset;
  253.   u_short  usEndOffset;
  254. };
  255. struct SctpDupTsn_S
  256. {
  257.   u_int  uiTsn;
  258. };
  259. #define SCTP_CHUNK_FORWARD_TSN_LENGTH  8
  260. struct SctpForwardTsnChunk_S
  261. {
  262.   SctpChunkHdr_S  sHdr;
  263.   u_int           uiNewCum;
  264. };
  265. struct SctpDest_S;
  266. #define SCTP_CHUNK_HEARTBEAT_LENGTH  24
  267. struct SctpHeartbeatChunk_S
  268. {
  269.   SctpChunkHdr_S  sHdr;
  270.   u_short         usInfoType;      // filled in, but not really used
  271.   u_short         usInfoLength;    // filled in, but not really used
  272.   double          dTimestamp;
  273.   SctpDest_S     *spDest;
  274. };
  275. typedef SctpHeartbeatChunk_S SctpHeartbeatAckChunk_S;
  276. /* SCTP state defines for internal state machine */
  277. enum SctpState_E
  278. {
  279.   SCTP_STATE_UNINITIALIZED,
  280.   SCTP_STATE_CLOSED,
  281.   SCTP_STATE_ESTABLISHED,
  282.   SCTP_STATE_COOKIE_WAIT,
  283.   SCTP_STATE_COOKIE_ECHOED,
  284.   SCTP_STATE_SHUTDOWN_SENT,        // not currently used
  285.   SCTP_STATE_SHUTDOWN_RECEIVED,    // not currently used
  286.   SCTP_STATE_SHUTDOWN_ACK_SENT,    // not currently used
  287.   SCTP_STATE_SHUTDOWN_PENDING      // not currently used
  288. };
  289. class SctpAgent;
  290. class T1InitTimer : public TimerHandler 
  291. {
  292. public:
  293.   T1InitTimer(SctpAgent *a) : TimerHandler(), opAgent(a) { }
  294. protected:
  295.   virtual void expire(Event *);
  296.   SctpAgent *opAgent;
  297. };
  298. class T1CookieTimer : public TimerHandler 
  299. {
  300. public:
  301.   T1CookieTimer(SctpAgent *a) : TimerHandler(), opAgent(a) { }
  302. protected:
  303.   virtual void expire(Event *);
  304.   SctpAgent *opAgent;
  305. };
  306. class T3RtxTimer : public TimerHandler 
  307. {
  308. public:
  309.   T3RtxTimer(SctpAgent *a, SctpDest_S *d) 
  310.     : TimerHandler(), opAgent(a) {spDest = d;}
  311. protected:
  312.   virtual void expire(Event *);
  313.   SctpAgent  *opAgent;
  314.   SctpDest_S *spDest;  // destination this timer corresponds to
  315. };
  316. class CwndDegradeTimer : public TimerHandler 
  317. {
  318. public:
  319.   CwndDegradeTimer(SctpAgent *a, SctpDest_S *d) 
  320.     : TimerHandler(), opAgent(a) {spDest = d;}
  321. protected:
  322.   virtual void expire(Event *);
  323.   SctpAgent  *opAgent;
  324.   SctpDest_S *spDest;  // destination this timer corresponds to
  325. };
  326. class HeartbeatGenTimer : public TimerHandler 
  327. {
  328. public:
  329.   HeartbeatGenTimer(SctpAgent *a) 
  330.     : TimerHandler(), opAgent(a) {}
  331.   double      dStartTime; // timestamp of when timer started
  332. protected:
  333.   virtual void expire(Event *);
  334.   SctpAgent  *opAgent;
  335. };
  336. class HeartbeatTimeoutTimer : public TimerHandler 
  337. {
  338. public:
  339.   HeartbeatTimeoutTimer(SctpAgent *a, SctpDest_S *d) 
  340.     : TimerHandler(), opAgent(a) {spDest = d;}
  341.   SctpDest_S *spDest;  // destination this timer corresponds to
  342. protected:
  343.   virtual void expire(Event *);
  344.   SctpAgent  *opAgent;
  345. };
  346. /* This timer simulates the route lifetime in the routing tables of
  347.  * reactive routing protocols for MANETs, etc. When this timer expires,
  348.  * the route is flushed and any future data sent to this dest will cause a 
  349.  * route calculation.
  350.  *
  351.  * Note: This timer is not normally used. It's only for our simulated reactive
  352.  * routing overheads for MANETs, etc. 
  353.  */
  354. class RouteCacheFlushTimer : public TimerHandler 
  355. {
  356. public:
  357.   RouteCacheFlushTimer(SctpAgent *a, SctpDest_S *d) 
  358.     : TimerHandler(), opAgent(a) {spDest = d;}
  359. protected:
  360.   virtual void expire(Event *);
  361.   SctpAgent  *opAgent;
  362.   SctpDest_S *spDest;  // destination this timer corresponds to
  363. };
  364. /* This timer simulates the time it takes to calculate a route in
  365.  * reactive routing protocols for MANETs, etc. 
  366.  *
  367.  * Note: This timer is not normally used. It's only for our simulated reactive
  368.  * routing overheads for MANETs, etc. 
  369.  */
  370. class RouteCalcDelayTimer : public TimerHandler 
  371. {
  372. public:
  373.   RouteCalcDelayTimer(SctpAgent *a, SctpDest_S *d) 
  374.     : TimerHandler(), opAgent(a) {spDest = d;}
  375. protected:
  376.   virtual void expire(Event *);
  377.   SctpAgent  *opAgent;
  378.   SctpDest_S *spDest;  // destination this timer corresponds to
  379. };
  380. struct SctpInterface_S
  381. {
  382.   int        iNsAddr;
  383.   int        iNsPort;
  384.   NsObject  *opTarget;
  385.   NsObject  *opLink;
  386. };
  387. enum SctpDestStatus_E
  388. {
  389.   SCTP_DEST_STATUS_INACTIVE,
  390.   SCTP_DEST_STATUS_POSSIBLY_FAILED,
  391.   SCTP_DEST_STATUS_ACTIVE,
  392.   SCTP_DEST_STATUS_UNCONFIRMED
  393. };
  394. enum NodeType_E
  395. {
  396.   NODE_TYPE_STREAM_BUFFER,
  397.   NODE_TYPE_RECV_TSN_BLOCK,
  398.   NODE_TYPE_DUP_TSN,
  399.   NODE_TYPE_SEND_BUFFER,
  400.   NODE_TYPE_APP_LAYER_BUFFER,
  401.   NODE_TYPE_INTERFACE_LIST,
  402.   NODE_TYPE_DESTINATION_LIST,
  403.   NODE_TYPE_PACKET_BUFFER
  404. };
  405. struct Node_S
  406. {
  407.   NodeType_E  eType;
  408.   void       *vpData;   // u can put any data type into the node
  409.   Node_S     *spNext;
  410.   Node_S     *spPrev;
  411. };
  412. struct List_S
  413. {
  414.   u_int    uiLength;
  415.   Node_S  *spHead;
  416.   Node_S  *spTail;
  417. };
  418. struct SctpSendBufferNode_S;
  419. struct SctpDest_S
  420. {
  421.   int        iNsAddr;  // ns "IP address"
  422.   int        iNsPort;  // ns "port"
  423.   /* Packet is simply used for determing src addr. The header stores dest addr,
  424.    * which makes it easy to determine src target using
  425.    * Connector->find(Packet *). Then with the target, we can determine src 
  426.    * addr.
  427.    */
  428.   Packet    *opRoutingAssistPacket;
  429.   int           iCwnd;                // current congestion window
  430.   int           iSsthresh;            // current ssthresh value
  431.   Boolean_E     eFirstRttMeasurement; // is this our first RTT measurement?
  432.   double        dRto;                 // current retransmission timeout value
  433.   double        dSrtt;                // current smoothed round trip time
  434.   double        dRttVar;              // current RTT variance
  435.   int           iPmtu;                // current known path MTU (not used)
  436.   Boolean_E     eRtxTimerIsRunning;   // is there a timer running already?
  437.   T3RtxTimer   *opT3RtxTimer;         // retransmission timer
  438.   Boolean_E     eRtoPending;          // DATA chunk being used to measure RTT?
  439.   int  iPartialBytesAcked; // helps to modify cwnd in congestion avoidance mode
  440.   int  iOutstandingBytes;  // outstanding bytes still in flight (unacked)
  441.   int                     iTimeoutCount;           // total number of timeouts
  442.   int                     iErrorCount;             // destination error counter
  443.   SctpDestStatus_E        eStatus;                 // active/inactive
  444.   CwndDegradeTimer       *opCwndDegradeTimer;      // timer to degrade cwnd
  445.   double                  dIdleSince;              // timestamp since idle
  446.   HeartbeatTimeoutTimer  *opHeartbeatTimeoutTimer; // heartbeat timeout timer
  447.   float fLossrate;          // Set from tcl, in SetLossrate(). Allows an
  448.     // Oracle to tell sender a given destination's
  449.     // lossrate. Used in CMT's RTX_LOSSRATE rtx
  450.     // policy.
  451.   /* these are temporary variables needed per destination and they should
  452.    * be cleared for each usage.
  453.    */
  454.   Boolean_E              eCcApplied;          // cong control already applied?
  455.   SctpSendBufferNode_S  *spFirstOutstanding;  // first outstanding on this dest
  456.   int                    iNumNewlyAckedBytes; // newly ack'd bytes in a sack
  457.   /* These variables are generally not used. They are only for our
  458.    * simulated reactive routing overheads for MANETs, etc. 
  459.    */
  460.   int                    iRcdCount;     // total count of route calc delays
  461.   Boolean_E              eRouteCached;  // route cache hit or miss?
  462.   RouteCacheFlushTimer  *opRouteCacheFlushTimer;
  463.   RouteCalcDelayTimer   *opRouteCalcDelayTimer;  
  464.   List_S                 sBufferedPackets;
  465.   /* CMT variables follow. These are used only when CMT is used. 
  466.    */
  467.   Boolean_E  eSawNewAck;                // was this destination acked 
  468.                                         // in the current SACK?
  469.   u_int uiHighestTsnInSackForDest;      // highest TSN newly acked sent to this 
  470.                                         // destination in SACK
  471.   u_int      uiExpectedPseudoCum;       // expected pseudo cumack for this dest
  472.   Boolean_E  eNewPseudoCum;             // is there a new pseudo cum for dest?
  473.   Boolean_E  eFindExpectedPseudoCum;    // find a new expected pseudo cumack?
  474.   u_int      uiExpectedRtxPseudoCum;    // expected rtx pseudo cum for dest
  475.   Boolean_E  eFindExpectedRtxPseudoCum; // find a new expected rtx pseudo cum?
  476.   u_int uiLowestTsnInSackForDest;       // lowest TSN newly acked sent to this 
  477.                                         // destination in SACK
  478.   u_int iNumPacketsSent;    // for the one packet limit during rtx. With 
  479.                             // independent bottlenecks, apply limit per path.
  480.   u_int uiBurstLength;      // tracks sending burst per SACK per dest
  481.   Boolean_E eMarkedChunksPending;  // added global var per dest
  482.   u_int uiRecover;                 // To enable newreno recovery per dest
  483.   SctpRtxLimit_E eRtxLimit; // Which destination should use 
  484.                             // RTX_ONE_PACKET_LIMIT
  485.                             // when calling rtxmarkedchunks()
  486.   u_int uiNumTimeouts;      // track number of timeouts for this dest
  487.   Boolean_E eHBTimerIsRunning;   // CMT-PF: Track & stop HB timer when 
  488.                                  // destination state changes from PF->Active 
  489.   double dPFSince;               // CMT-PF: time when destination is marked PF
  490.   /* End of CMT variables
  491.    */
  492.   
  493. };
  494. struct SctpRecvTsnBlock_S
  495. {
  496.   u_int  uiStartTsn;
  497.   u_int  uiEndTsn;
  498. };
  499. struct SctpSendBufferNode_S
  500. {
  501.   SctpDataChunkHdr_S  *spChunk;
  502.   Boolean_E            eAdvancedAcked;     // acked via rtx expiration (u-sctp)
  503.   Boolean_E            eGapAcked;          // acked via a Gap Ack Block
  504.   Boolean_E            eAddedToPartialBytesAcked; // already accounted for?
  505.   int                  iNumMissingReports; // # times reported missing
  506.   int                  iUnrelRtxLimit;     // limit on # of unreliable rtx's
  507.   MarkedForRtx_E       eMarkedForRtx;      // has it been marked for rtx?
  508.   Boolean_E            eIneligibleForFastRtx; // ineligible for fast rtx??
  509.   int                  iNumTxs;            // # of times transmitted (orig+rtx)
  510.   double               dTxTimestamp;  
  511.   SctpDest_S          *spDest;             // destination last sent to
  512.   /* variables used for extensions
  513.    */
  514.   u_int                uiFastRtxRecover;   // sctp-multipleFastRtxs.cc uses this
  515.   Boolean_E eMeasuringRtt;  // Maintain which TSN is being used for RTT
  516.     // measurement, so that all TSNs can have
  517.     // their timestamp. This timestamp can be used
  518.     // for different things, and is used by CMT
  519.     // for the RTT heuristic to determine whether
  520.     // a TSN should be rtxd or not.  If now <=
  521.     // timestamp + srtt, then no rtx.
  522. };
  523. struct SctpStreamBufferNode_S
  524. {
  525.   SctpDataChunkHdr_S  *spChunk;
  526. };
  527. enum SctpStreamMode_E
  528. {
  529.   SCTP_STREAM_RELIABLE,
  530.   SCTP_STREAM_UNRELIABLE
  531. };
  532. struct SctpInStream_S
  533. {
  534.   SctpStreamMode_E  eMode;
  535.   u_short           usNextStreamSeqNum;
  536.   List_S            sBufferedChunkList;
  537. };
  538. struct SctpOutStream_S
  539. {
  540.   SctpStreamMode_E  eMode;
  541.   u_short           usNextStreamSeqNum;
  542. };
  543. class SackGenTimer : public TimerHandler 
  544. {
  545. public:
  546.   SackGenTimer(SctpAgent *a) : TimerHandler(), opAgent(a) { }
  547. protected:
  548.   virtual void expire(Event *);
  549.   SctpAgent *opAgent;
  550. };
  551. class SctpAgent : public Agent 
  552. {
  553. public:
  554.   SctpAgent();
  555.   ~SctpAgent();
  556.   virtual void  recv(Packet *pkt, Handler*);
  557.   virtual void  sendmsg(int nbytes, const char *flags = 0);
  558.   virtual int   command(int argc, const char*const* argv);
  559.   void          T1InitTimerExpiration();
  560.   void          T1CookieTimerExpiration();
  561.   virtual void  Timeout(SctpChunkType_E, SctpDest_S *);
  562.   virtual void  CwndDegradeTimerExpiration(SctpDest_S *);
  563.   virtual void  HeartbeatGenTimerExpiration(double);
  564.   void          SackGenTimerExpiration();
  565.   void          RouteCacheFlushTimerExpiration(SctpDest_S *);
  566.   void          RouteCalcDelayTimerExpiration(SctpDest_S *);
  567. protected:
  568.   virtual void  delay_bind_init_all();
  569.   virtual int   delay_bind_dispatch(const char *varName, const char *localName,
  570.     TclObject *tracer);
  571.   /* initialization stuff
  572.    */
  573.   void           SetDebugOutFile();
  574.   virtual void   Reset();
  575.   virtual void   OptionReset();
  576.   virtual u_int  ControlChunkReservation();
  577.   /* tracing functions
  578.    */
  579.   virtual void  TraceVar(const char*);
  580.   virtual void  TraceAll();
  581.   void          trace(TracedVar*);
  582.   /* generic list functions
  583.    */
  584.   void       InsertNode(List_S *, Node_S *, Node_S *, Node_S *);
  585.   void       DeleteNode(List_S *, Node_S *);
  586.   void       ClearList(List_S *);
  587.   /* multihome functions
  588.    */
  589.   void       AddInterface(int, int, NsObject *, NsObject *);
  590.   void       AddDestination(int, int);
  591.   int        SetPrimary(int);
  592.   int        ForceSource(int);
  593.   int        SetLossrate(int, float); // Oracle tells sender lossrate to
  594.       // dest. Called by handling of tcl
  595.       // set-destination-lossrate command
  596.   /* chunk generation functions
  597.    */
  598.   virtual int  GenChunk(SctpChunkType_E, u_char *);
  599.   u_int        GetNextDataChunkSize();
  600.   int          GenOneDataChunk(u_char *);
  601.   virtual int  GenMultipleDataChunks(u_char *, int);
  602.   virtual int  BundleControlChunks(u_char *);
  603.   /* sending functions
  604.    */
  605.   void          StartT3RtxTimer(SctpDest_S *);
  606.   void          StopT3RtxTimer(SctpDest_S *);
  607.   virtual void  AddToSendBuffer(SctpDataChunkHdr_S *,int, u_int, SctpDest_S *);
  608.   void          RttUpdate(double, SctpDest_S *);
  609.   virtual void  SendBufferDequeueUpTo(u_int);
  610.   virtual void  AdjustCwnd(SctpDest_S *);
  611.   void          AdvancePeerAckPoint();
  612.   virtual u_int GetHighestOutstandingTsn();
  613.   virtual void  FastRtx();
  614.   void          TimeoutRtx(SctpDest_S *);
  615.   void          MarkChunkForRtx(SctpSendBufferNode_S *, MarkedForRtx_E);
  616.   Boolean_E     AnyMarkedChunks();
  617.   virtual void  RtxMarkedChunks(SctpRtxLimit_E);
  618.   void          SendHeartbeat(SctpDest_S *);
  619.   SctpDest_S   *GetNextDest(SctpDest_S *);
  620.   double        CalcHeartbeatTime(double);
  621.   void          SetSource(SctpDest_S *);
  622.   void          SetDestination(SctpDest_S *);
  623.   void          SendPacket(u_char *, int, SctpDest_S *);
  624.   SctpDest_S   *GetReplyDestination(hdr_ip *);
  625.   u_int         TotalOutstanding();
  626.   virtual void  SendMuch();
  627.   /* receiving functions
  628.    */
  629.   Boolean_E  UpdateHighestTsn(u_int);
  630.   Boolean_E  IsDuplicateChunk(u_int);
  631.   void       InsertDuplicateTsn(u_int);
  632.   void       UpdateCumAck();
  633.   void       UpdateRecvTsnBlocks(u_int);
  634.   void       PassToUpperLayer(SctpDataChunkHdr_S *);
  635.   void       InsertInStreamBuffer(List_S *, SctpDataChunkHdr_S *);
  636.   void       PassToStream(SctpDataChunkHdr_S *);
  637.   void       UpdateAllStreams();
  638.   /* processing functions
  639.    */
  640.   void               ProcessInitChunk(u_char *);
  641.   void               ProcessInitAckChunk(u_char *);
  642.   void               ProcessCookieEchoChunk(SctpCookieEchoChunk_S *);
  643.   void               ProcessCookieAckChunk(SctpCookieAckChunk_S *);
  644.   void               ProcessDataChunk(SctpDataChunkHdr_S *);
  645.   virtual Boolean_E  ProcessGapAckBlocks(u_char *, Boolean_E);
  646.   virtual void       ProcessSackChunk(u_char *);
  647.   void               ProcessForwardTsnChunk(SctpForwardTsnChunk_S *);  
  648.   void               ProcessHeartbeatAckChunk(SctpHeartbeatChunk_S *);  
  649.   virtual void       ProcessOptionChunk(u_char *);
  650.   virtual int        ProcessChunk(u_char *, u_char **);
  651.   void               NextChunk(u_char **, int *);
  652.   /* misc functions
  653.    */
  654.   void       Close();
  655.   /* debugging functions
  656.    */
  657.   void DumpSendBuffer();
  658.   /* sctp association state variable
  659.    */
  660.   SctpState_E     eState;
  661.   /* App Layer buffer
  662.    */
  663.   List_S          sAppLayerBuffer;
  664.   /* multihome variables
  665.    */
  666.   Classifier         *opCoreTarget;
  667.   List_S              sInterfaceList;
  668.   List_S              sDestList;
  669.   SctpDest_S         *spPrimaryDest;       // primary destination
  670.   SctpDest_S         *spNewTxDest;         // destination for new transmissions
  671.   SctpDest_S         *spReplyDest; // reply with sacks or control chunk replies
  672.   Boolean_E           eForceSource;
  673.   int                 iAssocErrorCount;  // total error counter for the assoc
  674.   /* heartbeat variables
  675.    */
  676.   HeartbeatGenTimer      *opHeartbeatGenTimer;      // to trigger a heartbeat
  677.   /* sending variables
  678.    */
  679.   T1InitTimer       *opT1InitTimer;    // T1-init timer
  680.   T1CookieTimer     *opT1CookieTimer;  // T1-cookie timer
  681.   int                iInitTryCount;    // # of unsuccessful INIT attempts
  682.   u_int              uiNextTsn;
  683.   u_short            usNextStreamId; // used to round-robin the streams
  684.   SctpOutStream_S   *spOutStreams;
  685.   u_int              uiPeerRwnd;
  686.   u_int              uiCumAckPoint;  
  687.   u_int              uiAdvancedPeerAckPoint;
  688.   u_int              uiHighestTsnNewlyAcked; // global for HTNA
  689.   u_int              uiRecover;
  690.   List_S             sSendBuffer;
  691.   Boolean_E          eForwardTsnNeeded;  // is a FORWARD TSN chunk needed?
  692.   Boolean_E          eSendNewDataChunks; // should we send new data chunks too?
  693.   Boolean_E          eMarkedChunksPending; // chunks waiting to be rtx'd?
  694.   Boolean_E          eApplyMaxBurst; 
  695.   DataSource_E       eDataSource;
  696.   u_int              uiBurstLength;  // tracks sending burst per SACK
  697.   /* receiving variables
  698.    */
  699.   u_int            uiMyRwnd;
  700.   u_int            uiCumAck;       
  701.   u_int            uiHighestRecvTsn; // higest tsn recv'd of entire assoc
  702.   List_S           sRecvTsnBlockList;
  703.   List_S           sDupTsnList;
  704.   int              iNumInStreams;
  705.   SctpInStream_S  *spInStreams;
  706.   Boolean_E        eStartOfPacket;             // for delayed sack triggering
  707.   int              iDataPktCountSinceLastSack; // for delayed sack triggering
  708.   Boolean_E        eSackChunkNeeded; // do we need to transmit a sack chunk?
  709.   SackGenTimer    *opSackGenTimer;    // sack generation timer
  710.   /* tcl bindable variables
  711.    */
  712.   u_int            uiDebugMask;     // 32 bits for fine level debugging
  713.   int              iDebugFileIndex; // 1 debug output file per agent 
  714.   u_int            uiPathMaxRetrans;
  715.   u_int            uiChangePrimaryThresh;
  716.   u_int            uiAssociationMaxRetrans;
  717.   u_int            uiMaxInitRetransmits;
  718.   u_int            uiHeartbeatInterval;
  719.   u_int            uiMtu;
  720.   u_int            uiInitialRwnd;
  721.   int              iInitialSsthresh;
  722.   u_int            uiIpHeaderSize;
  723.   u_int            uiDataChunkSize;
  724.   u_int            uiNumOutStreams;
  725.   Boolean_E        eUseDelayedSacks; // are we using delayed sacks?
  726.   double           dSackDelay;
  727.   MaxBurstUsage_E  eUseMaxBurst;
  728.   int              iInitialCwnd;
  729.   double           dInitialRto;
  730.   double           dMinRto;
  731.   double           dMaxRto;
  732.   int              iFastRtxTrigger;
  733.   u_int            uiNumUnrelStreams;
  734.   u_int            uiReliability; // k-rtx on all chunks & all unrel streams
  735.   Boolean_E        eUnordered;    // sets for all chunks on all streams :-(
  736.   RtxToAlt_E       eRtxToAlt;     // rtxs to alternate destination?
  737.   DormantAction_E  eDormantAction;// behavior during dormant state
  738.   double           dRouteCacheLifetime; 
  739.   double           dRouteCalcDelay; 
  740.   Boolean_E        eTraceAll;     // trace all variables on one line?
  741.   TracedInt        tiCwnd;        // trace cwnd for all destinations
  742.   TracedInt        tiRwnd;        // trace rwnd
  743.   TracedDouble     tdRto;         // trace rto for all destinations
  744.   TracedInt        tiErrorCount;  // trace error count for all destinations
  745.   TracedInt        tiFrCount;     // trace each time a fast rtx gets triggered
  746.   TracedInt        tiTimeoutCount;// trace each time a timeout occurs
  747.   TracedInt        tiRcdCount;    // trace each time a route calc delay occurs
  748.   /* globally used non-tcl bindable variables, but rely on the tcl bindable
  749.    */
  750.   u_int           uiMaxPayloadSize; // we don't want this to be tcl bindable
  751.   u_int           uiMaxDataSize; // max payload size - reserved control bytes
  752.   FILE           *fhpDebugFile;     // file pointer for debugging output
  753.   /* tracing variables that will be copied into hdr_sctp
  754.    */
  755.   u_int           uiNumChunks;
  756.   SctpTrace_S    *spSctpTrace;  
  757. };
  758. #endif