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) 2015 Natale Patriciello <natale.patriciello@gmail.com> | 3 * Copyright (c) 2015 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 |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with this program; if not, write to the Free Software | 15 * along with this program; if not, write to the Free Software |
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 * | 17 * |
18 */ | 18 */ |
19 #include "tcp-error-model.h" | |
20 | 19 |
21 #include "ns3/node.h" | 20 #include "ns3/node.h" |
22 #include "ns3/log.h" | 21 #include "ns3/log.h" |
23 #include "ns3/tcp-westwood.h" | 22 #include "ns3/tcp-westwood.h" |
24 #include "ns3/simple-channel.h" | 23 #include "ns3/simple-channel.h" |
25 #include "tcp-general-test.h" | 24 #include "tcp-general-test.h" |
26 #include "tcp-error-model.h" | 25 #include "tcp-error-model.h" |
27 | 26 |
28 NS_LOG_COMPONENT_DEFINE ("TcpRtoTest"); | 27 NS_LOG_COMPONENT_DEFINE ("TcpRtoTest"); |
29 | 28 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 // we are interested only in what happen after it expires | 97 // we are interested only in what happen after it expires |
99 Ptr<TcpSocketMsgBase> socket = TcpGeneralTest::CreateSenderSocket (node); | 98 Ptr<TcpSocketMsgBase> socket = TcpGeneralTest::CreateSenderSocket (node); |
100 socket->SetAttribute ("MinRto", TimeValue (Seconds (0.5))); | 99 socket->SetAttribute ("MinRto", TimeValue (Seconds (0.5))); |
101 | 100 |
102 return socket; | 101 return socket; |
103 } | 102 } |
104 | 103 |
105 void | 104 void |
106 TcpRtoTest::AfterRTOExpired (const Ptr<const TcpSocketState> tcb, SocketWho who) | 105 TcpRtoTest::AfterRTOExpired (const Ptr<const TcpSocketState> tcb, SocketWho who) |
107 { | 106 { |
108 NS_UNUSED(who); | 107 NS_UNUSED (who); |
109 // In this test, the RTO fires for the first segment (and no more). | 108 // In this test, the RTO fires for the first segment (and no more). |
110 // This function is called after the management of the RTO expiration, | 109 // This function is called after the management of the RTO expiration, |
111 // and because of this we must check all the involved variables. | 110 // and because of this we must check all the involved variables. |
112 NS_TEST_ASSERT_MSG_EQ (m_afterRTOExpired, false, | 111 NS_TEST_ASSERT_MSG_EQ (m_afterRTOExpired, false, |
113 "Second RTO expired"); | 112 "Second RTO expired"); |
114 NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (tcb), TcpSocketState::CA_LOSS, | 113 NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (tcb), TcpSocketState::CA_LOSS, |
115 "Ack state machine not in LOSS state after a loss"); | 114 "Ack state machine not in LOSS state after a loss"); |
116 | 115 |
117 m_afterRTOExpired = true; | 116 m_afterRTOExpired = true; |
118 } | 117 } |
119 | 118 |
120 void | 119 void |
121 TcpRtoTest::RcvAck (const Ptr<const TcpSocketState> tcb, const TcpHeader& h, | 120 TcpRtoTest::RcvAck (const Ptr<const TcpSocketState> tcb, const TcpHeader& h, |
122 SocketWho who) | 121 SocketWho who) |
123 { | 122 { |
124 NS_UNUSED(h); | 123 NS_UNUSED (h); |
125 // Called after the first ack is received (the lost segment has been | 124 // Called after the first ack is received (the lost segment has been |
126 // successfully retransmitted. We must check on the sender that variables | 125 // successfully retransmitted. We must check on the sender that variables |
127 // are in the same state as they where after AfterRTOExpired if it is the firs
t | 126 // are in the same state as they where after AfterRTOExpired if it is the firs
t |
128 // ACK after the loss; in every other case, all must be OPEN and the counter | 127 // ACK after the loss; in every other case, all must be OPEN and the counter |
129 // set to 0. | 128 // set to 0. |
130 | 129 |
131 if (m_afterRTOExpired && who == SENDER) | 130 if (m_afterRTOExpired && who == SENDER) |
132 { | 131 { |
133 NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (tcb), TcpSocketState::CA_LOSS, | 132 NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (tcb), TcpSocketState::CA_LOSS, |
134 "Ack state machine not in LOSS state after a loss")
; | 133 "Ack state machine not in LOSS state after a loss")
; |
135 } | 134 } |
136 else | 135 else |
137 { | 136 { |
138 NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (tcb), TcpSocketState::CA_OPEN, | 137 NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (tcb), TcpSocketState::CA_OPEN, |
139 "Ack state machine not in OPEN state after recoveri
ng " | 138 "Ack state machine not in OPEN state after recoveri
ng " |
140 "from loss"); | 139 "from loss"); |
141 } | 140 } |
142 } | 141 } |
143 | 142 |
144 void | 143 void |
145 TcpRtoTest::ProcessedAck (const Ptr<const TcpSocketState> tcb, const TcpHeader &
h, | 144 TcpRtoTest::ProcessedAck (const Ptr<const TcpSocketState> tcb, const TcpHeader &
h, |
146 SocketWho who) | 145 SocketWho who) |
147 { | 146 { |
148 NS_UNUSED(h); | 147 NS_UNUSED (h); |
149 // Called after the ACK processing. Every time we should be in OPEN state, | 148 // Called after the ACK processing. Every time we should be in OPEN state, |
150 // without any packet lost or marked as retransmitted, in both the sockets | 149 // without any packet lost or marked as retransmitted, in both the sockets |
151 | 150 |
152 NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (tcb), TcpSocketState::CA_OPEN, | 151 NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (tcb), TcpSocketState::CA_OPEN, |
153 "Ack state machine not in OPEN state after recovering " | 152 "Ack state machine not in OPEN state after recovering " |
154 "from loss"); | 153 "from loss"); |
155 | 154 |
156 if (who == SENDER) | 155 if (who == SENDER) |
157 { | 156 { |
158 m_afterRTOExpired = false; | 157 m_afterRTOExpired = false; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 | 260 |
262 errorModel->SetDropCallback (MakeCallback (&TcpSsThreshRtoTest::PktDropped, th
is)); | 261 errorModel->SetDropCallback (MakeCallback (&TcpSsThreshRtoTest::PktDropped, th
is)); |
263 | 262 |
264 return errorModel; | 263 return errorModel; |
265 } | 264 } |
266 | 265 |
267 void | 266 void |
268 TcpSsThreshRtoTest::PktDropped (const Ipv4Header &ipH, const TcpHeader& tcpH, | 267 TcpSsThreshRtoTest::PktDropped (const Ipv4Header &ipH, const TcpHeader& tcpH, |
269 Ptr<const Packet> p) | 268 Ptr<const Packet> p) |
270 { | 269 { |
271 NS_UNUSED(ipH); | 270 NS_UNUSED (ipH); |
272 NS_LOG_DEBUG ("DROPPED! " << tcpH); | 271 NS_LOG_DEBUG ("DROPPED! " << tcpH); |
273 } | 272 } |
274 | 273 |
275 void | 274 void |
276 TcpSsThreshRtoTest::BytesInFlightTrace (uint32_t oldValue, uint32_t newValue) | 275 TcpSsThreshRtoTest::BytesInFlightTrace (uint32_t oldValue, uint32_t newValue) |
277 { | 276 { |
278 NS_UNUSED(oldValue); | 277 NS_UNUSED (oldValue); |
279 NS_LOG_DEBUG ("Socket BytesInFlight=" << newValue); | 278 NS_LOG_DEBUG ("Socket BytesInFlight=" << newValue); |
280 m_bytesInFlight = newValue; | 279 m_bytesInFlight = newValue; |
281 } | 280 } |
282 | 281 |
283 void | 282 void |
284 TcpSsThreshRtoTest::SsThreshTrace (uint32_t oldValue, uint32_t newValue) | 283 TcpSsThreshRtoTest::SsThreshTrace (uint32_t oldValue, uint32_t newValue) |
285 { | 284 { |
286 NS_UNUSED(oldValue); | 285 NS_UNUSED (oldValue); |
287 NS_LOG_DEBUG ("Socket ssThresh=" << newValue); | 286 NS_LOG_DEBUG ("Socket ssThresh=" << newValue); |
288 m_ssThreshSocket = newValue; | 287 m_ssThreshSocket = newValue; |
289 } | 288 } |
290 | 289 |
291 void | 290 void |
292 TcpSsThreshRtoTest::BeforeRTOExpired (const Ptr<const TcpSocketState> tcb, Socke
tWho who) | 291 TcpSsThreshRtoTest::BeforeRTOExpired (const Ptr<const TcpSocketState> tcb, Socke
tWho who) |
293 { | 292 { |
294 NS_LOG_DEBUG ("Before RTO for connection " << who); | 293 NS_LOG_DEBUG ("Before RTO for connection " << who); |
295 | 294 |
296 // Get the bytesInFlight value before the expiration of the RTO | 295 // Get the bytesInFlight value before the expiration of the RTO |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 } | 464 } |
466 else if (who == RECEIVER) | 465 else if (who == RECEIVER) |
467 { | 466 { |
468 | 467 |
469 } | 468 } |
470 } | 469 } |
471 | 470 |
472 void | 471 void |
473 TcpTimeRtoTest::ErrorClose (SocketWho who) | 472 TcpTimeRtoTest::ErrorClose (SocketWho who) |
474 { | 473 { |
475 NS_UNUSED(who); | 474 NS_UNUSED (who); |
476 m_closed = true; | 475 m_closed = true; |
477 } | 476 } |
478 | 477 |
479 void | 478 void |
480 TcpTimeRtoTest::AfterRTOExpired (const Ptr<const TcpSocketState> tcb, SocketWho
who) | 479 TcpTimeRtoTest::AfterRTOExpired (const Ptr<const TcpSocketState> tcb, SocketWho
who) |
481 { | 480 { |
482 NS_TEST_ASSERT_MSG_EQ (who, SENDER, "RTO in Receiver. That's unexpected"); | 481 NS_TEST_ASSERT_MSG_EQ (who, SENDER, "RTO in Receiver. That's unexpected"); |
483 | 482 |
484 Time actualRto = GetRto (SENDER); | 483 Time actualRto = GetRto (SENDER); |
485 | 484 |
486 if (actualRto < Seconds (60)) | 485 if (actualRto < Seconds (60)) |
487 { | 486 { |
488 NS_TEST_ASSERT_MSG_EQ_TOL (actualRto, m_previousRTO+m_previousRTO, Seconds
(0.01), | 487 NS_TEST_ASSERT_MSG_EQ_TOL (actualRto, m_previousRTO+m_previousRTO, Seconds
(0.01), |
489 "RTO has not doubled after an expiration"); | 488 "RTO has not doubled after an expiration"); |
490 m_previousRTO += m_previousRTO; | 489 m_previousRTO += m_previousRTO; |
491 } | 490 } |
492 else | 491 else |
493 { | 492 { |
494 NS_TEST_ASSERT_MSG_EQ (actualRto, Seconds (60), | 493 NS_TEST_ASSERT_MSG_EQ (actualRto, Seconds (60), |
495 "RTO goes beyond 60 second limit"); | 494 "RTO goes beyond 60 second limit"); |
496 } | 495 } |
497 } | 496 } |
498 | 497 |
499 void | 498 void |
500 TcpTimeRtoTest::PktDropped (const Ipv4Header &ipH, const TcpHeader& tcpH, | 499 TcpTimeRtoTest::PktDropped (const Ipv4Header &ipH, const TcpHeader& tcpH, |
501 Ptr<const Packet> p) | 500 Ptr<const Packet> p) |
502 { | 501 { |
503 NS_UNUSED(ipH); | 502 NS_UNUSED (ipH); |
504 NS_LOG_INFO ("DROPPED! " << tcpH); | 503 NS_LOG_INFO ("DROPPED! " << tcpH); |
505 } | 504 } |
506 | 505 |
507 void | 506 void |
508 TcpTimeRtoTest::FinalChecks () | 507 TcpTimeRtoTest::FinalChecks () |
509 { | 508 { |
510 NS_TEST_ASSERT_MSG_EQ (m_closed, true, | 509 NS_TEST_ASSERT_MSG_EQ (m_closed, true, |
511 "Socket has not been closed after retrying data retrans
missions"); | 510 "Socket has not been closed after retrying data retrans
missions"); |
512 } | 511 } |
513 | 512 |
(...skipping 24 matching lines...) Expand all Loading... |
538 minRto = Seconds (0.005); | 537 minRto = Seconds (0.005); |
539 AddTestCase (new TcpSsThreshRtoTest ((*it), seqToDrop, minRto, (*it).Get
Name () + " RTO ssthresh testing, set to half of BytesInFlight"), TestCase::QUIC
K); | 538 AddTestCase (new TcpSsThreshRtoTest ((*it), seqToDrop, minRto, (*it).Get
Name () + " RTO ssthresh testing, set to half of BytesInFlight"), TestCase::QUIC
K); |
540 AddTestCase (new TcpTimeRtoTest ((*it), (*it).GetName () + " RTO timing
testing"), TestCase::QUICK); | 539 AddTestCase (new TcpTimeRtoTest ((*it), (*it).GetName () + " RTO timing
testing"), TestCase::QUICK); |
541 } | 540 } |
542 } | 541 } |
543 }; | 542 }; |
544 | 543 |
545 static TcpRtoTestSuite g_TcpRtoTestSuite; //!< Static variable for test initiali
zation | 544 static TcpRtoTestSuite g_TcpRtoTestSuite; //!< Static variable for test initiali
zation |
546 | 545 |
547 | 546 |
LEFT | RIGHT |