![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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 }
1.5.5