A Discrete-Event Network Simulator
API
tcp-rto-test.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2015 Natale Patriciello <natale.patriciello@gmail.com>
4  *
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
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
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
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  */
19 #include "tcp-rto-test.h"
20 #include "tcp-error-model.h"
21 
22 #include "ns3/node.h"
23 #include "ns3/log.h"
24 #include "ns3/tcp-westwood.h"
25 
26 namespace ns3 {
27 
28 NS_LOG_COMPONENT_DEFINE ("TcpRtoTest");
29 
30 TcpRtoTest::TcpRtoTest (TypeId &congControl, const std::string &desc)
31  : TcpGeneralTest (desc),
32  m_rtoExpired (false),
33  m_segmentReceived (false)
34 {
35  m_congControlTypeId = congControl;
36 }
37 
38 void
40 {
42  SetAppPktCount (100);
43 }
44 
45 void
47 {
50 }
51 
54 {
55  // Get a really low RTO, and let them fire as soon as possible since
56  // we are interested only in what happen after it expires
58  socket->SetAttribute ("MinRto", TimeValue (Seconds (0.5)));
59 
60  return socket;
61 }
62 
63 void
65 {
66  // In this test, the RTO fires for the first segment (and no more).
67  // This function is called after the management of the RTO expiration,
68  // and because of this we must check all the involved variables.
70  "Second RTO expired");
72  "Ack state machine not in LOSS state after a loss");
73 
74  m_rtoExpired = true;
75 }
76 
77 void
79  SocketWho who)
80 {
81  // Called after the first ack is received (the lost segment has been
82  // successfully retransmitted. We must check on the sender that variables
83  // are in the same state as they where after RTOExpired if it is the first
84  // ACK after the loss; in every other case, all must be OPEN and the counter
85  // set to 0.
86 
87  if (m_rtoExpired && who == SENDER)
88  {
90  "Ack state machine not in LOSS state after a loss");
91  }
92  else
93  {
95  "Ack state machine not in OPEN state after recovering "
96  "from loss");
97  }
98 }
99 
100 void
102  SocketWho who)
103 {
104  // Called after the ACK processing. Every time we should be in OPEN state,
105  // without any packet lost or marked as retransmitted, in both the sockets
106 
108  "Ack state machine not in OPEN state after recovering "
109  "from loss");
110 
111  if (who == SENDER)
112  {
113  m_rtoExpired = false;
114  m_segmentReceived = true;
115  }
116 }
117 
118 void
120 {
121  // At least one time we should process an ACK; otherwise, the segment
122  // has not been retransmitted, and this is bad
123 
125  "Retransmission has not been done");
126 }
127 
128 // TcpTimeRtoTest
129 
130 TcpTimeRtoTest::TcpTimeRtoTest (TypeId &congControl, const std::string &desc)
131  : TcpGeneralTest (desc),
132  m_senderSentSegments (0),
133  m_closed (false)
134 {
135  m_congControlTypeId = congControl;
136 }
137 
138 void
140 {
142  SetAppPktCount (100);
143 }
144 
145 
148 {
150  s->SetAttribute ("DataRetries", UintegerValue (6));
151 
152  return s;
153 }
154 
157 {
158  Ptr<TcpSeqErrorModel> errorModel = CreateObject<TcpSeqErrorModel> ();
159 
160  // Drop packet for 7 times. At the 7th, the connection should be dropped.
161  for (uint32_t i = 0; i<7; ++i)
162  {
163  errorModel->AddSeqToKill (SequenceNumber32 (1));
164  }
165 
166  errorModel->SetDropCallback (MakeCallback (&TcpTimeRtoTest::PktDropped, this));
167 
168  return errorModel;
169 }
170 
171 void
173 {
174  NS_LOG_FUNCTION (this << p << h << who);
175 
176  if (who == SENDER)
177  {
179  NS_LOG_INFO (Simulator::Now ().GetSeconds () << "\tMeasured RTO:" <<
180  GetRto (SENDER).GetSeconds ());
181 
182  if (h.GetFlags () & TcpHeader::SYN)
183  {
185 
186  Time s_rto = GetRto (SENDER);
188  "SYN packet sent without respecting "
189  "ConnTimeout attribute");
190  }
191  else
192  {
193  NS_LOG_INFO (Simulator::Now ().GetSeconds () << "\tTX: " << h <<
195 
197  "First packet has been correctly sent");
198 
199  // Remember, from RFC:
200  // m_rto = Max (m_rtt->GetEstimate () +
201  // Max (m_clockGranularity, m_rtt->GetVariation ()*4), m_minRto);
202 
203  if (m_senderSentSegments == 2)
204  { // ACK of SYN-ACK, rto set for the first time, since now we have
205  // an estimation of RTT
206 
207  Ptr<RttEstimator> rttEstimator = GetRttEstimator (SENDER);
208  Time clockGranularity = GetClockGranularity (SENDER);
209  m_previousRTO = rttEstimator->GetEstimate ();
210 
211  if (clockGranularity > rttEstimator->GetVariation ()*4)
212  {
213  m_previousRTO += clockGranularity;
214  }
215  else
216  {
217  m_previousRTO += rttEstimator->GetVariation ()*4;
218  }
219 
221 
223  "RTO value differs from calculation");
224  }
225  else if (m_senderSentSegments == 3)
226  { // First data packet. RTO should be the same as before
227 
229  "RTO value has changed unexpectedly");
230 
231  }
232  }
233  }
234  else if (who == RECEIVER)
235  {
236 
237  }
238 }
239 
240 void
242 {
243  m_closed = true;
244 }
245 
246 void
248 {
249  NS_TEST_ASSERT_MSG_EQ (who, SENDER, "RTO in Receiver. That's unexpected");
250 
251  Time actualRto = GetRto (SENDER);
252 
253  if (actualRto < Seconds (60))
254  {
256  "RTO has not doubled after an expiration");
258  }
259  else
260  {
261  NS_TEST_ASSERT_MSG_EQ (actualRto, Seconds (60),
262  "RTO goes beyond 60 second limit");
263  }
264 }
265 
266 void
269 {
270  NS_LOG_INFO (Simulator::Now ().GetSeconds () << "\tDROPPED! " << tcpH);
271 }
272 
273 void
275 {
277  "Socket has not been closed after retrying data retransmissions");
278 }
279 
280 //-----------------------------------------------------------------------------
281 
282 static class TcpRtoTestSuite : public TestSuite
283 {
284 public:
285  TcpRtoTestSuite () : TestSuite ("tcp-rto-test", UNIT)
286  {
287  std::list<TypeId> types;
288  types.insert (types.begin (), TcpNewReno::GetTypeId ());
289  types.insert (types.begin (), TcpWestwood::GetTypeId ());
290 
291  for (std::list<TypeId>::iterator it = types.begin (); it != types.end (); ++it)
292  {
293  AddTestCase (new TcpRtoTest ((*it), "RTO retransmit testing"), TestCase::QUICK);
294  AddTestCase (new TcpTimeRtoTest ((*it), "RTO timing testing"), TestCase::QUICK);
295  }
296  }
298 
299 } // namespace ns3
Time GetMinRto(SocketWho who)
Get the minimun RTO attribute.
virtual void ErrorClose(SocketWho who)
Socket closed with an error.
virtual void ConfigureEnvironment()
Change the configuration of the evironment.
Definition: tcp-rto-test.cc:39
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Normal state, no dubious events.
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:143
NUMERIC_TYPE GetValue() const
Extracts the numeric value of the sequence number.
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:173
uint32_t m_senderSentSegments
Definition: tcp-rto-test.h:81
ns3::TcpRtoTestSuite g_TcpRtoTestSuite
Fast test.
Definition: test.h:1152
A suite of tests to run.
Definition: test.h:1333
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
This test suite implements a Unit Test.
Definition: test.h:1343
static TcpSocketState::TcpCongState_t GetCongStateFrom(Ptr< const TcpSocketState > tcb)
Convenience function to retrieve the ACK state from a TCB.
virtual void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet transmitted down to IP layer.
virtual void ProcessedAck(const Ptr< const TcpSocketState > tcb, const TcpHeader &h, SocketWho who)
Processed ack.
Packet header for IPv4.
Definition: ipv4-header.h:33
static TypeId GetTypeId(void)
Get the type ID.
virtual Ptr< TcpSocketMsgBase > CreateSenderSocket(Ptr< Node > node)
Create and install the socket to install on the sender.
bool m_segmentReceived
Definition: tcp-rto-test.h:55
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
AttributeValue implementation for Time.
Definition: nstime.h:957
TcpTimeRtoTest(TypeId &congControl, const std::string &msg)
Testing the moments after an RTO expiration.
Definition: tcp-rto-test.h:36
virtual void FinalChecks()
Performs the (eventual) final checks through test asserts.
virtual void ConfigureProperties(void)
Change the configuration of the socket properties.
Hold an unsigned integer type.
Definition: uinteger.h:44
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:161
virtual Ptr< ErrorModel > CreateReceiverErrorModel()
Create and return the error model to install in the receiver node.
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
Definition: int64x64.h:209
Time GetConnTimeout(SocketWho who)
Get the retransmission time for the SYN segments.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:373
void PktDropped(const Ipv4Header &ipH, const TcpHeader &tcpH, Ptr< const Packet > p)
virtual Ptr< TcpSocketMsgBase > CreateSenderSocket(Ptr< Node > node)
Create and install the socket to install on the sender.
Definition: tcp-rto-test.cc:53
Time GetRto(SocketWho who)
Get the retransmission time.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:44
virtual void RTOExpired(const Ptr< const TcpSocketState > tcb, SocketWho who)
Rto has expired.
void SetAppPktCount(uint32_t pktCount)
Set app packet count.
virtual Ptr< TcpSocketMsgBase > CreateSenderSocket(Ptr< Node > node)
Create and install the socket to install on the sender.
static TypeId GetTypeId(void)
Get the type ID.
Definition: tcp-westwood.cc:47
virtual void RcvAck(const Ptr< const TcpSocketState > tcb, const TcpHeader &h, SocketWho who)
Received ack.
Definition: tcp-rto-test.cc:78
Time GetClockGranularity(SocketWho who)
Get the clock granularity attribute.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
TcpRtoTest(TypeId &congControl, const std::string &msg)
Definition: tcp-rto-test.cc:30
virtual void RTOExpired(const Ptr< const TcpSocketState > tcb, SocketWho who)
Rto has expired.
Definition: tcp-rto-test.cc:64
void SetInitialSsThresh(SocketWho who, uint32_t initialSsThresh)
Forcefully set the initial ssth.
virtual void ConfigureEnvironment()
Change the configuration of the evironment.
SocketWho
Used as parameter of methods, specifies on what node the caller is interested (e.g.
Ptr< RttEstimator > GetRttEstimator(SocketWho who)
Get the Rtt estimator of the socket.
General infrastructure for TCP testing.
virtual void ConfigureEnvironment(void)
Change the configuration of the evironment.
CWND was reduced due to RTO timeout or SACK reneging.
virtual void FinalChecks()
Performs the (eventual) final checks through test asserts.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
virtual void ConfigureProperties()
Change the configuration of the socket properties.
Definition: tcp-rto-test.cc:46
a unique identifier for an interface.
Definition: type-id.h:58
Testing the timing of RTO.
Definition: tcp-rto-test.h:63
TypeId m_congControlTypeId
Congestion control.