|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2009-2010 Thomas Reschka 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License 00006 // as published by the Free Software Foundation; either version 2 00007 // of the License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU Lesser General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU Lesser General Public License 00015 // along with this program; if not, see <http://www.gnu.org/licenses/>. 00016 // 00017 00018 00019 #include "TCPSACKRexmitQueue.h" 00020 00021 00022 TCPSACKRexmitQueue::TCPSACKRexmitQueue() 00023 { 00024 conn = NULL; 00025 begin = end = 0; 00026 } 00027 00028 TCPSACKRexmitQueue::~TCPSACKRexmitQueue() 00029 { 00030 while (!rexmitQueue.empty()) 00031 rexmitQueue.pop_front(); 00032 } 00033 00034 void TCPSACKRexmitQueue::init(uint32 seqNum) 00035 { 00036 begin = seqNum; 00037 end = seqNum; 00038 } 00039 00040 std::string TCPSACKRexmitQueue::str() const 00041 { 00042 std::stringstream out; 00043 out << "[" << begin << ".." << end << ")"; 00044 return out.str(); 00045 } 00046 00047 void TCPSACKRexmitQueue::info() 00048 { 00049 str(); 00050 RexmitQueue::iterator i = rexmitQueue.begin(); 00051 uint j = 1; 00052 while (i!=rexmitQueue.end()) 00053 { 00054 tcpEV << j << ". region: [" << i->beginSeqNum << ".." << i->endSeqNum << ") \t sacked=" << i->sacked << "\t rexmitted=" << i->rexmitted << "\n"; 00055 i++; 00056 j++; 00057 } 00058 } 00059 00060 uint32 TCPSACKRexmitQueue::getBufferStartSeq() 00061 { 00062 return begin; 00063 } 00064 00065 uint32 TCPSACKRexmitQueue::getBufferEndSeq() 00066 { 00067 return end; 00068 } 00069 00070 void TCPSACKRexmitQueue::discardUpTo(uint32 seqNum) 00071 { 00072 if (rexmitQueue.empty()) 00073 return; 00074 00075 ASSERT(seqLE(begin,seqNum) && seqLE(seqNum,end)); 00076 begin = seqNum; 00077 00078 RexmitQueue::iterator i = rexmitQueue.begin(); 00079 while (i!=rexmitQueue.end()) // discard/delete regions from rexmit queue, which have been acked 00080 { 00081 if (seqLess(i->beginSeqNum,begin)) 00082 i = rexmitQueue.erase(i); 00083 else 00084 i++; 00085 } 00086 00087 // update begin and end of rexmit queue 00088 if (rexmitQueue.empty()) 00089 begin = end = 0; 00090 else 00091 { 00092 i = rexmitQueue.begin(); 00093 begin = i->beginSeqNum; 00094 i = rexmitQueue.end(); 00095 end = i->endSeqNum; 00096 } 00097 } 00098 00099 void TCPSACKRexmitQueue::enqueueSentData(uint32 fromSeqNum, uint32 toSeqNum) 00100 { 00101 bool found = false; 00102 00103 tcpEV << "rexmitQ: " << str() << " enqueueSentData [" << fromSeqNum << ".." << toSeqNum << ")\n"; 00104 00105 Region region; 00106 region.beginSeqNum = fromSeqNum; 00107 region.endSeqNum = toSeqNum; 00108 region.sacked = false; 00109 region.rexmitted = false; 00110 00111 if (getQueueLength()==0) 00112 { 00113 begin = fromSeqNum; 00114 end = toSeqNum; 00115 rexmitQueue.push_back(region); 00116 // tcpEV << "rexmitQ: rexmitQLength=" << getQueueLength() << "\n"; 00117 return; 00118 } 00119 00120 if (seqLE(begin,fromSeqNum) && seqLE(toSeqNum,end)) 00121 { 00122 // Search for region in queue! 00123 RexmitQueue::iterator i = rexmitQueue.begin(); 00124 while (i!=rexmitQueue.end()) 00125 { 00126 if (i->beginSeqNum == fromSeqNum && i->endSeqNum == toSeqNum) 00127 { 00128 i->rexmitted = true; // set rexmitted bit 00129 found = true; 00130 } 00131 i++; 00132 } 00133 } 00134 00135 if (!found) 00136 { 00137 end = toSeqNum; 00138 rexmitQueue.push_back(region); 00139 } 00140 // tcpEV << "rexmitQ: rexmitQLength=" << getQueueLength() << "\n"; 00141 } 00142 00143 void TCPSACKRexmitQueue::setSackedBit(uint32 fromSeqNum, uint32 toSeqNum) 00144 { 00145 bool found = false; 00146 00147 if (seqLE(toSeqNum,end)) 00148 { 00149 RexmitQueue::iterator i = rexmitQueue.begin(); 00150 while (i!=rexmitQueue.end()) 00151 { 00152 if (i->beginSeqNum == fromSeqNum && seqGE(toSeqNum, i->endSeqNum)) // Search for LE of region in queue! 00153 { 00154 i->sacked = true; // set sacked bit 00155 found = true; 00156 i++; 00157 while (seqGE(toSeqNum, i->endSeqNum) && i!=rexmitQueue.end()) // Search for RE of region in queue! 00158 { 00159 i->sacked = true; // set sacked bit 00160 i++; 00161 } 00162 } 00163 else 00164 i++; 00165 } 00166 } 00167 00168 if (!found) 00169 tcpEV << "FAILED to set sacked bit for region: [" << fromSeqNum << ".." << toSeqNum << "). Not found in retransmission queue.\n"; 00170 } 00171 00172 bool TCPSACKRexmitQueue::getSackedBit(uint32 seqNum) 00173 { 00174 bool found = false; 00175 00176 if (seqLE(begin,seqNum)) 00177 { 00178 RexmitQueue::iterator i = rexmitQueue.begin(); 00179 while (i!=rexmitQueue.end()) 00180 { 00181 if (i->beginSeqNum == seqNum) // Search for region in queue! 00182 { 00183 found = i->sacked; 00184 break; 00185 } 00186 i++; 00187 } 00188 } 00189 return found; 00190 } 00191 00192 uint32 TCPSACKRexmitQueue::getQueueLength() 00193 { 00194 return rexmitQueue.size(); 00195 } 00196 00197 uint32 TCPSACKRexmitQueue::getHighestSackedSeqNum() 00198 { 00199 uint32 tmp_highest_sacked = 0; 00200 00201 RexmitQueue::iterator i = rexmitQueue.begin(); 00202 while (i!=rexmitQueue.end()) 00203 { 00204 if (i->sacked) 00205 tmp_highest_sacked = i->endSeqNum; 00206 i++; 00207 } 00208 return tmp_highest_sacked; 00209 } 00210 00211 uint32 TCPSACKRexmitQueue::getHighestRexmittedSeqNum() 00212 { 00213 uint32 tmp_highest_rexmitted = 0; 00214 00215 RexmitQueue::iterator i = rexmitQueue.begin(); 00216 while (i!=rexmitQueue.end()) 00217 { 00218 if (i->rexmitted) 00219 tmp_highest_rexmitted = i->endSeqNum; 00220 i++; 00221 } 00222 return tmp_highest_rexmitted; 00223 } 00224 00225 uint32 TCPSACKRexmitQueue::checkRexmitQueueForSackedOrRexmittedSegments(uint32 fromSeqNum) 00226 { 00227 uint32 counter = 0; 00228 00229 if (fromSeqNum==0 || rexmitQueue.empty() || !(seqLE(begin,fromSeqNum) && seqLE(fromSeqNum,end))) 00230 return counter; 00231 00232 RexmitQueue::iterator i = rexmitQueue.begin(); 00233 while (i!=rexmitQueue.end()) 00234 { 00235 // search for fromSeqNum (snd_nxt) 00236 if (i->beginSeqNum == fromSeqNum) 00237 break; 00238 else 00239 i++; 00240 } 00241 00242 // search for adjacent sacked/rexmitted regions 00243 while (i!=rexmitQueue.end()) 00244 { 00245 if (i->sacked || i->rexmitted) 00246 { 00247 counter = counter + (i->endSeqNum - i->beginSeqNum); 00248 00249 // adjacent regions? 00250 uint32 tmp = i->endSeqNum; 00251 i++; 00252 if (i->beginSeqNum != tmp) 00253 break; 00254 } 00255 else 00256 break; 00257 } 00258 return counter; 00259 } 00260 00261 void TCPSACKRexmitQueue::resetSackedBit() 00262 { 00263 RexmitQueue::iterator i = rexmitQueue.begin(); 00264 while (i!=rexmitQueue.end()) 00265 { 00266 i->sacked = false; // reset sacked bit 00267 i++; 00268 } 00269 } 00270 00271 void TCPSACKRexmitQueue::resetRexmittedBit() 00272 { 00273 RexmitQueue::iterator i = rexmitQueue.begin(); 00274 while (i!=rexmitQueue.end()) 00275 { 00276 i->rexmitted = false; // reset rexmitted bit 00277 i++; 00278 } 00279 } 00280 00281 uint32 TCPSACKRexmitQueue::getTotalAmountOfSackedBytes() 00282 { 00283 uint32 bytes = 0; 00284 uint32 counter = 0; 00285 00286 RexmitQueue::iterator i = rexmitQueue.begin(); 00287 while (i!=rexmitQueue.end()) 00288 { 00289 if (i->sacked) 00290 { 00291 counter++; 00292 bytes = bytes + (i->endSeqNum - i->beginSeqNum); 00293 } 00294 i++; 00295 } 00296 return bytes; 00297 } 00298 00299 uint32 TCPSACKRexmitQueue::getAmountOfSackedBytes(uint32 seqNum) 00300 { 00301 uint32 bytes = 0; 00302 uint32 counter = 0; 00303 00304 if (rexmitQueue.empty() || seqGE(seqNum,end)) 00305 return counter; 00306 00307 RexmitQueue::iterator i = rexmitQueue.begin(); 00308 while (i!=rexmitQueue.end() && seqLess(i->beginSeqNum, seqNum)) // search for seqNum 00309 { 00310 i++; 00311 if (i->beginSeqNum == seqNum) 00312 break; 00313 } 00314 00315 ASSERT(seqLE(seqNum,i->beginSeqNum) || seqGE(seqNum,--i->endSeqNum)); 00316 00317 while (i!=rexmitQueue.end()) 00318 { 00319 if (i->sacked) 00320 { 00321 counter++; 00322 bytes = bytes + (i->endSeqNum - i->beginSeqNum); 00323 } 00324 i++; 00325 } 00326 return bytes; 00327 } 00328 00329 00330 uint32 TCPSACKRexmitQueue::getNumOfDiscontiguousSacks(uint32 seqNum) 00331 { 00332 uint32 counter = 0; 00333 00334 if (rexmitQueue.empty() || seqGE(seqNum,end)) 00335 return counter; 00336 00337 RexmitQueue::iterator i = rexmitQueue.begin(); 00338 while (i!=rexmitQueue.end() && seqLess(i->beginSeqNum, seqNum)) // search for seqNum 00339 { 00340 i++; 00341 if (i->beginSeqNum == seqNum) 00342 break; 00343 } 00344 00345 ASSERT(seqLE(seqNum,i->beginSeqNum) || seqGE(seqNum,--i->endSeqNum)); 00346 00347 // search for discontiguous sacked regions 00348 while (i!=rexmitQueue.end()) 00349 { 00350 if (i->sacked) 00351 { 00352 counter++; 00353 uint32 tmp = i->endSeqNum; 00354 i++; 00355 while (i->sacked && i->beginSeqNum == tmp && i!=rexmitQueue.end()) // adjacent sacked regions? 00356 { 00357 tmp = i->endSeqNum; 00358 i++; 00359 } 00360 } 00361 else 00362 i++; 00363 } 00364 return counter; 00365 }