User Manual, Developers Guide and API Documentation

CongestionControl.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 16, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <TCP/SlowStart.hpp>
00029 #include <TCP/CongestionControl.hpp>
00030 
00031 
00032 using namespace tcp;
00033 
00034 
00035 CongestionControl::CongestionControl(const wns::pyconfig::View& _pyco) :
00036     pyco(_pyco),
00037     mode(SLOWSTART),
00038     slowStart(NULL),
00039     ca(NULL),
00040     logger(pyco.get("logger"))
00041 {
00042     slowStart = SlowStartFactory::creator("tcp.SlowStart")->create(pyco.getView("slowStart"));
00043     ca = CongestionAvoidanceFactory::creator("tcp.TahoeCongAvoid")->create(pyco.getView("tahoeCA"));
00044 }
00045 
00046 CongestionControl::~CongestionControl()
00047 {
00048     delete slowStart;
00049     delete ca;
00050 }
00051 
00052 void
00053 CongestionControl::onSegmentLoss(segmentLoss reason, unsigned long int _ackNR)
00054 {
00058     unsigned long int curr_cwnd;
00059 
00060     switch(reason)
00061     {
00062     case TIMEOUT:
00066         getCongestionControlMode()->onSegmentLoss(reason, _ackNR);
00067         curr_cwnd = getWindowSize();
00068 
00069         this->setCongestionControlMode(SLOWSTART);
00070 
00071         getCongestionControlMode()->setWindowSize(curr_cwnd);
00072 
00073         break;
00074 
00075     case DUPLICATE_ACK:
00076 
00077         getCongestionControlMode()->onSegmentLoss(reason, _ackNR);
00078         curr_cwnd = getWindowSize();
00079 
00080         if(duplicateACKThresholdReached(_ackNR))
00081         {
00082             setCongestionControlMode(SLOWSTART);
00083 
00084             // clear counter for duplicate acks
00085             ca->clearDuplicateACKCounter();
00086             
00087             getCongestionControlMode()->setWindowSize(curr_cwnd);
00088         }
00089 
00090         break;
00091 
00092     default:
00093         break;
00094     }
00095 }
00096 
00097 void
00098 CongestionControl::onRTTSample()
00099 {
00100     this->getCongestionControlMode()->onRTTSample();
00101 }
00102 
00103 unsigned long int
00104 CongestionControl::getWindowSize()
00105 {
00106     return getCongestionControlMode()->getWindowSize();
00107 }
00108 
00109 simTimeType
00110 CongestionControl::getRetransmissionTimeout()
00111 {
00112     return getCongestionControlMode()->getRetransmissionTimeout();
00113 }
00114 
00115 void
00116 CongestionControl::onSegmentAcknowledged()
00117 {
00118     unsigned long int curr_cwnd = getWindowSize();
00119 
00120     switch(mode)
00121     {
00122     case(SLOWSTART):
00123         if (curr_cwnd > dynamic_cast<tcp::SlowStart*>(slowStart)->getSlowStartThreshold())
00124         {
00125             setCongestionControlMode(CONGESTION_AVOIDANCE);
00126             getCongestionControlMode()->setWindowSize(curr_cwnd);
00127         }
00128         break;
00129 
00130     case(CONGESTION_AVOIDANCE):
00131         // do nothing
00132         break;
00133 
00134     default:
00135         break;
00136     }
00137 
00138     this->getCongestionControlMode()->onSegmentAcknowledged();
00139 }
00140 
00141 CongestionControlStrategy*
00142 CongestionControl::getCongestionControlMode()
00143 {
00144     switch(this->mode)
00145     {
00146     case SLOWSTART:
00147         return slowStart;
00148         break;
00149     case CONGESTION_AVOIDANCE:
00150         return ca;
00151         break;
00152     default:
00153         assure(false, "Unknown congestion control mode!");
00154         return NULL;
00155         break;
00156     }
00157 }
00158 
00159 void
00160 CongestionControl::setCongestionControlMode(Mode _mode)
00161 {
00162     if (this->mode == _mode)
00163     {
00164         MESSAGE_SINGLE(NORMAL, logger, "Still in mode " << printMode(_mode));
00165     }
00166     else
00167     {
00168         MESSAGE_SINGLE(NORMAL, logger, "Leaving mode " << printMode(mode));
00169         this->mode = _mode;
00170         MESSAGE_SINGLE(NORMAL, logger, "Entering mode " << printMode(_mode));
00171     }
00172 }
00173 
00174 void
00175 CongestionControl::setWindowSize(unsigned long int /*new_cwnd*/)
00176 {
00177     assure(false, "CongestionControl: Not allowed to set window size!");
00178 }
00179 
00180 
00181 unsigned long int
00182 CongestionControl::getSlowStartThreshold()
00183 {
00184     return dynamic_cast<tcp::SlowStart*>(slowStart)->getSlowStartThreshold();
00185 }
00186 
00187 
00188 bool
00189 CongestionControl::duplicateACKThresholdReached(unsigned long int _ackNR)
00190 {
00191     // forward this function to the CongestionAvoidance entity
00192     return ca->duplicateACKThresholdReached(_ackNR);
00193 }
00194 
00195 
00196 void
00197 CongestionControl::clearDuplicateACKCounter()
00198 {
00199     getCongestionControlMode()->clearDuplicateACKCounter();
00200 }
00201 
00202 
00203 std::string
00204 CongestionControl::printMode(Mode _mode)
00205 {
00206     switch(_mode)
00207     {
00208     case(SLOWSTART):
00209         return "SlowStart";
00210         break;
00211 
00212     case(CONGESTION_AVOIDANCE):
00213         return "CongestionAvoidance";
00214         break;
00215 
00216     default:
00217         assure(false, "Wrong type of mode.");
00218         return "";
00219         break;
00220     }
00221 }

Generated on Tue May 22 03:32:15 2012 for openWNS by  doxygen 1.5.5