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

通讯编程

开发平台:

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.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  *
  14.  * 1. Redistributions of source code must retain the above copyright
  15.  *    notice, this list of conditions and the following disclaimer.
  16.  *
  17.  * 2. Redistributions in binary form must reproduce the above copyright
  18.  *    notice, this list of conditions and the following disclaimer in the
  19.  *    documentation and/or other materials provided with the distribution.
  20.  *
  21.  * 3. Neither the name of the University nor of the Laboratory may be used
  22.  *    to endorse or promote products derived from this software without
  23.  *    specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37. /* This extension combines MultipleFastRtx and HbAfterRto extensions.
  38.  *
  39.  * MultipleFastRtx extension implements the Caro Multiple Fast Retransmit
  40.  * Algorithm. Caro's Algorithm introduces a fastRtxRecover state variable
  41.  * per TSN in the send buffer. Any time a TSN is retransmitted, its
  42.  * fastRtxRecover is set to the highest TSN outstanding at the time of
  43.  * retransmit. That way, only missing reports triggered by TSNs beyond
  44.  * fastRtxRecover may trigger yet another fast retransmit.
  45.  *
  46.  * HbAfterRto extension sends a heartbeat immediately after timeout
  47.  * retransmission. The idea is to give the destinations a chance to get an
  48.  * RTT measurement after their RTO is backed off. The hope is to avoid
  49.  * unnecessarily large RTOs (especially on the alternate destinations).
  50.  */
  51. #ifndef lint
  52. static const char rcsid[] =
  53. "@(#) $Header: /cvsroot/nsnam/ns-2/sctp/sctp-mfrHbAfterRto.cc,v 1.2 2007/06/17 21:44:40 tom_henderson Exp $ (UD/PEL)";
  54. #endif
  55. #include "ip.h"
  56. #include "sctp-mfrHbAfterRto.h"
  57. #include "flags.h"
  58. #include "random.h"
  59. #include "template.h"
  60. #include "sctpDebug.h"
  61. #ifdef DMALLOC
  62. #include "dmalloc.h"
  63. #endif
  64. #define MIN(x,y) (((x)<(y))?(x):(y))
  65. #define MAX(x,y) (((x)>(y))?(x):(y))
  66. static class MfrHbAfterRtoSctpClass : public TclClass 
  67. public:
  68.   MfrHbAfterRtoSctpClass() : TclClass("Agent/SCTP/MfrHbAfterRto") {}
  69.   TclObject* create(int, const char*const*) 
  70.   {
  71.     return (new MfrHbAfterRtoSctpAgent());
  72.   }
  73. } classSctpMfrHbAfterRto;
  74. MfrHbAfterRtoSctpAgent::MfrHbAfterRtoSctpAgent() : MultipleFastRtxSctpAgent()
  75. {
  76. }
  77. void MfrHbAfterRtoSctpAgent::delay_bind_init_all()
  78. {
  79.   MultipleFastRtxSctpAgent::delay_bind_init_all();
  80. }
  81. int MfrHbAfterRtoSctpAgent::delay_bind_dispatch(const char *cpVarName, 
  82. const char *cpLocalName, 
  83. TclObject *opTracer)
  84. {
  85.   return MultipleFastRtxSctpAgent::delay_bind_dispatch(cpVarName, 
  86.        cpLocalName, opTracer);
  87. }
  88. void MfrHbAfterRtoSctpAgent::Timeout(SctpChunkType_E eChunkType, 
  89.      SctpDest_S *spDest)
  90. {
  91.   DBG_I(Timeout);
  92.   DBG_PL(Timeout, "eChunkType=%s spDest=%p"), 
  93.     (eChunkType == SCTP_CHUNK_DATA) ? "DATA" : "HEARTBEAT",
  94.     spDest
  95.     DBG_PR;
  96.   double dCurrTime = Scheduler::instance().clock();
  97.   DBG_PL(Timeout, "dCurrTime=%f"), dCurrTime DBG_PR;
  98.   if(eChunkType == SCTP_CHUNK_DATA)
  99.     {
  100.       spDest->eRtxTimerIsRunning = FALSE;
  101.       
  102.       /* section 7.2.3 of rfc2960 (w/ implementor's guide)
  103.        */
  104.       if(spDest->iCwnd > 1 * (int) uiMaxDataSize)
  105. {
  106.   spDest->iSsthresh = MAX(spDest->iCwnd/2, 
  107.   iInitialCwnd * (int) uiMaxDataSize);
  108.   spDest->iCwnd = 1*uiMaxDataSize;
  109.   spDest->iPartialBytesAcked = 0; // reset
  110.   tiCwnd++; // trigger changes for trace to pick up
  111. }
  112.       spDest->opCwndDegradeTimer->force_cancel();
  113.       /* Cancel any pending RTT measurement on this destination. Stephan
  114.        * Baucke suggested (2004-04-27) this action as a fix for the
  115.        * following simple scenario:
  116.        *
  117.        * - Host A sends packets 1, 2 and 3 to host B, and choses 3 for
  118.        *   an RTT measurement
  119.        *
  120.        * - Host B receives all packets correctly and sends ACK1, ACK2,
  121.        *   and ACK3.
  122.        *
  123.        * - ACK2 and ACK3 are lost on the return path
  124.        *
  125.        * - Eventually a timeout fires for packet 2, and A retransmits 2
  126.        *
  127.        * - Upon receipt of 2, B sends a cumulative ACK3 (since it has
  128.        *   received 2 & 3 before)
  129.        *
  130.        * - Since packet 3 has never been retransmitted, the SCTP code
  131.        *   actually accepts the ACK for an RTT measurement, although it
  132.        *   was sent in reply to the retransmission of 2, which results
  133.        *   in a much too high RTT estimate. Since this case tends to
  134.        *   happen in case of longer link interruptions, the error is
  135.        *   often amplified by subsequent timer backoffs.
  136.        */
  137.       spDest->eRtoPending = FALSE; // cancel any pending RTT measurement
  138.     }
  139.   DBG_PL(Timeout, "was spDest->dRto=%f"), spDest->dRto DBG_PR;
  140.   spDest->dRto *= 2;    // back off the timer
  141.   if(spDest->dRto > dMaxRto)
  142.     spDest->dRto = dMaxRto;
  143.   tdRto++;              // trigger changes for trace to pick up
  144.   DBG_PL(Timeout, "now spDest->dRto=%f"), spDest->dRto DBG_PR;
  145.   spDest->iTimeoutCount++;
  146.   spDest->iErrorCount++; // @@@ window probe timeouts should not be counted
  147.   DBG_PL(Timeout, "now spDest->iErrorCount=%d"), spDest->iErrorCount DBG_PR;
  148.   if(spDest->eStatus == SCTP_DEST_STATUS_ACTIVE)
  149.     {  
  150.       iAssocErrorCount++;
  151.       DBG_PL(Timeout, "now iAssocErrorCount=%d"), iAssocErrorCount DBG_PR;
  152.        // Path.Max.Retrans exceeded?
  153.       if(spDest->iErrorCount > (int) uiPathMaxRetrans)
  154. {
  155.   spDest->eStatus = SCTP_DEST_STATUS_INACTIVE;
  156.   if(spDest == spNewTxDest)
  157.     {
  158.       spNewTxDest = GetNextDest(spDest);
  159.       DBG_PL(Timeout, "failing over from %p to %p"),
  160. spDest, spNewTxDest DBG_PR;
  161.     }
  162. }
  163.       if(iAssocErrorCount > (int) uiAssociationMaxRetrans)
  164. {
  165.   /* abruptly close the association!  (section 8.1)
  166.    */
  167.   DBG_PL(Timeout, "abruptly closing the association!") DBG_PR;
  168.   Close();
  169.   DBG_X(Timeout);
  170.   return;
  171. }
  172.     }
  173.   // trace it!
  174.   tiTimeoutCount++;
  175.   tiErrorCount++;       
  176.   if(spDest->iErrorCount > (int) uiChangePrimaryThresh &&
  177.      spDest == spPrimaryDest)
  178.     {
  179.       spPrimaryDest = spNewTxDest;
  180.       DBG_PL(Timeout, "changing primary from %p to %p"),
  181. spDest, spNewTxDest DBG_PR;
  182.     }
  183.   if(eChunkType == SCTP_CHUNK_DATA)
  184.     {
  185.       TimeoutRtx(spDest);
  186.       // BEGIN -- HbAfterRto changes to this function
  187.       /* If there is an active alternate destination, then send a HB
  188.        * immediately to the destination which timed out.
  189.        */
  190.       if(GetNextDest(spDest) != spDest)
  191. SendHeartbeat(spDest);  
  192.       // END -- HbAfterRto changes to this function
  193.     }
  194.   else if(eChunkType == SCTP_CHUNK_HB)
  195.     {
  196.       if(uiHeartbeatInterval != 0)
  197. SendHeartbeat(spDest);
  198.     }
  199.   DBG_X(Timeout);  
  200. }