LEFT | RIGHT |
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2016 Natale Patriciello <natale.patriciello@gmail.com> | 3 * Copyright (c) 2016 Natale Patriciello <natale.patriciello@gmail.com> |
4 * | 4 * |
5 * This program is free software; you can redistribute it and/or modify | 5 * This program is free software; you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 2 as | 6 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation; | 7 * published by the Free Software Foundation; |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 TcpBytesInFlightTest::RTOExpired (Time oldVal, Time newVal) | 164 TcpBytesInFlightTest::RTOExpired (Time oldVal, Time newVal) |
165 { | 165 { |
166 NS_LOG_DEBUG ("RTO expired at " << newVal.GetSeconds ()); | 166 NS_LOG_DEBUG ("RTO expired at " << newVal.GetSeconds ()); |
167 m_guessedBytesInFlight = 0; | 167 m_guessedBytesInFlight = 0; |
168 } | 168 } |
169 | 169 |
170 void | 170 void |
171 TcpBytesInFlightTest::PktDropped (const Ipv4Header &ipH, const TcpHeader &tcpH, | 171 TcpBytesInFlightTest::PktDropped (const Ipv4Header &ipH, const TcpHeader &tcpH, |
172 Ptr<const Packet> p) | 172 Ptr<const Packet> p) |
173 { | 173 { |
174 NS_UNUSED(ipH); | 174 NS_UNUSED (ipH); |
175 NS_LOG_DEBUG ("Drop seq= " << tcpH.GetSequenceNumber () << " size " << p->GetS
ize ()); | 175 NS_LOG_DEBUG ("Drop seq= " << tcpH.GetSequenceNumber () << " size " << p->GetS
ize ()); |
176 } | 176 } |
177 | 177 |
178 void | 178 void |
179 TcpBytesInFlightTest::Rx (const Ptr<const Packet> p, const TcpHeader &h, SocketW
ho who) | 179 TcpBytesInFlightTest::Rx (const Ptr<const Packet> p, const TcpHeader &h, SocketW
ho who) |
180 { | 180 { |
181 if (who == RECEIVER) | 181 if (who == RECEIVER) |
182 { | 182 { |
183 } | 183 } |
184 else if (who == SENDER) | 184 else if (who == SENDER) |
185 { | 185 { |
186 if (h.GetAckNumber () > m_lastAckRecv) | 186 if (h.GetAckNumber () > m_lastAckRecv) |
187 { // New ack | 187 { // New ack |
188 uint32_t diff = h.GetAckNumber () - m_lastAckRecv; | 188 uint32_t diff = h.GetAckNumber () - m_lastAckRecv; |
189 NS_LOG_DEBUG ("Recv ACK=" << h.GetAckNumber ()); | 189 NS_LOG_DEBUG ("Recv ACK=" << h.GetAckNumber ()); |
190 | 190 |
191 if (m_dupAckRecv > 0) | 191 if (m_dupAckRecv > 0) |
192 { // Previously we got some ACKs | 192 { // Previously we got some ACKs |
193 if (h.GetAckNumber () >= m_greatestSeqSent) | 193 if (h.GetAckNumber () >= m_greatestSeqSent) |
194 { // This an ACK which acknowledge all the window | 194 { // This an ACK which acknowledge all the window |
195 m_guessedBytesInFlight = 0; // All outstanding data acked | 195 m_guessedBytesInFlight = 0; // All outstanding data acked |
196 diff = 0; | 196 diff = 0; |
197 m_dupAckRecv = 0; | 197 m_dupAckRecv = 0; |
198 } | 198 } |
199 else | 199 else |
200 { | 200 { |
201 // Partial ACK: Update the dupAck received count | 201 // Partial ACK: Update the dupAck received count |
202 m_dupAckRecv -= diff / GetSegSize (SENDER); | 202 m_dupAckRecv -= diff / GetSegSize (SENDER); |
| 203 // During fast recovery the TCP data sender respond to a parti
al acknowledgment |
| 204 // by inferring that the next in-sequence packet has been lost
(RFC5681) |
| 205 m_guessedBytesInFlight -= GetSegSize (SENDER); |
203 } | 206 } |
204 } | 207 } |
205 | 208 |
206 if ((h.GetFlags () & TcpHeader::FIN) != 0 | 209 if ((h.GetFlags () & TcpHeader::FIN) != 0 |
207 || m_guessedBytesInFlight + 1 == diff) | 210 || m_guessedBytesInFlight + 1 == diff) |
208 { // received the ACK for the FIN (which includes 1 spurious byte) | 211 { // received the ACK for the FIN (which includes 1 spurious byte) |
209 diff -= 1; | 212 diff -= 1; |
210 } | 213 } |
211 m_guessedBytesInFlight -= diff; | 214 m_guessedBytesInFlight -= diff; |
212 m_lastAckRecv = h.GetAckNumber (); | 215 m_lastAckRecv = h.GetAckNumber (); |
213 NS_LOG_DEBUG ("Update m_guessedBytesInFlight to " << | 216 NS_LOG_DEBUG ("Update m_guessedBytesInFlight to " << |
214 m_guessedBytesInFlight); | 217 m_guessedBytesInFlight); |
215 } | 218 } |
216 else if (h.GetAckNumber () == m_lastAckRecv | 219 else if (h.GetAckNumber () == m_lastAckRecv |
217 && m_lastAckRecv != SequenceNumber32 (1) | 220 && m_lastAckRecv != SequenceNumber32 (1) |
218 && (h.GetFlags () & TcpHeader::FIN) == 0) | 221 && (h.GetFlags () & TcpHeader::FIN) == 0) |
219 { | 222 { |
220 // For each dupack I should guess that a segment has been received | 223 // For each dupack I should guess that a segment has been received |
221 // Please do not count FIN and SYN/ACK as dupacks | 224 // Please do not count FIN and SYN/ACK as dupacks |
222 m_guessedBytesInFlight -= GetSegSize (SENDER); | 225 m_guessedBytesInFlight -= GetSegSize (SENDER); |
223 m_dupAckRecv++; | 226 m_dupAckRecv++; |
224 // RFC 6675 says after two dupacks, the segment is considered lost | 227 // RFC 6675 says after two dupacks, the segment is considered lost |
225 if (m_dupAckRecv == 3) | 228 if (m_dupAckRecv == 3) |
226 { | 229 { |
227 NS_LOG_DEBUG ("Loss of a segment detected"); | 230 NS_LOG_DEBUG ("Loss of a segment detected"); |
| 231 m_guessedBytesInFlight -= GetSegSize (SENDER); |
228 } | 232 } |
229 NS_LOG_DEBUG ("Dupack received, Update m_guessedBytesInFlight to " << | 233 NS_LOG_DEBUG ("Dupack received, Update m_guessedBytesInFlight to " << |
230 m_guessedBytesInFlight); | 234 m_guessedBytesInFlight); |
231 } | 235 } |
232 | 236 |
233 } | 237 } |
234 } | 238 } |
235 | 239 |
236 void | 240 void |
237 TcpBytesInFlightTest::Tx (const Ptr<const Packet> p, const TcpHeader &h, SocketW
ho who) | 241 TcpBytesInFlightTest::Tx (const Ptr<const Packet> p, const TcpHeader &h, SocketW
ho who) |
(...skipping 22 matching lines...) Expand all Loading... |
260 retr = h.GetSequenceNumber (); | 264 retr = h.GetSequenceNumber (); |
261 | 265 |
262 NS_LOG_DEBUG ("TX size=" << p->GetSize () << " seq=" << h.GetSequenceNumbe
r () << | 266 NS_LOG_DEBUG ("TX size=" << p->GetSize () << " seq=" << h.GetSequenceNumbe
r () << |
263 " m_guessedBytesInFlight=" << m_guessedBytesInFlight); | 267 " m_guessedBytesInFlight=" << m_guessedBytesInFlight); |
264 } | 268 } |
265 } | 269 } |
266 | 270 |
267 void | 271 void |
268 TcpBytesInFlightTest::BytesInFlightTrace (uint32_t oldValue, uint32_t newValue) | 272 TcpBytesInFlightTest::BytesInFlightTrace (uint32_t oldValue, uint32_t newValue) |
269 { | 273 { |
270 NS_UNUSED(oldValue); | 274 NS_UNUSED (oldValue); |
271 NS_LOG_DEBUG ("Socket BytesInFlight=" << newValue << | 275 NS_LOG_DEBUG ("Socket BytesInFlight=" << newValue << |
272 " mine is=" << m_guessedBytesInFlight); | 276 " mine is=" << m_guessedBytesInFlight); |
273 NS_TEST_ASSERT_MSG_EQ (m_guessedBytesInFlight, newValue, | 277 NS_TEST_ASSERT_MSG_EQ (m_guessedBytesInFlight, newValue, |
274 "At time " << Simulator::Now ().GetSeconds () << "; gue
ssed and measured bytes in flight differs"); | 278 "At time " << Simulator::Now ().GetSeconds () << "; gue
ssed and measured bytes in flight differs"); |
275 } | 279 } |
276 | 280 |
277 void | 281 void |
278 TcpBytesInFlightTest::FinalChecks () | 282 TcpBytesInFlightTest::FinalChecks () |
279 { | 283 { |
280 NS_TEST_ASSERT_MSG_EQ (m_guessedBytesInFlight, 0, | 284 NS_TEST_ASSERT_MSG_EQ (m_guessedBytesInFlight, 0, |
(...skipping 23 matching lines...) Expand all Loading... |
304 TestCase::QUICK); | 308 TestCase::QUICK); |
305 toDrop.pop_back (); | 309 toDrop.pop_back (); |
306 toDrop.push_back (4501); | 310 toDrop.push_back (4501); |
307 AddTestCase (new TcpBytesInFlightTest ("BytesInFlight value, two drop of con
secutive segments", toDrop), | 311 AddTestCase (new TcpBytesInFlightTest ("BytesInFlight value, two drop of con
secutive segments", toDrop), |
308 TestCase::QUICK); | 312 TestCase::QUICK); |
309 } | 313 } |
310 }; | 314 }; |
311 | 315 |
312 static TcpBytesInFlightTestSuite g_tcpBytesInFlightTestSuite; //!< Static variab
le for test initialization | 316 static TcpBytesInFlightTestSuite g_tcpBytesInFlightTestSuite; //!< Static variab
le for test initialization |
313 | 317 |
LEFT | RIGHT |