sctp-hbAfterRto.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. /* HbAfterRto extension sends a heartbeat immediately after timeout
  38.  * retransmission. The idea is to give the destinations a chance to get an
  39.  * RTT measurement after their RTO is backed off. The hope is to avoid
  40.  * unnecessarily large RTOs (especially on the alternate destinations).
  41.  */
  42. #ifndef lint
  43. static const char rcsid[] =
  44. "@(#) $Header: /cvsroot/nsnam/ns-2/sctp/sctp-hbAfterRto.cc,v 1.4 2007/06/17 21:44:40 tom_henderson Exp $ (UD/PEL)";
  45. #endif
  46. #include "ip.h"
  47. #include "sctp-hbAfterRto.h"
  48. #include "flags.h"
  49. #include "random.h"
  50. #include "template.h"
  51. #include "sctpDebug.h"
  52. #ifdef DMALLOC
  53. #include "dmalloc.h"
  54. #endif
  55. #define MIN(x,y) (((x)<(y))?(x):(y))
  56. #define MAX(x,y) (((x)>(y))?(x):(y))
  57. static class HbAfterRtoSctpClass : public TclClass 
  58. public:
  59.   HbAfterRtoSctpClass() : TclClass("Agent/SCTP/HbAfterRto") {}
  60.   TclObject* create(int, const char*const*) 
  61.   {
  62.     return (new HbAfterRtoSctpAgent());
  63.   }
  64. } classSctpHbAfterRto;
  65. HbAfterRtoSctpAgent::HbAfterRtoSctpAgent() : SctpAgent()
  66. {
  67. }
  68. void HbAfterRtoSctpAgent::delay_bind_init_all()
  69. {
  70.   SctpAgent::delay_bind_init_all();
  71. }
  72. int HbAfterRtoSctpAgent::delay_bind_dispatch(const char *cpVarName, 
  73.   const char *cpLocalName, 
  74.   TclObject *opTracer)
  75. {
  76.   return SctpAgent::delay_bind_dispatch(cpVarName, cpLocalName, opTracer);
  77. }
  78. void HbAfterRtoSctpAgent::Timeout(SctpChunkType_E eChunkType, 
  79.   SctpDest_S *spDest)
  80. {
  81.   DBG_I(Timeout);
  82.   DBG_PL(Timeout, "eChunkType=%s spDest=%p"), 
  83.     (eChunkType == SCTP_CHUNK_DATA) ? "DATA" : "HEARTBEAT",
  84.     spDest
  85.     DBG_PR;
  86.   double dCurrTime = Scheduler::instance().clock();
  87.   DBG_PL(Timeout, "dCurrTime=%f"), dCurrTime DBG_PR;
  88.   if(eChunkType == SCTP_CHUNK_DATA)
  89.     {
  90.       spDest->eRtxTimerIsRunning = FALSE;
  91.       
  92.       /* section 7.2.3 of rfc2960 (w/ implementor's guide)
  93.        */
  94.       if(spDest->iCwnd > 1 * (int) uiMaxDataSize)
  95. {
  96.   spDest->iSsthresh = MAX(spDest->iCwnd/2, 
  97.   iInitialCwnd * (int) uiMaxDataSize);
  98.   spDest->iCwnd = 1*uiMaxDataSize;
  99.   spDest->iPartialBytesAcked = 0; // reset
  100.   tiCwnd++; // trigger changes for trace to pick up
  101. }
  102.       spDest->opCwndDegradeTimer->force_cancel();
  103.       /* Cancel any pending RTT measurement on this destination. Stephan
  104.        * Baucke suggested (2004-04-27) this action as a fix for the
  105.        * following simple scenario:
  106.        *
  107.        * - Host A sends packets 1, 2 and 3 to host B, and choses 3 for
  108.        *   an RTT measurement
  109.        *
  110.        * - Host B receives all packets correctly and sends ACK1, ACK2,
  111.        *   and ACK3.
  112.        *
  113.        * - ACK2 and ACK3 are lost on the return path
  114.        *
  115.        * - Eventually a timeout fires for packet 2, and A retransmits 2
  116.        *
  117.        * - Upon receipt of 2, B sends a cumulative ACK3 (since it has
  118.        *   received 2 & 3 before)
  119.        *
  120.        * - Since packet 3 has never been retransmitted, the SCTP code
  121.        *   actually accepts the ACK for an RTT measurement, although it
  122.        *   was sent in reply to the retransmission of 2, which results
  123.        *   in a much too high RTT estimate. Since this case tends to
  124.        *   happen in case of longer link interruptions, the error is
  125.        *   often amplified by subsequent timer backoffs.
  126.        */
  127.       spDest->eRtoPending = FALSE; // cancel any pending RTT measurement
  128.     }
  129.   DBG_PL(Timeout, "was spDest->dRto=%f"), spDest->dRto DBG_PR;
  130.   spDest->dRto *= 2;    // back off the timer
  131.   if(spDest->dRto > dMaxRto)
  132.     spDest->dRto = dMaxRto;
  133.   tdRto++;              // trigger changes for trace to pick up
  134.   DBG_PL(Timeout, "now spDest->dRto=%f"), spDest->dRto DBG_PR;
  135.   spDest->iTimeoutCount++;
  136.   spDest->iErrorCount++; // @@@ window probe timeouts should not be counted
  137.   DBG_PL(Timeout, "now spDest->iErrorCount=%d"), spDest->iErrorCount DBG_PR;
  138.   if(spDest->eStatus == SCTP_DEST_STATUS_ACTIVE)
  139.     {  
  140.       iAssocErrorCount++;
  141.       DBG_PL(Timeout, "now iAssocErrorCount=%d"), iAssocErrorCount DBG_PR;
  142.       // Path.Max.Retrans exceeded?
  143.       if(spDest->iErrorCount > (int) uiPathMaxRetrans) 
  144. {
  145.   spDest->eStatus = SCTP_DEST_STATUS_INACTIVE;
  146.   if(spDest == spNewTxDest)
  147.     {
  148.       spNewTxDest = GetNextDest(spDest);
  149.       DBG_PL(Timeout, "failing over from %p to %p"),
  150. spDest, spNewTxDest DBG_PR;
  151.     }
  152. }
  153.       if(iAssocErrorCount > (int) uiAssociationMaxRetrans)
  154. {
  155.   /* abruptly close the association!  (section 8.1)
  156.    */
  157.   DBG_PL(Timeout, "abruptly closing the association!") DBG_PR;
  158.   Close();
  159.   DBG_X(Timeout);
  160.   return;
  161. }
  162.     }
  163.   // trace it!
  164.   tiTimeoutCount++;
  165.   tiErrorCount++;       
  166.   if(spDest->iErrorCount > (int) uiChangePrimaryThresh &&
  167.      spDest == spPrimaryDest)
  168.     {
  169.       spPrimaryDest = spNewTxDest;
  170.       DBG_PL(Timeout, "changing primary from %p to %p"),
  171. spDest, spNewTxDest DBG_PR;
  172.     }
  173.   if(eChunkType == SCTP_CHUNK_DATA)
  174.     {
  175.       TimeoutRtx(spDest);
  176.       // BEGIN -- HbAfterRto changes to this function
  177.       /* If there is an active alternate destination, then send a HB
  178.        * immediately to the destination which timed out.
  179.        */
  180.       if(GetNextDest(spDest) != spDest)
  181. SendHeartbeat(spDest);  
  182.       // END -- HbAfterRto changes to this function
  183.     }
  184.   else if(eChunkType == SCTP_CHUNK_HB)
  185.     {
  186.       if(uiHeartbeatInterval != 0)
  187. SendHeartbeat(spDest);
  188.     }
  189.   DBG_X(Timeout);  
  190. }